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

PG::Error在#:中发生
错误:准备好的语句“a2”不存在

错误前执行的ruby代码

def self.get_ownership_record(id,key)
self.where(“user_id =?AND key =?”,id,key)。首先
结尾

pgbouncer配置

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

[数据库]

fakedatabase =假的

[pgbouncer]

; -----常规设置--------------------------
; -------------------------------------------------
日志文件=/opt/local/var/log/pgbouncer/pgbouncer.log
pidfile =/opt/local/var/run/pgbouncer/pgbouncer.pid
listen_addr = *
listen_port = 5444

; unix_socket_dir =/tmp
用户= _webuser
auth_file =/用户/共享/数据/全局/pg_auth
auth_type =信任
pool_mode =交易
; max_client_conn = 100
; default_pool_size = 20
; reserve_pool_size = 0
; reserve_pool_timeout = 5
; server_round_robin = 0

; -----日志设置------------------------------
; -------------------------------------------------
; syslog = 0
; syslog_ident = pgbouncer
; syslog_facility =守护程序
; log_connections = 1
; log_disconnections = 1
; log_pooler_errors = 1

; -----控制台访问控制--------------------
; -------------------------------------------------
admin_users = admin,nagios
; -------------------------------------------------
; server_reset_query =全部取消;
server_check_delay = 0
server_check_query =选择1;
; server_lifetime = 3600
; server_idle_timeout = 600
; server_connect_timeout = 600
; server_login_retry = 15

我唯一的解决方案是关闭准备好的语句?

数据库

生产:
适配器:PostgreSQL
数据库:fakedatabase
用户名:admin
主机:本地主机
端口:5444
重新连接:正确
prepare_statements:否

编辑

我已经更新了pgbouncer.ini以使用 session 池
pool_mode=session
而且没有评论
server_reset_query=DISCARD ALL;
而且我似乎仍然随机地得到与准备好的语句有关的错误,但是这次

ActiveRecord::StatementInvalid发生在#:

PG::Error:ERROR:绑定(bind)消息提供2个参数,但准备好的语句“a1”需要0

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

最佳答案

跟随理查德·赫克斯顿(Richard Huxton)提出建议,并经过反复试验。

我的最终设置看起来像
database.yml
必须将prepared_statements设置为true
生产:
适配器:PostgreSQL
数据库:fakedatabase
用户名:admin
主机:本地主机
端口:5444
重新连接:正确
prepare_statements:正确
pgbouncer.ini
必须取消注释server_reset_query=DISCARD ALL;
并设置pool_mode=session
; ################################################ #######
; ############ SECTION HEADER [DATABASES] #################
; ################################################ #######

[数据库]

fakedatabase =假的

[pgbouncer]

; -----常规设置--------------------------
; -------------------------------------------------
日志文件=/opt/local/var/log/pgbouncer/pgbouncer.log
pidfile =/opt/local/var/run/pgbouncer/pgbouncer.pid
listen_addr = *
listen_port = 5444

; unix_socket_dir =/tmp
用户= _webuser
auth_file =/用户/共享/数据/全局/pg_auth
auth_type =信任
pool_mode = session
; max_client_conn = 100
; default_pool_size = 20
; reserve_pool_size = 0
; reserve_pool_timeout = 5
; server_round_robin = 0

; -----日志设置------------------------------
; -------------------------------------------------
; syslog = 0
; syslog_ident = pgbouncer
; syslog_facility =守护程序
; log_connections = 1
; log_disconnections = 1
; log_pooler_errors = 1

; -----控制台访问控制--------------------
; -------------------------------------------------
admin_users = admin,nagios
; -------------------------------------------------
server_reset_query =全部取消;
server_check_delay = 0
server_check_query =选择1;
; server_lifetime = 3600
; server_idle_timeout = 600
; server_connect_timeout = 600
; server_login_retry = 15

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

关于postgresql - 准备的语句不存在,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20150503/

10-11 06:24