postgresql 准备好的报表不存在

moiiocjp  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(5)|浏览(154)

目前正在运行一个简单的sinatra应用程序,使用passenger,并使用pgbouncer连接池到与应用程序相同的服务器上的数据库。目前我间歇性地收到一个PG错误,即准备好的语句“a\d”不存在。

A PG::Error occurred in #: 
ERROR: prepared statement "a2" does not exist

字符串
在错误之前执行的ruby代码

def self.get_ownership_record(id, key)
  self.where("user_id=? AND key=?", id, key ).first 
end


pgbouncer配置

; #########################################################
; ############# SECTION HEADER [DATABASES] ################
; #########################################################

[databases]

fakedatabase=fake

[pgbouncer]

; ----- Generic Settings --------------------------
; -------------------------------------------------
logfile=/opt/local/var/log/pgbouncer/pgbouncer.log
pidfile=/opt/local/var/run/pgbouncer/pgbouncer.pid
listen_addr=*
listen_port=5444

; unix_socket_dir=/tmp
user=_webuser
auth_file=/Users/Shared/data/global/pg_auth
auth_type=trust
pool_mode=transaction
; max_client_conn=100
; default_pool_size=20
; reserve_pool_size=0
; reserve_pool_timeout=5
; server_round_robin=0

; ----- Log Settings ------------------------------
; -------------------------------------------------
; syslog=0
; syslog_ident=pgbouncer
; syslog_facility=daemon
; log_connections=1
; log_disconnections=1
; log_pooler_errors=1

; ----- Console Access Control --------------------
; -------------------------------------------------
admin_users=admin,nagios
; -------------------------------------------------
; server_reset_query=DISCARD ALL;
 server_check_delay=0
 server_check_query=SELECT 1;
; server_lifetime=3600
; server_idle_timeout=600
; server_connect_timeout=600
; server_login_retry=15


是我唯一的解决办法,关掉准备好的陈述?
database.yml

production:
  adapter: postgresql
  database: fakedatabase
  username: admin
  host: localhost
  port: 5444
  reconnect: true
  prepared_statements: false

编辑

我更新了pgbouncer.ini以使用会话池
第一个月
未评论
server_reset_query=DISCARD ALL;
我仍然似乎,随机得到错误涉及准备发言,但这一次,

An ActiveRecord::StatementInvalid occurred in #: 

PG::Error: ERROR: bind message supplies 2 parameters, but prepared statement "a1" requires 0


我已经在我的postgresql日志中打开了语句级别的日志记录,如果可能的话,我会报告更多的细节。

zu0ti5jz

zu0ti5jz1#

听从理查德·赫克斯顿的建议,经过一些尝试和错误。
我的最终设置看起来像
第一个月
必须将prepared_statements设置为true

production:
  adapter: postgresql
  database: fakedatabase
  username: admin
  host: localhost
  port: 5444
  reconnect: true
  prepared_statements: true

字符串
pgbouncer.ini
取消注解server_reset_query=DISCARD ALL;
并设置pool_mode=session

; #########################################################
; ############# SECTION HEADER [DATABASES] ################
; #########################################################

[databases]

fakedatabase=fake

[pgbouncer]

; ----- Generic Settings --------------------------
; -------------------------------------------------
logfile=/opt/local/var/log/pgbouncer/pgbouncer.log
pidfile=/opt/local/var/run/pgbouncer/pgbouncer.pid
listen_addr=*
listen_port=5444

; unix_socket_dir=/tmp
user=_webuser
auth_file=/Users/Shared/data/global/pg_auth
auth_type=trust
pool_mode=session
; max_client_conn=100
; default_pool_size=20
; reserve_pool_size=0
; reserve_pool_timeout=5
; server_round_robin=0

; ----- Log Settings ------------------------------
; -------------------------------------------------
; syslog=0
; syslog_ident=pgbouncer
; syslog_facility=daemon
; log_connections=1
; log_disconnections=1
; log_pooler_errors=1

; ----- Console Access Control --------------------
; -------------------------------------------------
admin_users=admin,nagios
; -------------------------------------------------
server_reset_query=DISCARD ALL;
server_check_delay=0
server_check_query=SELECT 1;
; server_lifetime=3600
; server_idle_timeout=600
; server_connect_timeout=600
; server_login_retry=15

基本上允许在会话池模式下使用默认服务器重置查询的预准备语句。

368yc8dk

368yc8dk2#

也许reading the FAQ会有帮助?除非你有一个很好的理由不这样做,否则会话池应该是明智的。

v1l68za4

v1l68za43#

在我的例子中,访问postgres目录并运行“DEALLOCATE ALL”解决了这个问题。
如果你用heroku,像这样

> heroku pg:psql -a app_name
app_name::DATABASE=> DEALLOCATE ALL

字符串

f8rj6qna

f8rj6qna4#

由于PgBouncer 1.21.0现在支持协议级别的命名准备语句,这可能是Ruby客户端使用的。您可以通过将max_prepared_statements设置为非零值来启用此支持。有关详细信息,请查看文档:https://www.pgbouncer.org/config.html#max_prepared_statements

enyaitl3

enyaitl35#

您可以使用事务池,前提是您在同一个事务中PREPAREEXECUTE准备查询(以避免pgBouncer在其间运行server_reset_query)。

相关问题