Prepared Statement doesn't exist

danmanstx picture danmanstx · Nov 22, 2013 · Viewed 10.2k times · Source

Currently running a simple sinatra app, using passenger, and using pgbouncer for connection pooling to a database on the same server as the app. Currently I am intermittently getting a PG error that the prepared statement "a\d" doesn't exist.

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

the ruby code that is executed before the error

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

Is my only solution, to turn off prepared statements?

database.yml

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

EDIT

I have updated the pgbouncer.ini to use session pooling

pool_mode=session

and uncommented

server_reset_query=DISCARD ALL;

and I am still seemingly, randomly getting errors involving prepared statements, but this time

An ActiveRecord::StatementInvalid occurred in #: 

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

I have turned on statement level logging in my postgresql logs and will report back with more details if possible.

Answer

danmanstx picture danmanstx · Nov 27, 2013

follwing Richard Huxton advice, and after some trial and error.

my final setup looks like

database.yml

had to set prepared_statements to true

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

pgbouncer.ini

had to uncomment server_reset_query=DISCARD ALL;

and set 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

basically allow prepared statements in a session pool mode with the default server reset query.