mysql事务未提交断开连接_与数据库连接异常断开导致事务没提交怎么办

当MySQL事务因网络问题或程序错误导致未提交且连接断开时,可能导致事务锁定和连接数激增。本文介绍了一种解决方案,即在InnoDB存储引擎层或MySQL Server层实现事务超时关闭连接功能,尤其是针对空闲事务。通过设置参数`innodb_idle_trx_timeout`,当事务超过指定时间无后续操作时自动关闭连接,减少线上问题的发生。

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

本帖最后由 P-Linux 于 2011-12-25 00:58 编辑

我们经常遇到一个情况,就是网络断开或程序Bug导致COMMIT/ROLLBACK语句没有传到数据库,也没有释放线程,但是线上事务锁定等待严重,连接数暴涨,尤其在测试库这种情况很多,线上也偶有发生,于是想为MySQL增加一个杀掉空闲事务的功能。

那么如何实现呢,通过MySQL Server层有很多不确定因素,最保险还是在存储引擎层实现,我们用的几乎都是InnoDB/XtraDB,所以就基于Percona来修改了,Oracle版的MySQL也可以照着修改。

需求:

1. 一个事务启动,如果事务内最后一个语句执行完超过一个时间(innodb_idle_trx_timeout),就应该关闭链接。

2. 如果事务是纯读事务,因为不加锁,所以无害,不需要关闭,保持即可。

虽然这个思路被Percona的指出Alexey Kopytov可能存在“Even though SELECT queries do not place row locks by default (there are exceptions), they can still block undo log records from being purged.”的问题,但是我们确实有场景SELECT是绝对不能kill的,除非之后的INSERT/UPDATE/DELETE发生了,所以我根据我们的业务特点来修改。跟Percona的Yasufumi Kinoshita和Alexey Kopytov提出过纯SELECT事务不应被kill,现在也得到回复他们也同意这么做。

一、在InnoDB层实现

首先想到这个功能肯定是放在InnoDB Master Thread最方便,Master Thread每秒调度一次,可以顺便检查空闲事务,然后关闭,因为在事务中操作trx->mysql_thd并不安全,所以一般来说最好在InnoDB层换成Thread ID操作,并且InnoDB中除了ha_innodb.cc,其他地方不能饮用THD,所以Master Thread中需要的线程数值,都需要在ha_innodb中计算好传递整型或布尔型返回值给master thread调用。

首先,我们要增加一个参数:idle_trx_timeout,它表示事务多久没有下一条语句发生就超时关闭。

在storage/innodb_plugin/srv/srv0srv.c的“/* plugin options */”注释下增加如下代码注册idle_trx_timeout变量。static MYSQL_SYSVAR_LONG(idle_trx_timeout, srv_idle_trx_timeout,  PLUGIN_VAR_RQCMDARG,  "If zero then this function no effect, if no-zero then wait idle_trx_timeout seconds this transaction will be closed",  "Seconds of Idle-Transaction timeout",  NULL, NULL, 0, 0, LONG_MAX, 0);

代码往下找在innobase_system_variables结构体内加上:MYSQL_SYSVAR(idle_trx_timeout),

有了这个变量,我们需要在Master Thread(storage/innodb_plugin/srv/srv0srv.c )中执行检测函数查找空闲事务。在loop循环的if (sync_array_print_long_waits

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值