mysql连接池长连接机制无效的问题排查-(go-sql-driver的问题)

在使用Golang进行批量数据导入时,遇到连接池长连接机制失效问题,导致大量短连接产生。通过对比不同版本的go-sql-driver,发现v1.3.0版本能够正确维护长连接,而v1.4.0及更高版本则存在问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:

golang的mysql库采用的是驱动模型

Go官方提供了database/sql包来给用户进行和数据库打交道的工作,database/sql库实际只提供了一套操作数据库的接口和规范,例如抽象好的SQL预处理(prepare),连接池管理,数据绑定,事务,错误处理等等。官方并没有提供具体某种数据库实现的协议支持。

和具体的数据库,例如MySQL打交道,还需要再引入MySQL的驱动

具体的底层实现库,采用“注册驱动”的方式注册到上层去使用,比如 https://github.com/go-sql-driver/mysql   这样可以降低耦合

 

问题与排查:

之前一直用的go-sql-driver一直都是好的,一次偶然的机会需要批量导数据,发现一些连接池长连接机制无效的问题,追踪排查了好几天。(#^.^#),也由此产生了此文

golang 版本:go 1.10.4

数据库参数配置

db.SetMaxOpenConns(500)//最大连接数500

db.SetMaxIdleConns(200)//空闲连接200

db.SetConnMaxLifetime(time.Hour * 1)//长连接有效期一个小时

然后导数据的并发设置的是300,按照道理来说 应该是一直维持300左右的长连接的,

但是实际情况是创建了一个连接,用完之后,并没有放到连接池等待下一次使用,而是直接关闭了,于是产生了大量的短连接,参考下图11点之前的曲线,这种情况是不合理的,很奇怪~

但是只有这个服务有问题,线上很多其他的服务连接池的表现都是正常的

我起初以为是database/sql 包里面连接池的问题,一直在找其中的源码,甚至找了go不同版本(1.10和1.11)之间的差异,发现改动不大,源码中也没有看到存在什么明显的问题

在我一度怀疑人生的时候,抱着试试看的方法,把之前正常的服务用的 mysql相关依赖包全部copy了一份到新的服务的vendor里面(其中就包括go-sql-driver),试了一下,竟然正常了~~~

立马看到了曙光,试着把所有包的发布版本切换一下,试了一下,

发现go-sql-driver的v1.3.0是ok的,但是新版v1.4.0和v1.4.1 是不行的,O(∩_∩)O哈哈~

大家可以看到上图11.20之后的曲线,都是正常的,符合预期的(当时与数据库建立的长连接就是300个左右,图中看到的将近350,是因为其它进程占用了)

 

那接下来就是go-sql-driver v1.3.0和v1.4.0之间的差异比较了,简单比较了下,不是必现,只有在并发量越高的时候,短连接越多,也不影响mysql数据的正常使用

由于时间限制,两个版本的源码只是简单比较了一下,还未深究,暂时还未发现具体的原因

这个还需接下来细细定位下源码~~

未完待续

已经在github提了 issue了:https://github.com/go-sql-driver/mysql/issues/991

欢迎沟通,如果您已经找到原因了,可以告诉我,感激不尽~~

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值