pgBouncer transaction池模式下预准备语句报错问题求助
解决pgBouncer transaction模式下预准备语句报错问题
问题原因
pgBouncer的transaction连接池模式会在事务结束后回收连接,而预准备语句是绑定在单个数据库连接上的。rust-postgres客户端默认会将查询转为预准备语句,当连接被回收复用后,新的请求找不到之前创建的预准备语句,就会抛出prepared statement "s0" does not exist错误。
解决办法
方法一:禁用客户端预准备语句
在PostgreSQL连接字符串中添加prepare=0参数,强制客户端发送普通查询,不使用预准备语句。修改后的代码如下:
use postgres::{Client, Error, NoTls}; fn main() -> Result<(), Error> { let mut client = Client::connect( "postgresql://haproxy@localhost:9435/haproxy?prepare=0", NoTls, )?; for row in client.query("SELECT pg_is_in_recovery() as x;", &[])? { let x: bool = row.get(0); println!("found app x: {}", x); } Ok(()) }
方法二:切换pgBouncer连接池模式
把pgBouncer的模式从transaction改为session。这种模式下,连接会绑定到客户端会话,直到客户端主动断开才会回收,预准备语句可以正常使用。但缺点是连接资源占用更高,适合长会话场景,需要根据业务需求权衡。
内容的提问来源于stack exchange,提问作者Sassan torabkheslat
相关产品推荐
相关产品推荐

