我尝试在Go中使用pq driver连接到postresql数据库。
DB, err = sql.Open("postgres", "user=user password=pwd dbname=mydb sslmode=disable")
字符串
一切都很顺利。
但是,当我切换到生产服务器时,连接通过pgbouncer进行:
DB, err = sql.Open("postgres", "user=user password=pwd host=/var/run/pgbouncer port=port dbname=mydb sslmode=disable")
型
对于所有的查询,我总是得到相同的错误,无论多么简单:
Database error: pq: S:"ERROR" M:"prepared statement \"1\" does not exist" C:"26000" F:"prepare.c" L:"519" R:"FetchPreparedStatement"
型
(it总是“prepared statement \“1"",独立于我试图传递的查询)
这两种情况下的查询都简单地运行如下:
res_rows, err := DB.Query(query)
if err != nil {
log.Printf("Database error: %s\n", err)
}
for res_rows.Next() {
...
}
型
谷歌搜索建议关闭准备语句,但我不知道如何在Go中做到这一点,我不确定它是否支持。任何帮助(甚至建议完全使用其他东西)都将非常感谢。
4条答案
按热度按时间mwecs4sa1#
如果使用PgBouncer,则需要将
binary_parameters=yes
设置为数据库dsn连接的查询参数试试这个:
DB, err = sql.Open("postgres", "user=user password=pwd dbname=mydb sslmode=disable, binary_parameters=yes")
个x33g5p2x2#
Package driver
第一个月
字符串
Queryer
是可以由Conn
实现的可选接口。如果
Conn
没有实现Queryer
,sql
包的DB.Query
将首先准备查询,执行语句,然后关闭语句。我不知道lib/pq PostgreSQL驱动程序在哪里实现了
Queryer
。因此,DB.Query
查询在执行之前就准备好了。PgBouncer并不支持所有池化方法的CockE特性:池化模式的特性矩阵。
a0zr77ik3#
Postgres驱动程序现在有一个解决方案来解决这个问题:https://github.com/lib/pq/issues/389
它不在文档中,但可以按预期工作,包括启用PgBouncer和事务池。
ghhaqwfi4#
从PgBouncer 1.21.0开始,它现在支持协议级别的命名准备语句,这几乎可以解决这个错误。你可以通过在PgBouncer的配置文件中将
max_prepared_statements
设置为非零值来打开这个支持。有关详细信息,请查看文档:https://www.pgbouncer.org/config.html#max_prepared_statements