当MySQL事务中发生了网络异常

一、前言

在我们运维MySQL的时候,总会遇到各种情况导致程序和MySQL之间的会话异常中断,比如

假如强制关闭应用
假如client机器突然崩溃宕机/断电
假如网络发生抖动/网卡发生故障
机房级别断网

那么此时正在MySQL中执行的事务会何表现?

二、实践

设计一个案例模拟client 在MySQL中执行事务,但是client机器突然down机,导致会话异常中断。

client 192.168.56.102  
MySQL  192.168.56.101

在这里插入图片描述

client 连接db 执行 select for update 动作给记录加上锁,当然实际上 也可以是update,delete 这样的动作给记录加上锁。
在这里插入图片描述

然后关闭client机器模拟断电,断网。

此时server端 网络层的连接状态依然是 ESTABLISH 数据库中的事务处于running状态。
在这里插入图片描述

再开启另外一个会话,对t1表进行加锁需要等待,说明断网之后的事务依然处于活跃状态。
在这里插入图片描述

ok 表演结束 ,我们接下来继续分析网络断开,事务为啥没有退出?

三、分析

3.1 服务端为什么没有退出这个事务呢?

MySQL普通的会话连接没有保活机制,即没有设置socket属性,也没有设置心跳机制。如果网络连接异常断开服务端不能及时探测到该异常。更进一步,我们通过 TCP 关闭的四次握手来看
在这里插入图片描述

网络异常的时候,TCP连接的状态还是ESTABLISHED,说明 server 和 client 任何一方都没有主动发送FIN包,服务端还在等待 client端 发送数据,此时的 MySQL 事务无法直接退出。

3.2 事务在网络断开后如何处理

事务正在执行

一个连接进行事务后,如果事务语句正在执行,那么网络断开后会在语句执行完成后回滚掉。因为执行状态包不能送达客户端,因此会感知到这种网络断开的错误。调试堆栈信息参考 堆栈1。

   if (thd->is_error() || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值