Postgresql
使用 pgBouncer 準備好的語句
我有一個 pgBouncer 作為連接池的 PostgreSQL 伺服器。
我的應用程序正在 Elixir 上執行。
這是我的 pgBouncer 配置文件:
* = host=X.X.X.X port=5432 logfile = /var/log/postgresql/pgbouncer.log pidfile = /var/run/postgresql/pgbouncer.pid listen_addr = 0.0.0.0 listen_port = 6432 unix_socket_dir = /var/run/postgresql auth_type = trust auth_file = /etc/pgbouncer/userlist.txt admin_users = admin pool_mode = transaction ignore_startup_parameters = extra_float_digits server_check_query = select 1 server_check_delay = 30 max_client_conn = 10000 default_pool_size = 5 min_pool_size = 3 reserve_pool_size = 3 server_reset_query = DEALLOCATE ALL;
當我使用事務池時,出現此錯誤:
ERROR 08P01 (protocol_violation) bind message supplies 4 parameters, but prepared statement "ecto_323" requires 2
然後我將其更改為會話池模式。這次我收到了這個錯誤:
ERROR 26000 (invalid_sql_statement_name) prepared statement "ecto_83" does not exist
如何從 pgBouncer 解決這個問題?
當我直接連接數據庫時,我沒有看到任何錯誤。它在沒有任何代理的情況下執行了一年多。我們現在正在實施 pgBouncer。
會話池模式中的錯誤表明您正在執行與 pgBouncer 無關的不同操作:如果應用程序始終具有相同的會話,則缺少準備好的語句的唯一解釋是它從未被聲明或釋放。如果沒有 pgBouncer,這應該會發生同樣的情況。
這裡的格言是一切都應該在會話池模式下工作。
事務池模式的錯誤表明您對不同的語句使用相同的預準備語句名稱。現在,當應用程序執行緒在下一個事務中獲得其他執行緒的會話時,它會同時獲得準備好的語句,這並不奇怪。