2013-11-22 102 views
4

當前運行一個簡單的sinatra應用程序,使用乘客,並使用pgbouncer連接到與應用程序相同的服務器上的數據庫。目前,我間歇性地收到一個PG錯誤,準備好的語句「a \ d」不存在。準備好的聲明不存在

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

是錯誤

 
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 

是我唯一的解決辦法之前執行的Ruby代碼,關閉預處理語句?

的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

我不得不下軌控制檯這個問題。解決方案很簡單,我需要重新啓動控制檯;) – MC2DX

回答

2

理查德·胡克斯頓的建議,並經過一些試驗和錯誤。

我最後的安裝看起來像

database.yml

必須設置prepared_statementstrue

 
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

也許reading the FAQ會有幫助嗎?除非你有充分的理由不這樣做,否則會話池應該是明智的。

+0

那個鏈接現在已經死了 – Stewart

+0

謝謝Stewart - 更新。 –

+0

我永遠不會發現! – Stewart

0

您可以使用交易池,前提是你PREPAREEXECUTE同一事務中準備好的查詢(以避免pgBouncer運行中的server_reset_query)。

0

在我的情況下訪問postgres目錄並運行「DEALLOCATE ALL」來解決問題。

如果你使用Heroku的,這樣

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