MySQL Replay(非 GTID)
非 GTID 情况
1 切换前置检查
1.1 设置只读
执行 "SET GLOBAL READ_ONLY=1";
1.2 检查是否本地回放完成
slave_status.master_log_file == slave_status.relay_master_log_file
同时
slave_status.read_master_log_pos == slave_status.exec_master_log_pos
1.3 停止 slave io_thread
执行 "STOP SLAVE IO_THREAD";4.4 授权 Grant replication privileges for slaves
4.5 返回切换辅助信息
4.5.1 检查逻辑
(1)日志类型判断:
如果 binlog 和 relay log 都不存在,直接返回失败(
NO_LOGS_FIND)。如果 只有 relay log,优先从 relay log 查找。
如果 只有 binlog,优先从 binlog 查找。
如果 两者都存在,进入复杂逻辑(需结合心跳值和节点历史角色判断)。
(2) 心跳值校验(NOT_SURE 分支):
调用
MySQLMgr::GetHeartbeatValue获取心跳表中的最新进度值(value)。根据
has_master_before决定 优先检查 binlog 还是 relay log:曾是主库:先查 binlog(要求 checkpoint 必须与心跳值一致),再查 relay log。
曾是从库:先查 relay log(要求 checkpoint ≥ 心跳值),再查 binlog。
如果两者均未找到匹配的 checkpoint,返回失败。
(3) 结果返回:
通过
use_binlog返回实际使用的日志类型。返回
0(成功)或-1(失败)。
4.5.2 binlog 和 relay log 格式
主从复制:
从库的
relay-log.info文件记录:表示从库已应用到
relay-log.000001的 1234 位置,对应主库的binlog.000005的 5678 位置。
GTID 模式(全局事务标识符):
使用
gtid_executed变量记录已应用的事务 ID 集合,替代文件 + position。
2 提升新主
3 常见问题
3.1 主库故障导致的不完整事务
如果主库在提交事务后、传输binlog给从库的过程中崩溃,从库只接收到部分事务的binlog事件。
此时,Read_Master_Log_Pos 记录已接收到的位置,而Exec_Master_Log_Pos停留在上一个完整事务的结束位置。则 Read_Master_Log_Pos ≠ Exec_Master_Log_Pos , 认为本地回放没有成功
此时 stop slave 会卡 60s。
3.2 本地回放一直未完成
Last updated