前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >故障分析 | 一则 MySQL 从节点 hung 死问题分析

故障分析 | 一则 MySQL 从节点 hung 死问题分析

作者头像
爱可生开源社区
发布于 2024-04-11 07:51:59
发布于 2024-04-11 07:51:59
39500
代码可运行
举报
运行总次数:0
代码可运行

近期,发现一个 MySQL 从节点提示同步异常。执行 show replica status 都被挂起。

重要信息

MySQL 版本

8.0.27

架构

主从模式

binlog_transaction_dependency_tracking

WRITESET

replica_parallel_workers

16

1初步分析

1.1 连接情况

当前连接的线程情况

当前连接中,运行的 16 个 worker 线程。其中:

  • 4 个状态为 Waiting for preceding transaction to commit
  • 11 个状态为 Applying batch of row changes
  • 1 个状态为 Executing event

线程等待时间 137272 秒(38 小时左右)。

同时看到执行的 show replica statusflush logs 命令都被挂起。

1.2 InnoDB Status 输出

根据 innodb status 输出结果:检查 ROW OPERATIONSFILE I/O,未见几个典型的问题,比如 innodb_thread_concurrency 配置不合理导致无法进入 InnoDB。

1.3 负载情况

检查系统负载,线程模式查看所有线程的状态。发现 MySQL 的 ib_log_checkpt 线程 CPU 使用率一直处于 100% 的状态。其它线程都处于空闲状态。

1.4 错误日志

检查错误日志,未见相关的错误日志记录。

1.5 慢查询

检查慢查询日志,未见相关的慢查询记录。

1.6 分析小结

我们知道当前版本存在一些已知缺陷,根据主从线程的状态,首先想到可能是由于多线程复制(MTS)的缺陷(Bug 103636 :MySQL 8.0 MTS 定时炸弹)导致。

但根据之前发现的案例,如果是该缺陷导致,在Bug触发了这么久,worker线程的状态应该都是处于 Waiting for preceding transaction to commit 状态,与此处现象不相符。

2结合源码进一步分析

结合源码对 MTS 相关的逻辑进行梳理。关键逻辑如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// STEP-1: 启动时,根据配置参数,分配 commit_order_mngr
|-handle_slave_sql (./sql/rpl_replica.cc:6812)
  |-Commit_order_manager *commit_order_mngr = nullptr
  |-if (opt_replica_preserve_commit_order && !rli->is_parallel_exec() && rli->opt_replica_parallel_workers > 1)
    |-commit_order_mngr = new Commit_order_manager(rli->opt_replica_parallel_workers)
  |-rli->set_commit_order_manager(commit_order_mngr) // 设置 commit_order_mngr
// STEP-2: 执行event时,分配提交请求的序列号
|-handle_slave_sql (./sql/rpl_replica.cc:7076)
  |-exec_relay_log_event (./sql/rpl_replica.cc:4905)
    |-apply_event_and_update_pos (./sql/rpl_replica.cc:4388)
      |-Log_event::apply_event (./sql/log_event.cc:3307)
        |-Log_event::get_slave_worker (./sql/log_event.cc:2770)
          |-Mts_submode_logical_clock::get_least_occupied_worker (./sql/rpl_mta_submode.cc:976)
            |-Commit_order_manager::register_trx (./sql/rpl_replica_commit_order_manager.cc:67)
              |-this->m_workers[worker->id].m_stage = cs::apply::Commit_order_queue::enum_worker_stage::REGISTERED
              |-this->m_workers.push(worker->id)
                // 此节点的 worker 正在处理的提交请求的序列号,其取值为每次从 m_commit_sequence_generator(提交序列号计数器) 加 1 后所得
                // m_commit_sequence_generator 应该是全局的
                // 每次 start slave 之后会重新初始化
                |-this->m_workers[index].m_commit_sequence_nr->store(this->m_commit_sequence_generator->fetch_add(1))
                // 将worker id 加入到 m_commit_queue 的尾部
                |-this->m_commit_queue << index
|-...
|-handle_slave_worker (./sql/rpl_replica.cc:5891)
  |-slave_worker_exec_job_group (./sql/rpl_rli_pdb.cc:2549)
    |-Slave_worker::slave_worker_exec_event (./sql/rpl_rli_pdb.cc:1760)
      |-Xid_apply_log_event::do_apply_event_worker (./sql/log_event.cc:6179)
        |-Xid_log_event::do_commit (./sql/log_event.cc:6084)
          |-trans_commit (./sql/transaction.cc:246)
            |-ha_commit_trans (./sql/handler.cc:1765)
              |-MYSQL_BIN_LOG::commit (./sql/binlog.cc:8170)
                // STEP-3: 提交事务前,判断worker队列状态和位置,使用MDL锁,等待释放事务锁
                |-MYSQL_BIN_LOG::ordered_commit (./sql/binlog.cc:8749)
                  // 在该函数会控制,只有 slave 的worker 线程由于持有commit_order_manager, 才会在此处进行 mngr->wait
                  |-Commit_order_manager::wait (./sql/rpl_replica_commit_order_manager.cc:375)
                    |-if (has_commit_order_manager(thd)): // 确认有 commit_order_manager 对象,该对象只要在开启并行符合和从库提交顺序一致后,才不为nullptr
                      |-Commit_order_manager::wait (./sql/rpl_replica_commit_order_manager.cc:153)
                        |-Commit_order_manager::wait_on_graph (./sql/rpl_replica_commit_order_manager.cc:71)
                          |-this->m_workers[worker->id].m_stage = cs::apply::Commit_order_queue::enum_worker_stage::FINISHED_APPLYING
                          // Worker is first in the queue
                          |-if (this->m_workers.front() != worker->id) {}
                          // Worker is NOT first in the queue
                          |-if (this->m_workers.front() != worker->id):
                            |-this->m_workers[worker->id].m_stage = cs::apply::Commit_order_queue::enum_worker_stage::REQUESTED_GRANT
                            |-set_timespec(&abs_timeout, LONG_TIMEOUT);  // Wait for a year
                            // 等待 MDL 锁
                            |-auto wait_status = worker_thd->mdl_context.m_wait.timed_wait(worker_thd, &abs_timeout,...)
                // STEP-4: 提交事务后,自增获取下一个 worker、sequence_number,然后释放对应的锁。
                //         释放了之后,其它worker就会在STEP-3中获取到锁,否则就会一直在STEP-3 等待
                |-MYSQL_BIN_LOG::ordered_commit (./sql/binlog.cc:8763)
                  |-MYSQL_BIN_LOG::change_stage (./sql/binlog.cc:8483)
                    |-Commit_stage_manager::enroll_for (./sql/rpl_commit_stage_manager.cc:209)
                      |-Commit_order_manager::finish_one (./sql/rpl_replica_commit_order_manager.cc:454)
                        |-Commit_order_manager::finish_one (./sql/rpl_replica_commit_order_manager.cc:300)
                          // 获取 commit_queue 的第一个 worker 线程: next_worker
                          |-auto next_worker = this->m_workers.front()
                          // 确认 next_worker 线程的状态,并比对 m_commit_sequence_nr。
                          // 如果满足,则设置 mdl 锁状态为 GRANTED,即唤醒 next_worker 执行 ordered_commit 的后续操作
                          |-if (this->m_workers[next_worker].m_stage in (FINISHED_APPLYING,REQUESTED_GRANT) and
                                /* 对比 next_worker 的 m_commit_sequence_nr 与 next_seq_nr:
                                   如果 m_commit_sequence_nr == next_seq_nr, 则 返回 true , 然后将 m_commit_sequence_nr = SEQUENCE_NR_FROZEN(1)
                                   如果 m_commit_sequence_nr != next_seq_nr, 则 返回 false
                                */
                               this->m_workers[next_worker].freeze_commit_sequence_nr(next_seq_nr))
                            // 如果 if 条件满足, 设置 next_worker 为授权状态
                            |-this->m_workers[next_worker].m_mdl_context->m_wait.set_status(MDL_wait::GRANTED)
                            /* 对比 next_worker的 m_commit_sequence_nr 与 next_seq_nr
                               如果 m_commit_sequence_nr == 1, 则 返回 true , 然后将 m_commit_sequence_nr = next_seq_nr
                               如果 m_commit_sequence_nr != 1, 则 返回 false
                            */
                            |-this->m_workers[next_worker].unfreeze_commit_sequence_nr(next_seq_nr)
                          |-this->m_workers[this_worker].m_mdl_context->m_wait.reset_status()
                          // 标记当前状态为终态(FINISHED)
                          |-this->m_workers[this_worker].m_stage = cs::apply::Commit_order_queue::enum_worker_stage::FINISHED
                                             

为便于下文说明,对于 MTS 的 16 个 worker 线程,分类如下:

  • A 类: 4 个 worker 线程的状态为 Waiting for preceding transaction to commit
  • B 类: 11 个 worker 线程的状态为 Applying batch of row changes
  • C 类: 1 个 worker 线程的状态为 Executing event

论点 1

假设是由于 Bug 103636 导致该问题,那么 worker 线程应该会在执行提交操作的时候,在 ordered_commit 函数执行的开始位置,由于无法获取 MDL 锁而进行等待,通过 show processlist 查看 worker 线程的状态应该为 Waiting for preceding transaction to commit

而且通过 debug 验证发现,一旦该问题被触发,那么所有的 worker(即使只有一个 worker 在执行事务),都会进入到 ordered_commit 函数,然后由于无法获取 MDL 锁,都会在相同的位置进行等待。即应该是所有 worker 线程处于 Waiting for preceding transaction to commit 状态。

因此,初步判断该问题现象和 bug 103636 不相符合。

论点 2

从因果关系来看:如果是由于 bug 103636 作为问题的原因,结合论点 1 的分析,无法完全说明问题现象。

但相对的,可能是由于其它原因,导致以上 B 类和 C 类的 worker 线程无法顺利执行事务,从而导致 A 类 worker 线程在提交的时候,由于具有较小的 commit_sequence 事务的 worker 线程还未提交执行操作,因此进行等待,导致其线程状态为 Waiting for preceding transaction to commit。如此更能合理的解释当前数据库的状态。

那又是什么原因,导致 B 类、C 类线程无法提交?根据采集信息,发现1个奇怪的症状:

根据的 CPU 使用情况,问题时段的 ib_log_checkpt 一直是处于 100% 的 CPU 在运行。

3根因分析

3.1 ib_log_checkpt 堆栈分析

根据 top 的线程 ID、堆栈以及 perf report 信息:

结合 log_checkpoint 的实现,我们看到该线程,主要是执行 dirty page flush 操作。具体包括:

buf_pool_get_oldest_modification_approx 实现分析,一直在循环遍历,找 dirty page 的最小 LSN。然后根据该 LSN 进行异步 IO 刷 dirty page 操作。

由于 buf_pool_get_oldest_modification_approx 一直在跑,猜测可能是异步 IO 慢。导致检查点无法完成,一直在寻找最小的 LSN。为此,进一步分析系统 IO 压力。

3.2 系统 IO 负载情况

根据以上 IO 负载情况,发现问题时段服务器 IO 压力分析,与上述猜想不想符!那是因为什么原因导致该问题呢?难道是无法找到最小 LSN,或者寻找比较慢?

3.3 再次分析 InnoDB Status

根据以上分析结果,再次分析了相关采集数据。发现 innodb status 输出包含如下信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
LOG
---
Log sequence number          54848990703166
Log buffer assigned up to    54848990703166
Log buffer completed up to   54848990703166
Log written up to            54848990703166
Log flushed up to            54848990703166
Added dirty pages up to      54848990703166
Pages flushed up to          54846113541560
Last checkpoint at           54846113541560
5166640859 log i/o's done, 0.00 log i/o's/second
----------------------

发现当前 InnoDB 中的 Redo 日志使用量=最新 lsn - checkpoint lsn=54848990703166-54846113541560=2,877,161,606=2.68GB。

而此时数据库的 InnoDB Redo Log 配置为:

  • innodb_log_file_size | 1073741824
  • innodb_log_files_in_group | 3

即总的日志大小=1073741824*3=3GB

根据 MySQL 官方说明,需要确保 Redo 日志使用量不超过 Redo 总大小的 75%,否则就会导致数据库出现性能问题。但问题时刻我们的日志使用率=2.68/3=89%,超过 Redo 日志使用率的建议值 14%。

4问题总结与建议

4.1 问题总结

综合以上分析过程,导致此次故障的根本原因还是在于数据库的 Redo 配置参数过小,在问题时段从节点的压力下,Redo 的使用率过高,导致 InnoDB 无法完成检查点。并进一步导致从节点的 worker 线程在执行事务时,检查 Redo Log 是否存在有剩余 Log 文件时,而发生等待。当前一个 worker 线程执行事务挂起后,由于从节点采用 MTS,且 slave_preserve_commit_order=on,因此其它 worker 线程需要等待之前的事务提交,最终导致所有 worker 线程挂起。

4.2 解决建议

  • 增加 Redo Log 文件的大小
  • 升级到 MySQL 8.0 的最新版本,解决 Bug 103636 等关键 bug
  • 增加 innodb_buffer_pool_size 内存大小

4.3 复杂问题针对数据采集建议

针对以上所有问题数据的采集,分享针对 MySQL 复杂问题的问题采集命令。具体如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
来自:李锡超 -- <未知问题重启前信息采集>

su - mysql
currdt=`date +%Y%m%d_%H%M%S`
echo "$currdt" > /tmp/currdt_tmp.txt
mkdir /tmp/diag_info_`hostname -i`_$currdt
cd /tmp/diag_info_`hostname -i`_$currdt

-- 1. mysql进程负载
su - 
cd /tmp/diag_info_`hostname -i`_`cat /tmp/currdt_tmp.txt`

ps -ef | grep -w mysqld
mpid=`pidof mysqld`
echo $mpid

-- b: 批量模式; n: 制定采集测试; d: 间隔时间; H: 线程模式; p: 指定进程号
echo $mpid
top -b -n 120 -d 1 -H -p $mpid > mysqld_top_`date +%Y%m%d_%H%M%S`.txt

-- 2. 信息采集步骤--- 以下窗口,建议启动额外的窗口执行
mysql -uroot -h127.1 -p

tee var-1.txt
show global variables;

tee stat-1.txt
show global status;

tee proclist-1.txt
show full processlist\G
show full processlist;

tee slave_stat-1.txt
show slave status\G

tee threads-1.txt
select * from performance_schema.threads \G

tee innodb_trx-1.txt
select * from information_schema.innodb_trx \G

tee innodb_stat-1.txt
show engine innodb status\G

tee innodb_mutex-1.txt
SHOW ENGINE INNODB MUTEX;

-- 锁与等待信息
tee data_locks-1.txt

-- mysql8.0
select * from performance_schema.data_locks\G
select * from performance_schema.data_lock_waits\G

-- mysql5.7
select * from information_schema.innodb_lock_waits \G
select * from information_schema.innodb_locks\G


-- 3. 堆栈信息
su - 
cd /tmp/diag_info_`hostname -i`_`cat /tmp/currdt_tmp.txt`

ps -ef | grep -w mysqld
mpid=`pidof mysqld`
echo $mpid

-- 堆栈信息
echo $mpid
pstack $mpid > mysqld_stack_`date +%Y%m%d_%H%M%S`.txt

-- 线程压力
echo $mpid

perf top
echo $mpid
perf top -p $mpid

perf record -a -g -F 1000 -p $mpid -o pdata_1.dat
perf report -i pdata_1.dat

-- 4. 等待 30SELECT SLEEP(60);

-- 5. 信息采集步骤--- 以下窗口,建议启动额外的窗口执行
mysql -uroot -h127.1 -p

tee var-2.txt
show global variables;

tee stat-2.txt
show global status;

tee proclist-2.txt
show full processlist\G
show full processlist;

tee slave_stat-2.txt
show slave status\G

tee threads-2.txt
select * from performance_schema.threads \G

tee innodb_trx-2.txt
select * from information_schema.innodb_trx \G

tee innodb_stat-2.txt
show engine innodb status\G

tee innodb_mutex-2.txt
SHOW ENGINE INNODB MUTEX;

-- 锁与等待信息
tee data_locks-2.txt

-- mysql8.0
select * from performance_schema.data_locks\G
select * from performance_schema.data_lock_waits\G

-- mysql5.7
select * from information_schema.innodb_lock_waits \G
select * from information_schema.innodb_locks\G


-- 6. 堆栈信息
su - 
cd /tmp/diag_info_`hostname -i`_`cat /tmp/currdt_tmp.txt`

ps -ef | grep -w mysqld
mpid=`pidof mysqld`
echo $mpid

-- 堆栈信息
echo $mpid
pstack $mpid > mysqld_stack_`date +%Y%m%d_%H%M%S`.txt

-- 线程压力
echo $mpid

perf top
echo $mpid
perf top -p $mpid

perf record -a -g -F 1000 -p $mpid -o pdata_2.dat
perf report -i pdata_2.dat

--- END --

以上信息仅供交流,作者水平有限,如有不足之处,欢迎在评论区交流。

本文关键字:#MySQL# #复制# #Hung#

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-04-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱可生开源社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
故障分析 | MySQL 从机故障重启后主从同步报错案例分析
现居珠海,主要负责 Oracle、MySQL、mongoDB 和 Redis 维护工作。
爱可生开源社区
2022/04/06
9520
MySQL里Wating for Slave workers to free pending events到底在等什么
这是一位朋友给我的一个截图,说show slave status一直处于Wating for Slave workers to free pending events状态,这个库是MTS从库,版本为5.7.25
用户1278550
2021/11/26
5820
MySQL在国产化ARM架构下的首个大坑
本文介绍了MySQL数据库在国产化ARM环境中出现的第一个大坑——从库复制延迟。作者首先分析了导致这一现象的原因,包括主库的binlog dump线程、从库的IO线程、从库的SQL线程及协调线程等各个方面的因素。然后,作者进行了详细的调试和分析,发现了社区版MySQL在ARM架构下存在的获取CPU缓存行大小函数兼容性BUG。最后,作者提出了解决方案并在国产ARM架构中使用TXSQL避免了这个问题。
吹水老王
2023/11/13
3.2K0
MySQL主从复制之增强半同步(无损复制)、延迟复制和并行复制
MySQL有四种同步方式: 1、异步复制(Async Replication) 2、同步复制(sync Replication) 3、半同步复制(Async Replication) 4、增强半同步复制(lossless Semi-Sync Replication)、无损复制
AiDBA宝典
2023/04/26
7.6K0
MySQL主从复制之增强半同步(无损复制)、延迟复制和并行复制
MySQL案例:延迟一个小时了,Seconds_Behind_Master 还是 0 ?
最近有接到一个咨询,腾讯云数据库 MySQL 的只读实例出现了同步延迟,但是监控的延迟时间显示为 0,而且延迟的 binlog 距离非 0,且数值越来越大。临时解决之后,仔细想了一想,Seconds_Behind_Master 虽然计算方式有点坑,但是出现这么“巨大”的误差还是挺奇怪的,复习一下计算方式的同时,也顺便记录一下对这个问题的研究。
王文安@DBA
2021/06/08
2.2K2
MySQL案例:延迟一个小时了,Seconds_Behind_Master 还是 0 ?
技术分享 | MySQL:从库出现 system lock 的原因
本文为笔者 2 年前写一篇说明性文章,发现很多同学都在问这个问题,因此做一次分享。
爱可生开源社区
2020/03/31
3.1K0
故障分析 | 全局读锁一直没有释放,发生了什么?
爱可生交付服务部团队北京 DBA,主要负责处理 MySQL 的 troubleshooting 和我司自研数据库自动化管理平台 DMP 的日常运维问题,对数据库及周边技术有浓厚的学习兴趣,喜欢看书,追求技术。
爱可生开源社区
2021/01/14
1.2K0
故障分析 | 全局读锁一直没有释放,发生了什么?
MYSQL 8 上云 performance_schema 里面参数我们打开了那些 5个表调整脚本?(POLARDB 适用)
关于监控如果上云后,到底还需要自行进行监控吗,是一个问题,是否把所有的数据库监控都放到云上,通过云来获取数据库的信息是一个问题。
AustinDatabases
2022/07/13
9180
MYSQL 8  上云 performance_schema 里面参数我们打开了那些  5个表调整脚本?(POLARDB 适用)
源码分析 | 详解 binlog 时间戳与 exec_time 的关系
近期,某系统进行测试时,发现主从同步存在延迟,随即通过 binlog 确认延迟原因。当使用 mysqlbinlog 命令解析后,发现其中的信息“似懂非懂”。
爱可生开源社区
2024/05/20
1980
源码分析 | 详解 binlog 时间戳与 exec_time 的关系
源码分析 | MySQL 的 commit 是怎么 commit 的?
爱可生 DBA 团队成员,主要负责 MySQL 故障处理和 SQL 审核优化。对技术执着,为客户负责。
爱可生开源社区
2023/08/18
6940
源码分析 | MySQL 的 commit 是怎么 commit 的?
rds mysql主从同步延迟排查与解决
从库严重严重落后于主库,读写分离业务失真,基于从库做的报表数据出不来以及基于从库做的数据探查失效。
叔牙
2023/06/21
1K0
rds mysql主从同步延迟排查与解决
技术分享 | MySQL 复制那点事 - Seconds_behind_Master 参数调查笔记
本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
爱可生开源社区
2020/08/28
2.3K0
故障分析 | 从库并行回放死锁问题分析
爱可生服务团队成员,负责处理客户在 MySQL 日常运维中遇到的问题;擅长处理备份相关的问题,对数据库相关技术有浓厚的兴趣,喜欢钻研各种问题。
爱可生开源社区
2021/01/13
1.1K0
PolarDB MySQL 加索引卡主的整体解决方案
在使用PolarDB for MySQL的过程中,我们遇到一个问题,PolarDB 8.02的小版本8.02.2.24 在添加索引的时候,会有部分情况无法添加索引,添加索引失败。具体表现是如下图:
AustinDatabases
2025/04/10
1310
PolarDB MySQL 加索引卡主的整体解决方案
技术分享 | 从库 MTS 多线程并行回放(一)
这里只准备讨论基于 LOGICAL_CLOCK 的并发方式,而不会讨论老的基于 DATABASE 的方式,下面是我设置的参数:
爱可生开源社区
2020/03/13
1.7K0
由MySQL复制延迟说起
相信 slave 延迟是MySQL dba 遇到的一个老生长谈的问题了。我们先来分析一下slave延迟带来的风险
用户1278550
2019/04/25
1.3K0
由MySQL复制延迟说起
深入理解MySQL 5.7 GTID系列(五) gtid_executed&amp;amp;gtid_purged什么时候更新
本节将集中讨论下面三种GTID更新的时机,这部分相当重要,后面的故障案列会和这节有关。下面先来看一下他们的定义:
wubx
2019/02/27
1.3K0
MySQL 8 复制(二)——半同步复制
直到目前的最新版本为止,MySQL缺省依然使用异步复制策略。简单说所谓异步复制,指的是主库写二进制日志、从库的I/O线程读主库的二进制日志写本地中继日志、从库的SQL线程重放中继日志,这三步操作都是异步进行的。如此选择的主要理由是出于性能考虑,与同步复制相比,异步复制显然更快,同时能承载更高的吞吐量。但异步复制的缺点同样明显,不能保证主从数据实时一致,也无法控制从库的延迟时间,因此它不适于要求主从数据实时同步的场景。例如,为了分解读写压力,同一程序写主库读从库,但要求读到的数据与读主库的相同,异步复制不满足这种强数据一致性需求。异步复制的另一个问题是可能会有数据丢失,例如主库宕机时,已经提交的事务可能还没有传到从库上,如果此时强行主从切换,可能导致新主库上的数据不完整。
用户1148526
2019/05/25
5.4K0
Mysql8.4基于GTID主从部署以及故障修复
MySQL 8.4是一个稳定和高性能的关系型数据库管理系统,支持各种操作系统平台,包括Linux、Windows和macOS。部署MySQL 8.4通常包括安装、配置、优化和测试等步骤
DBA实战
2024/09/26
5460
Mysql8.4基于GTID主从部署以及故障修复
技术分享 | 从库 MTS 多线程并行回放(二)
这一节会先描述 MTS 的工作线程执行 Event 的大概流程。然后重点描述一下 MTS 中检查点的概念。在后面的第 25 节我们可以看到,MTS 的异常恢复很多情况下需要依赖这个检查点,从检查点位置开始扫描 relay log 做恢复操作,但是在 GTID AUTO_POSITION MODE 模式且设置了 recovery_relay_log=1 的情况下这种依赖将会弱化。
爱可生开源社区
2020/03/13
9530
推荐阅读
相关推荐
故障分析 | MySQL 从机故障重启后主从同步报错案例分析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档