postgresql报错prepared statement ““S_84““ does not exist

开发人员说升级JDBC驱动后,很多SQL无法执行,查看数据库报错信息如下

2021-06-09 11:44:07.619 CST,"melotroom","melotroom",52308,"192.168.110.119:33768",60c0357c.cc54,131,"idle",2021-06-09 11:29:00 CST,4/0,0,ERROR,26000,"prepared statement ""S_84"" does not exist",,,,,,,,,"PostgreSQL JDBC Driver"
2021-06-09 11:44:07.914 CST,"melotroom","melotroom",38882,"192.168.110.119:33306",60c02eb1.97e2,781,"idle",2021-06-09 11:00:01 CST,9/0,0,ERROR,26000,"prepared statement ""S_85"" does not exist",,,,,,,,,"PostgreSQL JDBC Driver"
2021-06-09 11:44:07.915 CST,"melotroom","melotroom",38882,"192.168.110.119:33306",60c02eb1.97e2,782,"PARSE",2021-06-09 11:00:01 CST,9/2853710982,0,ERROR,42P05,"prepared statement ""S_86"" already exists",,,,,,"select

数据库使用环境用了pgbouncer,用的事物模式,发现事物模式不支持prepared statements
如果是session模式,可以设置erver_reset_query = DISCARD ALL; 或者至少设置 DEALLOCATE ALL。

如果需要在jdbc中禁用prepared statements,那么在连接串中设置prepareThreshold=0

prepared statements可以提升SQL的执行速度,原因如下:

  1. 它只发送语句句柄(例如S_1),而不是完整的SQL文本。
  2. 可使用二进制传输,参数和结果解析速度要快得多。
  3. 可重用服务端的执行计划。
  4. 客户端可以重用结果集列定义,因此不必在每次执行时接收和解析元数据。

会跟踪语句执行的次数,默认5次,也就是prepareThreshold=5.

总结:
所以在使用pgbouncer 事物模式的情况下,无法使用prepared statements,需要设置为如下:
jdbc.url=jdbc:postgresql://xxxxx:6431/xxxxx?prepareThreshold=0,但是这样设置每次都是硬解析了,无法绑定数据库服务端缓存的执行计划了。性能上会有损耗。
如果是会话模式,可以设置erver_reset_query = DISCARD ALL; 或者DEALLOCATE ALL。

参考:
http://www.pgbouncer.org/faq.html#how-to-use-prepared-statements-with-session-pooling
https://jdbc.postgresql.org/documentation/head/server-prepare.html
https://stackoverflow.com/questions/7611926/postgres-error-prepared-statement-s-1-already-exists
https://jdbc.postgresql.org/documentation/head/connect.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值