searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

MySQL中并行复制(Multi-Threaded Slave,MTS)和xtrabackup的死锁

2023-06-09 06:51:28
154
0

一、故障表现

高可用从库复制延迟持续升高,通过show slave status\G查看从库的复制状态,从库的executed_gtid集合不变化。

二、故障信息

processlist如下图

备份进程如下图:

三、故障原因

看这个图的48、49、18747763这三个进程即可。以下按时间顺序描述:

1、session 48 开始回放但未进入提交阶段;

2、session 49 先提交,持有了表的commit锁,但需要等待session 48的事务先提交,进入waiting for preceding transaction to commit的状态,这里是因为slave_preserve_commit_order=1, 事务保序回放;

3、session 18747763 备份进程加锁,flush table with read lock先拿到全局读锁GLOBAL:S,下一步是拿全局COMMIT锁,这个全局锁的获取 被session 49的commit锁堵塞,进入waiting for commit状态;

4、session 48 应用Xid_event提交事务,尝试获取commit:IX锁,但是由于"COMMIT:IX和COMMIT:S的互斥性",被session 18747763堵塞;

所以就形成了 49等待48、48等待18747763、18747763等待49 的死锁。参考下图:

四、临时解决方案

这种故障表现具备一定的偶然性,因此可以:kill掉session 18747763备份进程的全局锁的获取,让MTS恢复正常;手工重新发起备份

涉及范围:5.7 & 8.0

五、长期解决方案

1、slave_preserve_commit_order=0规避,不建议;

2、set global slave_parallel_workers=0;stop slave;start slave; 关掉并行复制、或者直接stop slave sql_thread;  备份完再set回来(管控实现)

六、一些MDL信息补充

1、MDL实现,可参考 http://mysql.taobao.org/monthly/2015/11/04/

2、FTWRL与DML分别涉及的MDL锁,可参考下图(可能因版本更新不完全准确)。

FTWRL获取两个锁 MDL::global read lock 和MDL::global commit lock。

DML事务执行中获取MDL_key::GLOBAL IX锁;在事务提交前,会先请求MDL_key::COMMIT IX锁。

 

七、一些疑问回答

1、为什么xtrabackup没有主动停止,备份命令中的--ftwrl-wait-query-type=all --ftwrl-wait-timeout=180 没有生效?

>> 这两个参数是ftwrl加锁前的检查,检查没有超时进程,才开始执行Flush table with read lock

2、为什么xtrabackup没有kill掉并行复制的慢查询,备份命令中的--kill-long-queries-timeout=20 --kill-long-query-type=all 没有生效?

>> xtrabackup选择杀掉的线程时,不处理从库的MTS线程。如下参数说明参考。

3、为什么lock_wait_timeout=1800没有生效,全局锁持续了几千秒 没有主动结束?

>> xtrabackup执行全量备份时会执行SET SESSION lock_wait_timeout=31536000

>> lock_wait_timeout本身 对mdl锁是生效的

0条评论
0 / 1000
z****n
18文章数
1粉丝数
z****n
18 文章 | 1 粉丝
原创

MySQL中并行复制(Multi-Threaded Slave,MTS)和xtrabackup的死锁

2023-06-09 06:51:28
154
0

一、故障表现

高可用从库复制延迟持续升高,通过show slave status\G查看从库的复制状态,从库的executed_gtid集合不变化。

二、故障信息

processlist如下图

备份进程如下图:

三、故障原因

看这个图的48、49、18747763这三个进程即可。以下按时间顺序描述:

1、session 48 开始回放但未进入提交阶段;

2、session 49 先提交,持有了表的commit锁,但需要等待session 48的事务先提交,进入waiting for preceding transaction to commit的状态,这里是因为slave_preserve_commit_order=1, 事务保序回放;

3、session 18747763 备份进程加锁,flush table with read lock先拿到全局读锁GLOBAL:S,下一步是拿全局COMMIT锁,这个全局锁的获取 被session 49的commit锁堵塞,进入waiting for commit状态;

4、session 48 应用Xid_event提交事务,尝试获取commit:IX锁,但是由于"COMMIT:IX和COMMIT:S的互斥性",被session 18747763堵塞;

所以就形成了 49等待48、48等待18747763、18747763等待49 的死锁。参考下图:

四、临时解决方案

这种故障表现具备一定的偶然性,因此可以:kill掉session 18747763备份进程的全局锁的获取,让MTS恢复正常;手工重新发起备份

涉及范围:5.7 & 8.0

五、长期解决方案

1、slave_preserve_commit_order=0规避,不建议;

2、set global slave_parallel_workers=0;stop slave;start slave; 关掉并行复制、或者直接stop slave sql_thread;  备份完再set回来(管控实现)

六、一些MDL信息补充

1、MDL实现,可参考 http://mysql.taobao.org/monthly/2015/11/04/

2、FTWRL与DML分别涉及的MDL锁,可参考下图(可能因版本更新不完全准确)。

FTWRL获取两个锁 MDL::global read lock 和MDL::global commit lock。

DML事务执行中获取MDL_key::GLOBAL IX锁;在事务提交前,会先请求MDL_key::COMMIT IX锁。

 

七、一些疑问回答

1、为什么xtrabackup没有主动停止,备份命令中的--ftwrl-wait-query-type=all --ftwrl-wait-timeout=180 没有生效?

>> 这两个参数是ftwrl加锁前的检查,检查没有超时进程,才开始执行Flush table with read lock

2、为什么xtrabackup没有kill掉并行复制的慢查询,备份命令中的--kill-long-queries-timeout=20 --kill-long-query-type=all 没有生效?

>> xtrabackup选择杀掉的线程时,不处理从库的MTS线程。如下参数说明参考。

3、为什么lock_wait_timeout=1800没有生效,全局锁持续了几千秒 没有主动结束?

>> xtrabackup执行全量备份时会执行SET SESSION lock_wait_timeout=31536000

>> lock_wait_timeout本身 对mdl锁是生效的

文章来自个人专栏
数据库运维专项
18 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
1
0