为了账号安全,请及时绑定邮箱和手机立即绑定

如何安全地丢弃 golang 数据库/sql 池连接,例如当它们指向只读副本时?

如何安全地丢弃 golang 数据库/sql 池连接,例如当它们指向只读副本时?

Go
胡子哥哥 2023-03-21 15:07:15
我们一直在使用 golangdatabase/sql和github.com/lib/pqPostgreSQL 集群,这意味着作为复制主服务器的某个数据库服务器在先前的主服务器发生故障后可能是只读副本。最近,我们的低使用率服务设法在其连接池中保留一个连接(没有会打开第二个连接的并发请求),并且其目标已降级为只读副本。结果,对服务的每个写入操作都失败,直到它重新启动。如果与集群建立了新连接,就不会发生这种情况。问题是我找不到记录在案的方法来丢弃某些类型错误的连接。唯一database/sql听起来正确的公共方法是Conn.Close将连接返回到池而不关闭它。不调用它会导致资源泄漏,最终使池无法使用。有没有一种可持续的方法可以在应用程序需要时摆脱连接?
查看完整描述

3 回答

?
紫衣仙女

TA贡献1839条经验 获得超15个赞

我相信在使用 时database/sql,答案是“否”,尽管我很乐意得到纠正。

不久前,出于类似的原因(无法控制低级别的连接),我们从database/sqlwith切换lib/pq到纯 Go jackc/pgx ,并对结果感到满意。该模块提供了ConnPool.Reset听起来像你在这里想要的东西:

Reset 关闭所有打开的连接,但让池保持打开状态。它旨在用于检测到会中断所有连接的错误(例如网络中断或服务器状态更改)。

在签出连接时重置池是安全的。这些连接将在返回池时关闭。


查看完整回答
反对 回复 2023-03-21
?
aluckdog

TA贡献1847条经验 获得超7个赞

最好的选择可能是 Postgres 的DISCONNECT命令。

_, err := conn.ExecContext(context.Background(), "DISCONNECT")

将导致连接从服务器端关闭。


查看完整回答
反对 回复 2023-03-21
?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

我认为您可以通过使用 Raw 函数并返回 driver.ErrBadConn 错误来丢弃它:

conn.Raw(func(interface{}) error { return driver.ErrBadConn })


查看完整回答
反对 回复 2023-03-21
  • 3 回答
  • 0 关注
  • 123 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信