目前运行一个简单的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 config
; ######################################################### ; ############# 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日志中打开了语句级别日志记录,如果可能的话会报告更多详细信息。
答案 0 :(得分:2)
我的最终设置看起来像
database.yml
必须将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
基本上允许使用默认服务器重置查询在会话池模式下准备语句。
答案 1 :(得分:1)
也许reading the FAQ会有所帮助?除非你有充分的理由不这样做,否则会话合并应该是明智的。
答案 2 :(得分:0)
您可以使用事务池,前提是您在同一事务中PREPARE
和EXECUTE
准备好的查询(以避免pgBouncer在其间运行server_reset_query
)。
答案 3 :(得分:0)
在我的情况下访问postgres目录并运行" DEALLOCATE ALL"解决问题。
如果你使用heroku,就像这样
> heroku pg:psql -a app_name
app_name::DATABASE=> DEALLOCATE ALL