Java应用通过Pgbouncer连接PostgreSQL指定quartz schema失败求助
Java应用使用public和quartz两个schema,尝试通过Pgbouncer连接quartz schema,使用的JDBC连接串为:
jdbc:postgresql://127.0.0.1:6432/test_db?currentSchema=quartz;prepareThreshold=0
应用启动失败,日志提示qrtz_locks表不存在,但该表实际存在于quartz schema中。直接连接PostgreSQL默认端口5432时应用运行正常,怀疑JDBC参数currentSchema=quartz被忽略,应用默认连接到了public schema。附上pgbouncer.ini配置文件:
[databases] ; fallback connect string * = host=10.1.2.2 port=5432 [pgbouncer] logfile = /var/log/pgbouncer/pgbouncer.log pidfile = /var/run/pgbouncer/pgbouncer.pid listen_addr = * listen_port = 6432 auth_type = md5 auth_file = /etc/pgbouncer/userlist auth_hba_file = /etc/pgbouncer/pb_hba.conf admin_users = postgres stats_users = postgres pool_mode = transaction ignore_startup_parameters = extra_float_digits,search_path application_name_add_host = 1 max_client_conn = 500 default_pool_size = 15 reserve_pool_size = 10 reserve_pool_timeout = 3 server_lifetime = 300 server_idle_timeout = 120 server_connect_timeout = 5 server_login_retry = 1 query_timeout = 60 query_wait_timeout = 60 client_idle_timeout = 60 client_login_timeout = 60
以下是几种可行的解决方法:
方法1:调整Pgbouncer的启动参数忽略列表
currentSchema参数最终会转化为PostgreSQL的search_path启动参数,而当前配置里把search_path加入了ignore_startup_parameters,导致Pgbouncer直接忽略了客户端发送的search_path设置。
修改pgbouncer.ini中的对应行:
ignore_startup_parameters = extra_float_digits
移除search_path后重启Pgbouncer,这样Pgbouncer会传递客户端的search_path设置到PostgreSQL服务器,currentSchema参数就能正常生效。
方法2:在Pgbouncer数据库配置中指定默认schema
如果希望所有连接test_db的请求默认使用quartz schema,可以在[databases]段直接配置:
[databases] test_db = host=10.1.2.2 port=5432 dbname=test_db options='-c search_path=quartz' ; 保留其他数据库的 fallback 配置 * = host=10.1.2.2 port=5432
这种方式下,不需要在JDBC连接串中额外指定currentSchema参数。
方法3:修改应用数据库用户的默认schema
如果该应用使用的数据库用户仅需访问quartz schema,可直接修改用户的默认schema:
ALTER USER your_app_user SET search_path TO quartz;
修改后,无论通过Pgbouncer还是直接连接,该用户都会默认使用quartz schema。
方法4:在JDBC连接串中改用原生options参数
部分场景下currentSchema参数可能被中间件处理异常,可以直接用PostgreSQL原生的options参数指定schema:
jdbc:postgresql://127.0.0.1:6432/test_db?options=-c%20search_path=quartz&prepareThreshold=0
注意URL编码,%20是空格的编码形式。
内容的提问来源于stack exchange,提问作者Nikolay Debolsky

