准备好的声明不存在

dan*_*stx 5 postgresql sinatra pgbouncer

目前运行一个简单的sinatra应用程序,使用乘客,并使用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以使用会话池

pool_mode=session

并且没有注释

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日志中打开了语句级别日志记录,如果可能的话会报告更多详细信息.

dan*_*stx 5

遵循理查德·赫克斯顿的建议,并经过一些尝试和错误。

我的最终设置看起来像

database.yml

必须设置prepared_statementstrue

生产:
  适配器:postgresql
  数据库:假数据库
  用户名: 管理员
  主机:本地主机
  端口:5444
  重新连接:正确
  准备好的语句:true

pgbouncer.ini

不得不取消评论server_reset_query=DISCARD ALL;

并设置pool_mode=session

; #################################################### #######
; ############# 节标题 [数据库] ################
; #################################################### #######

[数据库]

假数据库=假的

[保镖]

; ----- 通用设置 --------------------------
; -------------------------------------------------
日志文件=/opt/local/var/log/pgbouncer/pgbouncer.log
pidfile=/opt/local/var/run/pgbouncer/pgbouncer.pid
监听地址=*
监听端口=5444

; unix_socket_dir=/tmp
用户=_webuser
auth_file=/用户/共享/数据/全局/pg_auth
auth_type=信任
pool_mode=会话
; 最大客户端连接=100
; 默认池大小=20
; Reserve_pool_size=0
; Reserve_pool_timeout=5
; server_round_robin=0

; ----- 日志设置 ------------------------------------------
; -------------------------------------------------
; 系统日志=0
; syslog_ident = pgbouncer
; syslog_facility=守护进程
; 日志连接=1
; log_disconnections=1
; log_pooler_errors=1

; ----- 控制台访问控制 --------------------
; -------------------------------------------------
admin_users=管理员,nagios
; -------------------------------------------------
server_reset_query=放弃全部;
server_check_delay=0
server_check_query=选择 1;
; 服务器生命周期=3600
; server_idle_timeout=600
; server_connect_timeout=600
; server_login_retry=15

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