技术分享 | slave_relay_log_info 表认知的一些展开
本篇文章向大家介绍《技术分享 | slave_relay_log_info 表认知的一些展开》,主要包括MySQL、数据库,具有一定的参考价值,需要的朋友可以参考一下。
作者:胡呈清
slave_relay_log_info 表是这样的:
mysql> select * from mysql.slave_relay_log_info\G
*************************** 1. row ***************************
Number_of_lines: 7
Relay_log_name: ./mysql-relay.000015
Relay_log_pos: 621
Master_log_name: mysql-bin.000001
Master_log_pos: 2407
Sql_delay: 0
Number_of_workers: 16
Id: 1
Channel_name:
slave_relay_log_info 表存储 slave sql thread 的工作位置。
在从库启动的时候时,读取 slave_relay_log_info 表中存储的位置,并把值传给 "show slave status" 中的 Relay_Log_File、Relay_Log_Pos,下次 "start slave" 是从这个位置开始继续回放 relay log。
slave_relay_log_info 表存储的是持久化的状态、show slave status 输出的是内存中的状态:
- 两者输出的位置可能不一样
- stop slave 或者正常关闭 mysqld,都会将内存中的状态持久化到磁盘上(slave_relay_log_info表中)
- 启动 mysqld 时会读取磁盘状态,初始化给内存状态
- start slave 时生效的是内存状态
slave io thread 按照 Master_Log_File、Read_Master_Log_Pos 位置读取主库的 binlog,并写入到本地 relay log(注意这两个位点信息保存在 slave_master_info 表中);slave sql thread 按照 Relay_Log_Name、Relay_Log_Pos 位置进行 realy log 的回放。
但是同一个事务在从库 relay log 中的 position 和主库 binlog 中的 position 是不相等的,slave_relay_log_info 表通过 Master_log_name、Master_log_pos 这两个字段记录了 relay log 中事务对应在主库 binlog 中的 position。
我们得知道如果 slave io thread 重复、遗漏的读取主库 binlog 写入到 relay log 中,sql thread 也会重复、遗漏地回放这些 relay log。也就是说从库的数据是否正确,io thread 的位置是否正确也非常重要。
在 MySQL 5.6 以前,复制位点信息只能存储在数据目录的 master.info 文件中,在回放事务后更新到文件中(默认每次回放10000个事务更新,受参数 sync_relay_log_info 控制)。即使每个事务都更新文件,意外宕机时也没法保证持久性一致性。
MySQL 5.6 开始,可以设置 --relay-log-info-repository=TABLE,将 slave sql thread 的工作位置存储在 mysql.slave_relay_log_info 表中,如果这个表是 InnoDB 这样的支持事务的引擎,则从库每回放一个事务时都会在这个事务里同时更新 mysql.slave_relay_log_info 表,使得 sql thread 的位置与数据保持一致。事实上在 5.6.0-5.6.5 的版本,slave_relay_log_info 表默认使用的是 MyISAM 引擎,之后的版本才改为 InnoDB,不过再考虑到 MySQL 5.6.10 才 GA,这个坑踩过的人应该不多。
更新机制
引用手册:
sync_relay_log_info = 0 If relay_log_info_repository is set to FILE, the MySQL server performs no synchronization of the relay- log.info file to disk; instead, the server relies on the operating system to flush its contents periodically as with any other file. If relay_log_info_repository is set to TABLE, and the storage engine for that table is transactional, the table is updated after each transaction. (Thesync_relay_log_info setting is effectively ignored in this case.) If relay_log_info_repository is set to TABLE, and the storage engine for that table is not transactional, the table is never updated. sync_relay_log_info = N > 0 If relay_log_info_repository is set to FILE, the slave synchronizes its relay-log.info file to disk (using fdatasync()) after every N transactions. If relay_log_info_repository is set to TABLE, and the storage engine for that table is transactional, the table is updated after each transaction. (Thesync_relay_log_info setting is effectively ignored in this case.) If relay_log_info_repository is set to TABLE, and the storage engine for that table is not transactional, the table is updated after every N events.
一般的运维规范都会要求 relay_log_info_repository=TABLE,默认值 sync_relay_log_info=10000 此时会失效,变成每回放一个事务都会在这个事务里同时更新 mysql.slave_relay_log_info 表,保证持久性,以最终保证复制的数据一致。当然 InooDB 的持久性需要 innodb_flush_log_at_trx_commit=1 来保证。
前面有一句话“也就是说从库的数据是否正确,io thread 的位置是否正确也非常重要”。简单来说 io thread 位置保存在 slave_master_info 表中,其实设置和 relay_log_info_repository 类似,不同的是它的持久化保障通常与性能冲突很大:
- 必须设置 master_info_repository = TABLE 和 sync_master_info=1,刷盘的单位是 binlog event 而不是事务,写放大很严重,性能损耗大
所以通常 sync_master_info 使用默认值 10000, io thread 的位置无法保证持久化,也就没法保证正确。MySQL 有另一个参数 relay_log_recovery 提供一种机制来保证 mysqld crash 后 io thread 位置的准确性,稍后进行介绍。
master_auto_position
master_auto_position 的作用是根据从库的 Executed_Gtid_Set 自动寻找主库上对应 binlog 位置,这是在 GTID 出现后的一个功能。
这里思考一个问题:开启 master_auto_position 后,slave io thread 能直接根据从库的 Executed_Gtid_Set 定位主库上 binlog 的位置吗?还需要 slave_relay_log_info、slave_master_info 表中记录的位点信息吗?
其实 slave_relay_log_info、slave_master_info 表依然发挥作用:
- 当第一次或者 reset slave 后,执行 start slave,io thread 将从库的 Executed_Gtid_Set 发往主库,获取到对应的 File、Position,之后更新到从库的 slave_relay_log_info、slave_master_info 表中
- 当 slave_relay_log_info、slave_master_info 表中存在位置信息后,此后无论是重启复制还是重启 mysqld,都是直接从这两个地方获取 File、Position,并从这里开始读取 binlog 和回放 relay log
注意:执行 "reset slave" 会删除从库上的 relay log,并且重置 slave_relay_log_info 表,即重置复制位置。如果 master_auto_position=0,下次启动复制时会从新开始获取并回放主库的 binlog,造成错误。
relay_log_recovery
当启用 relay_log_recovery,mysqld 启动时,recovery 过程会生成一个新的 relay log,并初始化 slave sql thread 的位置,表现为:
- slave_relay_log_info 表的 Relay_Log_Name 值更新为最新的日志名, Relay_Log_Pos 值更新为一个固定值 4(应该是头部固定信息占 4个偏移量)
- 内存状态即 show slave status 输出中的 Relay_Log_File、Relay_Log_Pos,也更新成上面一样的
并且 slave io thread 的位置也会初始化,表现为:
- slave_master_info 表中的 Master_log_name、Master_log_pos 不会改变
- 内存状态即 show slave status 输出中的 Master_Log_File、Read_Master_Log_Pos,会更新为 slave_relay_log_info 表中 Master_Log_Name、Master_Log_Pos
io thread 这个位置的初始化思路就是:既然以前记录的位置不确定是否准确,那就直接不要了。sql thread 回放到哪,我就从哪开始重新拿主库的 binlog,这样准没错。一个事务在 relay log 中的 position 对应到主库 binlog 的 position 是这样来确定的:
- slave_relay_log_info 表中的 Relay_log_name 与 Master_log_name,Relay_Log_Pos 与 Master_Log_Pos 始终一一对应,代表同一个事务的位置。
所以,即使 sync_master_info 表的持久化无法保证,relay_log_recovery 也会将 io thread 重置到已经回放的那个位置。
relay_log_recovery 的另一个作用是防止 relay log 的损坏,因为默认 relay log 是不保证持久化的(也不推荐设置 sync_relay_log=1),当操作系统或者 mysqld crash 后,sql thread 可能会因为 relay log 的损坏、丢失导致错误。
一些结论
- 当开启 GTID 和 master_auto_position,并设置 relay_log_recovery=1,即使 relay_log_info_repository 设置为 file,操作系统或者 mysqld crash 后,mysqld 下次重启启动复制都能保证数据与主库一致。即使 slave_relay_log_info 表中记录的位置不是最新的,sql thread 可能会重复回放一部分事务,但是从库已经存在这些事务的 GTID,这部分重复的事务会被跳过。
- 当未开启 GTID 和 master_auto_position,必须要设置 relay_log_info_repository=table、relay_log_recovery=1,操作系统或者 mysqld crash 后,mysqld 下次重启启动复制才能保证数据与主库一致。
理论要掌握,实操不能落!以上关于《技术分享 | slave_relay_log_info 表认知的一些展开》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!
-
- 数据库 · MySQL | 12小时前 |
- MySQL 在线 ALTER TABLE 前怎么判断是否会重建表
- 339浏览 收藏
-
- 数据库 · MySQL | 14小时前 | MySQL · 锁 · 事务 · InnoDB · Savepoint ROLLBACK TO SAVEPOINT InnoDB锁
- MySQL SAVEPOINT 回滚后哪些锁仍然保留
- 226浏览 收藏
-
- 数据库 · MySQL | 15小时前 |
- MySQL InnoDB 死锁后为什么只回滚一个事务
- 201浏览 收藏
-
- 数据库 · MySQL | 16小时前 | MySQL · 数据库 · 外键约束 · 数据一致性 · 表结构设计 · mysql 外键 foreign key ON DELETE SET NULL 可空列
- MySQL 外键 ON DELETE SET NULL 为什么要求列可空
- 325浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL JSON_TABLE 展开数组时如何保留缺失字段
- 501浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL CTE 多次引用时为什么可能重复物化
- 237浏览 收藏
-
- 数据库 · MySQL | 1天前 | MySQL · 执行计划 · 索引优化 · mysql explain OR条件 Index Merge
- MySQL OR 条件什么时候会选择 Index Merge
- 373浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL 事务隔离级别下普通 SELECT 为什么看不到新提交
- 385浏览 收藏
-
- 数据库 · MySQL | 1天前 | MySQL · 索引 · 性能优化 · 执行计划 · mysql explain optimizer hint FORCE INDEX USE INDEX
- MySQL optimizer hint 和 FORCE INDEX 怎么选择
- 478浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 92次使用
-
- OpenCompass
- OpenCompass是上海AI实验室推出的开源大模型评测平台,提供CompassKit、CompassHub和CompassRank三大核心组件,支持LLM及多模态模型的一站式标准化评估与排行榜查询。
- 23次使用
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 250次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 176次使用
-
- AI Prompt Library
- 探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
- 108次使用
-
- MySQL 明明加了索引,为什么查询还是很慢?先查这 6 个点
- 2026-06-27 374浏览
-
- 接口返回的数据和数据库不一致怎么办?按数据生命周期排查
- 2026-06-27 398浏览
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- golang 基于 mysql 简单实现分布式读写锁
- 2023-01-07 384浏览
-
- 详解如何利用GORM实现MySQL事务
- 2023-01-07 184浏览

MySql使用总结
