slave开启MTS时执行mysqldump引发死锁案例(2)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: slave开启MTS时执行mysqldump引发死锁案例

五、关于woker线程w2的等待


这里可能的原因有2个:

  • 多线程并行的情况下,线程执行的顺序本生就是不定的,很可能线程由于丢失CPU而落后其他线程的处理,因为CPU调度的最小单位是线程。如果保证某个共享内存操作的完整性需要用到mutex、原子变量等技术。
  • 如果w2中的事务本生就包含了多个DML语句,那么获取 GLOBAL READ LOCK 本身就是间歇性的,也就是每个语句结束都会释放,然后下一个语句开始的时候再次open table来获取。

我们来看看第二点,只考虑row_format格式的binlog。

我们知道一个事务可以包含多个语句,每条语句都会包含一个map Event和多个DML Event,当本Event是语句的最后一个Event的时候会使用STMT_END_F进行标记,也正是在这个时候会释放 GLOBAL READ LOCK,源码有如下:



if (get_flags(STMT_END_F))
  {
    if((error= rows_event_stmt_cleanup(rli, thd)))

栈:
#0  MDL_context::release_lock (this=0x7fffa8000a08, duration=MDL_STATEMENT, ticket=0x7fffa800ea40) at /opt/percona-server-locks-detail-5.7.22/sql/mdl.cc:4350
#1  0x0000000001464bf1 in MDL_context::release_locks_stored_before (this=0x7fffa8000a08, duration=MDL_STATEMENT, sentinel=0x0) at /opt/percona-server-locks-detail-5.7.22/sql/mdl.cc:4521
#2  0x000000000146541b in MDL_context::release_statement_locks (this=0x7fffa8000a08) at /opt/percona-server-locks-detail-5.7.22/sql/mdl.cc:4813
#3  0x0000000001865c75 in Relay_log_info::slave_close_thread_tables (this=0x341e8b0, thd=0x7fffa8000970) at /opt/percona-server-locks-detail-5.7.22/sql/rpl_rli.cc:2014
#4  0x0000000001865873 in Relay_log_info::cleanup_context (this=0x341e8b0, thd=0x7fffa8000970, error=false) at /opt/percona-server-locks-detail-5.7.22/sql/rpl_rli.cc:1886
#5  0x00000000017e8fc7 in rows_event_stmt_cleanup (rli=0x341e8b0, thd=0x7fffa8000970) at /opt/percona-server-locks-detail-5.7.22/sql/log_event.cc:11782
#6  0x00000000017e8c79 in Rows_log_event::do_apply_event (this=0x7fffa8017dc0, rli=0x341e8b0) at /opt/percona-server-locks-detail-5.7.22/sql/log_event.cc:11660
#7  0x00000000017cfdcd in Log_event::apply_event (this=0x7fffa8017dc0, rli=0x341e8b0) at /opt/percona-server-locks-detail-5.7.22/sql/log_event.cc:3570
#8  0x00000000018476dc in apply_event_and_update_pos (ptr_ev=0x7fffec14f880, thd=0x7fffa8000970, rli=0x341e8b0) at /opt/percona-server-locks-detail-5.7.22/sql/rpl_slave.cc:4766
#9  0x0000000001848d9a in exec_relay_log_event (thd=0x7fffa8000970, rli=0x341e8b0) at /opt/percona-server-locks-detail-5.7.22/sql/rpl_slave.cc:5300
#10 0x000000000184f9cc in handle_slave_sql (arg=0x33769a0) at /opt/percona-server-locks-detail-5.7.22/sql/rpl_slave.cc:7543
(gdb) p ticket->m_lock->key.mdl_namespace()
$1 = MDL_key::GLOBAL
(gdb) p ticket->m_type
$2 = MDL_INTENTION_EXCLUSIVE
(gdb) p ticket->m_duration
$3 = MDL_STATEMENT


如果下一条语句开始又会重新获取GLOBAL READ LOCK,这就是我说的间歇性获取。


到这里死锁条件已经成熟,只要遇到这种情况就可能需要人为介入才能继续了。


六、关于mysqldump


社区版在如下情况下需要增加FTWRL:

  • 设置了master-data
  • 设置了singal-transaction和flush-logs

percona版在如下情况需要增加FTWRL:

  • 设置了singal-transaction和flush-logs

我们来大概看看社区版的代码如下(代码版本8.0.21),下面是从FTWRL倒UNLOCK的过程:



 if ((opt_lock_all_tables || opt_master_data || //如果设置了 master data 设置flush table with read lock

(opt_single_transaction && flush_logs)) &&//如果设置了single transaction和flush logs 设置flush table with read lock
do_flush_tables_read_lock(mysql)) //设置flush table with read lock
goto err;
/*
/*
Flush logs before starting transaction since
this causes implicit commit starting mysql-5.5.
*/
if (opt_lock_all_tables || opt_master_data ||
(opt_single_transaction && flush_logs) || opt_delete_master_logs) {
if (flush_logs || opt_delete_master_logs) {//如果设置了 flush logs 进行日志刷新
if (mysql_refresh(mysql, REFRESH_LOG)) { //进行日志刷新
DB_error(mysql, "when doing refresh");
goto err;
}
verbose_msg("-- main : logs flushed successfully!\n");
}

/ Not anymore! That would not be sensible. /
flush_logs = false;
}

if (opt_delete_master_logs) {
if (get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name))) goto err;
}

if (opt_single_transaction && start_transaction(mysql)) goto err; //开启事务 RR

/ Add 'STOP SLAVE to beginning of dump /
if (opt_slave_apply && add_stop_slave()) goto err;

/* Process opt_set_gtid_purged and add SET @@GLOBAL.GTID_PURGED if required.
*/
if (process_set_gtid_purged(mysql)) goto err; //设置GTID,如果设置了gtid_purged 这个函数会跳过

if (opt_master_data && do_show_master_status(mysql)) goto err; //获取主库binlog位置
if (opt_slave_data && do_show_slave_status(mysql)) goto err; //slave_data 设置相关 从show slave中获取
if (opt_single_transaction &&
do_unlock_tables(mysql)) / unlock but no commit! /
goto err;



percona版本中增加了判断函数 check_consistent_binlog_pos,如下(不过多描述)


 if (opt_single_transaction && opt_master_data)
{
/*
See if we can avoid FLUSH TABLES WITH READ LOCK with Binlog_snapshot_*
variables.
*/
consistent_binlog_pos= check_consistent_binlog_pos(NULL, NULL);
}

if ((opt_lock_all_tables || (opt_master_data && !consistent_binlog_pos) ||//consistent_binlog_pos 0 需要 1 不需要
(opt_single_transaction && flush_logs)))
{
if (do_flush_tables_read_lock(mysql))
goto err;
}



七、如何解决

总结如下:

  • master-data 一般备份都会增加,因此只能在低峰期进行备份,尽量减少影响。
  • 考虑关闭参数 slave_preserve_commit_order。但是FTWRL的堵塞还是存在,只是不会产生死锁。
  • 如果压力不大可以考虑关闭MTS。但是FTWRL的堵塞还是存在,只是不会产生死锁。

全文完。

Enjoy MySQL :)

            </div>
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6月前
|
移动开发 前端开发 JavaScript
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
207 0
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
|
4月前
|
算法 测试技术 PHP
通过阶乘获取一个一维PHP数组中全部的组合情况
在PHP中,`FactorialHandler`类通过递归实现了数组的全组合,`getArrAllCombineByFactor`方法逐个添加元素至所有子组合中。示例代码展示了一个包含组合生成的过程,输出了所有可能的排列。此外,还提供了一个深度优先搜索的递归函数`depth_picker`,用于生成数组的所有组合,从选择单个元素到选择所有元素。这两个示例揭示了递归在处理数组组合问题中的应用,常见于算法设计和测试用例生成。
23 0
通过阶乘获取一个一维PHP数组中全部的组合情况
|
SQL 缓存 关系型数据库
slave开启MTS时执行mysqldump引发死锁案例(1)
slave开启MTS时执行mysqldump引发死锁案例
slave开启MTS时执行mysqldump引发死锁案例(1)
|
SQL 关系型数据库 MySQL
slave开启MTS时执行mysqldump引发死锁案例(2)
slave开启MTS时执行mysqldump引发死锁案例
|
6月前
|
数据采集 数据处理 开发工具
argparse是你的好帮手:快速编写自动化脚本、测试脚本、数据处理脚本
argparse是你的好帮手:快速编写自动化脚本、测试脚本、数据处理脚本
|
SQL 分布式计算 编译器
MaxCompute ODPS重装上阵, IF ELSE分支语句
MaxCompute通过脚本模式支持IF ELSE分支语句,让程序根据条件自动选择执行逻辑,支持更好的处理因数据不同而需要采用不同策略的业务场景产生的复杂SQL,提高开发者编程的灵活性!
866 2
|
设计模式 存储 算法
【Java设计模式 经典设计原则】六 KISS、YAGNI和DRY原则
【Java设计模式 经典设计原则】六 KISS、YAGNI和DRY原则
226 0
|
城市大脑 人工智能 运维
城市大脑 | 城市中枢系统与数字驾驶舱
本文介绍了城市大脑 | 城市中枢系统与数字驾驶舱的方案概述,方案价值及优势以及最佳实践。
城市大脑 | 城市中枢系统与数字驾驶舱
|
安全 jenkins Java
CVE-2017-1000353 Jenkins漏洞复现系列(一)
Jenkins未授权远程代码执行漏洞, 允许攻击者将序列化的Java SignedObject对象传输给Jenkins CLI处理,反序列化ObjectInputStream作为Command对象,这将绕过基于黑名单的保护机制, 导致代码执行
793 0
|
达摩院 大数据 关系型数据库
如何使用ModelScope魔搭训练工业级语音识别模型
如何使用ModelScope魔搭训练工业级语音识别模型
1763 1
如何使用ModelScope魔搭训练工业级语音识别模型