📖 本篇简介:主从复制与高可用是 MySQL 生产部署的核心,也是面试高频考点。本篇以表格化形式汇总主从复制原理、三种同步方式(异步/半同步/组复制)、主从延迟原因、高可用方案对比、主从搭建命令、主从切换命令等内容。所有示例基于 MySQL 8.0 语法。读完你能快速判断主从延迟原因、怎么选高可用方案、怎么搭主从。
主从复制解决读扩展和高可用,高可用解决主库挂了自动切换。这俩是生产 MySQL 的标配。
面试问主从,十有八九会问到主从延迟、半同步、MGR、高可用切换流程这几块。本篇整理成表格,考前过一遍。
目录
- 主从复制原理速查
- 三种同步方式对比
- binlog 格式对比
- 主从延迟原因与排查
- 高可用方案对比
- 主从搭建常用命令
- 主从切换常用命令
- 高可用相关参数速查
- 面试高频问答
- 主从延迟监控指标
- 主从一致性校验
- 读写分离速查
- 自测:主从与高可用速查
主从复制原理速查
主从复制是 MySQL 高可用和读扩展的基础,面试必问。
MySQL 主从复制分三步:
1. 主库把变更写 binlog
2. 从库 IO 线程拉 binlog,写 relay log(中继日志)
3. 从库 SQL 线程重放 relay log,执行变更
-- 主库查看(本示例基于 MySQL 8.0)
SHOW MASTER STATUS; -- 查看 binlog 位点
-- 从库查看
SHOW REPLICA STATUS\G; -- 8.0 用 REPLICA,5.7 用 SLAVE
关键线程:主库 binlog dump 线程、从库 IO 线程、从库 SQL 线程。
复制方式演进:5.7 之前单线程回放 -> 5.7 基于库并行 -> 8.0 基于 LOGICAL_CLOCK 并行,性能大幅提升。
并行复制原理:同一个事务的 commit 之后,其他不冲突的事务可以并行回放。
三种同步方式对比
主从同步有三种方式,性能和安全性折中。
| 方式 | 原理 | 性能 | 数据安全 | 适用 |
|---|---|---|---|---|
| 异步复制 | 主库写完 binlog 就返回,不等从库 | 最高 | 可能丢 | 默认,读扩展 |
| 半同步复制 | 主库等至少一个从库收到 binlog 才返回 | 中 | 丢的少 | 金融、重要业务 |
| 组复制 MGR | 多主一致性协议 Paxos | 低 | 强一致 | 高可用场景 |
-- 开启半同步(本示例基于 MySQL 8.0)
INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so';
SET GLOBAL rpl_semi_sync_source_enabled = 1;
半同步超时降级:半同步等从库超时后,自动降级为异步,性能不受影响。
MGR 要求:至少 3 节点,基于 Paxos 协议,自动选主,强一致。
异步复制风险:主库挂了,没同步到从库的事务就丢了。RPO > 0。
半同步配置:rpl_semi_sync_source_enabled=ON,rpl_semi_sync_replica_enabled=ON。
同步方式选型:一般业务用异步,核心业务用半同步或 MGR。
binlog 格式对比
binlog 格式是主从复制的基础,生产推荐 ROW。
| 格式 | 记录内容 | 优点 | 缺点 |
|---|---|---|---|
| STATEMENT | SQL 语句 | 日志小 | 函数不确定、主从不一致 |
| ROW | 每行变更前后值 | 主从一致、可闪回 | 日志大 |
| MIXED | 自动选 | 折中 | 少用 |
生产推荐 ROW:主从一致、可闪回、避免函数不确定问题。
ROW 模式日志大怎么办:binlog_row_image=MINIMAL,只记录变更列,日志小很多。
STATEMENT 为什么不推荐:像 NOW()、UUID() 这种函数,主从执行结果可能不一样,导致数据不一致。
MIXED 是什么:默认 STATEMENT,遇到不确定函数自动切 ROW。一般不用。
binlog 作用:主从复制、数据恢复、闪回误操作。
binlog 日志大怎么办:定期清理,调 binlog_expire_logs_seconds。
主从延迟原因与排查
| 原因 | 说明 | 解决 |
|---|---|---|
| 大事务 | 从库回放慢 | 拆分大事务 |
| 从库单线程回放 | 8.0 之前 SQL 线程单线程 | 开启并行复制 |
| 从库性能差 | 从库机器配置低 | 升级从库 |
| 慢 SQL | 从库跑了慢查询 | 优化慢 SQL |
| 网络延迟 | 主从跨机房 | 同机房、优化网络 |
| 从库大查询 | 从库跑报表 SQL | 报表走专门从库 |
| 锁竞争 | 从库回放和查询抢锁 | 低峰期跑报表 |
| 大表无主键 | 从库回放慢 | 加主键 |
| 从库磁盘 IO 慢 | 回放写盘慢 | SSD |
| 大事务回放慢 | 一个事务太大 | 拆分事务 |
| 从库并行度不够 | 回放慢 | 调大 slave_parallel_workers |
| 网络延迟大 | binlog 传输慢 | 同机房部署 |
| 主库压力大 | binlog 写慢 | 读写分离 |
-- 查看主从延迟(本示例基于 MySQL 8.0)
SHOW REPLICA STATUS\G
-- 看 Seconds_Behind_Source 字段
高可用方案对比
高可用方案有很多种,根据业务规模和一致性要求选。
| 方案 | 原理 | 优点 | 缺点 | 适用 |
|---|---|---|---|---|
| MHA | 监控主库,挂了自动提升从库 | 成熟、简单 | 需要额外组件 | 中小规模 |
| Orchestrator | 可视化、自动切换 | 界面好 | 要维护 | 中大规模 |
| MGR 组复制 | 多主一致性协议 | 强一致、自动选主 | 配置复杂 | 金融、核心业务 |
| 云 RDS | 云厂商托管 | 免运维 | 贵、 lock-in | 云上业务 |
| Orchestrator | 可视化、自动切换 | 界面好 | 要维护 | 中大规模 |
| Keepalived+VIP | VIP 漂移 | 简单 | 脑裂风险 | 小规模 |
选型建议:云上业务直接用云 RDS,免运维。自建中小规模用 MHA,核心业务用 MGR。
RTO 目标:高可用方案的 RTO 一般要做到秒级,RPO 接近 0。
VIP 是什么:虚拟 IP,客户端连 VIP,主挂了 VIP 飘到新主,客户端无感知。
MHA 是什么:Master High Availability,监控主库,挂了自动选最新从库提升为新主。
MGR 是什么:MySQL Group Replication,基于 Paxos,多节点强一致,自动选主。
主从搭建常用命令
搭主从前要保证主从数据一致,一般用 mysqldump 或 xtrabackup 备份主库恢复到从库,再配复制位点。
-- 主库:创建复制账号(本示例基于 MySQL 8.0)
CREATE USER 'repl'@'10.0.0.%' IDENTIFIED BY 'repl_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.0.%';
-- 从库:配置主库信息(用 GTID 更简单,不用记位点)
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='10.0.0.1',
SOURCE_USER='repl',
SOURCE_PASSWORD='repl_password',
SOURCE_LOG_FILE='binlog.000001',
SOURCE_LOG_POS=156;
-- 从库:启动复制
START REPLICA;
-- 查看从库状态
SHOW REPLICA STATUS\G;
-- 从库跳过错误(不推荐,应急用)
SET GLOBAL sql_slave_skip_counter = 1;
-- 跳过指定 GTID 事务
SET GTID_NEXT = 'aaaaaaaa-1111-2222-3333-444455556666:12345';
BEGIN; COMMIT;
SET GTID_NEXT = 'AUTOMATIC';
主从切换常用命令
主从切换分计划内切换和故障切换。计划内切换要先停写、追数据、再提升从库。故障切换由高可用组件自动完成。
-- 计划内切换:先停主库写入(本示例基于 MySQL 8.0)
SET GLOBAL read_only = ON;
SET GLOBAL super_read_only = ON;
-- 等从库追上
SHOW REPLICA STATUS\G; -- 看 Relay_Master_Log_File 追上主库
-- 直到 Seconds_Behind_Source = 0
-- 提升从库为新主
STOP REPLICA;
RESET REPLICA ALL;
SET GLOBAL read_only = OFF;
SET GLOBAL super_read_only = OFF;
-- 其他从库指向新主
CHANGE REPLICATION SOURCE TO SOURCE_HOST='新主IP';
-- 验证新主可写
SHOW MASTER STATUS;
-- 旧主降级为从库
CHANGE REPLICATION SOURCE TO SOURCE_HOST='新主IP';
START REPLICA;
高可用相关参数速查
| 参数 | 默认值 | 说明 |
|---|---|---|
| binlog_format | ROW | binlog 格式 |
| sync_binlog | 1 | binlog 刷盘策略 |
| innodb_flush_log_at_trx_commit | 1 | redo 刷盘策略 |
| rpl_semi_sync_source_enabled | OFF | 半同步开关 |
| replica_parallel_workers | 0 | 从库并行回放线程数 |
| replica_parallel_type | LOGICAL_CLOCK | 并行回放模式 |
| gtid_mode | OFF | GTID 开关 |
| enforce_gtid_consistency | OFF | GTID 一致性 |
| log_slave_updates | ON | 从库写 binlog |
| binlog_expire_logs_seconds | 2592000 | binlog 保留天数 |
| max_connections | 151 | 最大连接数 |
| innodb_buffer_pool_size | 128M | 缓冲池大小,建议物理内存 70% |
| innodb_log_file_size | 48M | redo log 大小 |
| slow_query_log | OFF | 慢查询日志 |
| long_query_time | 10 | 慢查询阈值(秒) |
| log_bin | ON | 开启 binlog |
| server_id | 1 | 主从唯一 ID |
| gtid_mode | ON | 开启 GTID |
| enforce_gtid_consistency | ON | GTID 强一致 |
| slave_parallel_workers | 4 | 并行回放线程数 |
主从高可用相关参数,生产环境建议按下面调优。
面试高频问答
| 问题 | 一句话答案 |
|---|---|
主从与高可用面试高频题,每题一句话答案,考前过一遍。
| 问题 | 一句话答案 |
|---|---|
| 主从复制原理 | binlog -> relay log -> 重放 |
| 主从延迟为什么大 | 大事务、单线程回放 |
| 半同步和异步区别 | 半同步等从库收 binlog |
| MGR 是什么 | 组复制,多主一致性 |
| 主从延迟怎么排查 | SHOW REPLICA STATUS 看 Seconds_Behind |
| 怎么解决主从延迟 | 并行复制、拆大事务 |
| 高可用方案怎么选 | 中小 MHA,核心 MGR |
| 脑裂是什么 | 两个主库同时写 |
| VIP 切换原理 | VRRP 协议漂移 |
| binlog 为什么用 ROW | 主从一致、可闪回 |
| 主从延迟怎么监控 | Seconds_Behind_Source |
| 什么是 relay log | 从库中转日志,IO 线程写、SQL 线程读 |
| 主从切换要注意什么 | 防脑裂、追数据、改配置 |
| 什么是半同步复制 | 主库等从库收 binlog 才返回 |
| MGR 的优缺点 | 强一致自动选主,但配置复杂 |
| 读写分离怎么做 | 应用路由或中间件 |
| 主从延迟怎么监控 | Seconds_Behind_Source |
| 什么是 relay log | 从库中转日志 |
| 主从切换要注意什么 | 防脑裂、追数据 |
| 什么是 GTID | 全局事务 ID,自动找同步点 |
| 什么是半同步 | 主库等从库收 binlog |
| MGR 几节点 | 至少 3 节点 |
| 主从复制为什么延迟 | 单线程回放、大事务、网络 |
| 怎么修主从不一致 | pt-table-checksum + pt-table-sync |
| 读写分离怎么路由 | 应用层或 ProxySQL |
| GTID 有什么好处 | 自动找同步点,不用记位点 |
| 从库挂了怎么办 | 不影响读,高可用再切 |
| 主从复制为什么用 binlog | 记录所有变更 |
| 什么是 relay log | 从库中转日志 |
| 什么是 GTID | 全局事务 ID,替代位点复制 |
| 主从不一致怎么办 | pt-table-checksum 校验,修复 |
| 高可用 RTO 是什么 | 故障恢复时间目标 |
| RPO 是什么 | 恢复点目标,丢多少数据 |
| 主从延迟怎么解决 | 并行复制、拆大事务 |
| 什么是半同步 | 主库等从库收 binlog |
| MGR 几节点 | 至少 3 节点,Paxos |
| 读写分离怎么做 | 应用路由或中间件 |
| 主从延迟怎么监控 | Seconds_Behind_Source |
| 什么是 relay log | 从库中转日志 |
| 主从切换要注意什么 | 防脑裂、追数据 |
| 什么是 GTID | 全局事务 ID,自动找同步点 |
| 什么是半同步 | 主库等从库收 binlog |
| MGR 几节点 | 至少 3 节点 |
| 主从复制为什么延迟 | 单线程回放、大事务、网络 |
| 怎么修主从不一致 | pt-table-checksum + pt-table-sync |
| 读写分离怎么路由 | 应用层或 ProxySQL |
| GTID 有什么好处 | 自动找同步点,不用记位点 |
| 从库挂了怎么办 | 不影响读,高可用再切 |
| 主从复制为什么用 binlog | 记录所有变更 |
| 什么是 relay log | 从库中转日志 |
主从延迟监控指标
主从延迟是生产最常见的问题,监控这几个指标。
| 指标 | 含义 | 告警阈值 |
|---|---|---|
| Seconds_Behind_Source | SQL 线程落后秒数 | > 30 秒告警 |
| Relay_Log_Space | 中继日志大小 | 持续增长告警 |
| Replica_SQL_Running | SQL 线程是否在跑 | No 就是断了 |
| Exec_Source_Log_Pos | 已回放位点 | 对比主库位点 |
| Retrieved_Gtid_Set | 已收到 GTID | 对比主库 GTID |
| Source_Log_File | IO 线程读到的 binlog 文件 | |
| Relay_Master_Log_File | SQL 线程执行到的 binlog 文件 | |
| Exec_Master_Log_Pos | SQL 线程执行位点 | |
| Replica_SQL_Running | SQL 线程是否在跑 | No 就是断了 |
| Exec_Source_Log_Pos | 已回放位点 | 对比主库位点 |
| Retrieved_Gtid_Set | 已收到 GTID | 对比主库 GTID |
| Replica_IO_Running | IO 线程是否在跑 | No 就是断了 |
| Seconds_Behind_Source | 延迟秒数 | > 30 秒告警 |
| Relay_Log_Space | 中继日志大小 | 持续增长告警 |
| Replica_SQL_Running | SQL 线程是否在跑 | No 就是断了 |
| Exec_Source_Log_Pos | 已回放位点 | 对比主库位点 |
| Retrieved_Gtid_Set | 已收到 GTID | 对比主库 GTID |
主从一致性校验
主从数据要定期校验,不然不一致了都不知道。
-- 用 pt-table-checksum 校验主从一致性(本示例基于 MySQL 8.0)
-- pt-table-checksum --host=主库 --databases=app
-- 从库查差异
SELECT * FROM percona.checksums WHERE master_cnt != this_cnt;
常见不一致原因:从库误写、大事务中断、binlog 格式问题。
修复不一致:先停写,用 pt-table-sync 修复,再追数据。
校验频率:核心表每周一次,一般表每月一次。
校验原理:对每张表计算 checksum,主从对比,不一致就修。
注意事项:校验会加读锁,建议低峰期跑,大表分批校验。
不一致后果:业务读到脏数据,或者切主后丢数据。
读写分离速查
读多写少的业务,用主从读写分离扩展读能力。
| 方案 | 原理 | 优缺点 |
|---|---|---|
| 应用层路由 | 应用自己判断走主还是从 | 灵活、侵入业务 |
| 中间件 ProxySQL | SQL 级路由 | 透明、要维护中间件 |
| 中间件 MyCAT | 分库分表+读写分离 | 功能全、性能损耗 |
读写分离注意:写后读要走主库,否则读不到刚写的数据。
中间件推荐:ProxySQL(轻量、SQL 级路由)、MyCAT(功能全、分库分表)。
写后读问题:写操作后短时间内读走主库,中间件可以配置"写后读主"策略。
读写分离限制:不支持跨库 join,不支持分布式事务。
主库挂了怎么办:高可用组件自动切换,VIP 飘到新主,客户端无感知。
从库挂了怎么办:读请求切到其他从库,不影响写。
自测:主从与高可用速查
下面 12 道题覆盖主从与高可用核心考点,先自己想答案,再展开参考答案。
题 1:主从复制的三步是什么?
<details>
<summary>参考答案</summary>
主库写 binlog -> 从库 IO 线程拉 binlog 写 relay log -> 从库 SQL 线程重放 relay log。
</details>
题 2:主从延迟大怎么排查?
<details>
<summary>参考答案</summary>
SHOW REPLICA STATUS 看 Seconds_Behind_Source。大了就查:是不是大事务、从库是不是单线程回放、从库性能够不够。
</details>
题 3:半同步复制解决什么问题?
<details>
<summary>参考答案</summary>
异步复制主库挂了可能丢数据(binlog 还没传到从库)。半同步等至少一个从库收到 binlog 才返回,减少丢数据风险。
</details>
题 4:MGR 是什么?
<details>
<summary>参考答案</summary>
MySQL Group Replication,组复制。多主基于 Paxos 协议保证一致性,自动选主,不用外部高可用组件。适合核心业务。
</details>
题 5:脑裂是什么?
<details>
<summary>参考答案</summary>
两个主库同时接受写入,数据冲突。VIP 切换如果没做好健康检查,可能出现脑裂。MGR 用 Paxos 避免脑裂。
</details>
题 6:binlog 三种格式区别?
<details>
<summary>参考答案</summary>
STATEMENT 记 SQL,ROW 记行变更,MIXED 混合。生产推荐 ROW,主从一致、可闪回。
</details>
题 7:什么是并行复制?
<details>
<summary>参考答案</summary>
从库 SQL 线程多线程回放 relay log,解决单线程回放慢的问题。8.0 默认 LOGICAL_CLOCK 模式。
</details>
题 8:高可用切换流程是什么?
<details>
<summary>参考答案</summary>
检测主库挂了 -> 选最干净的从库 -> 提升为新主 -> 其他从库指向新主 -> 应用切换连接。全程要自动,RTO 秒级。
</details>
题 9:读写分离怎么解决写后读问题?
<details>
<summary>参考答案</summary>
写操作后的短时间内,读请求走主库。中间件可以做"写后读主"策略,应用层也可以自己控制。
</details>
题 10:MHA 工作原理?
<details>
<summary>参考答案</summary>
MHA Manager 监控主库,主库挂了自动选最同步的从库提升,其他从库指向新主。过程几秒,数据基本不丢。
</details>
题 11:什么是 GTID?
<details>
<summary>参考答案</summary>
全局事务 ID,格式 source_id:transaction_id。替代传统的位点复制,主从切换不用记位点,自动找同步点。8.0 推荐用 GTID。
</details>
题 12:RTO 和 RPO 是什么?
<details>
<summary>参考答案</summary>
RTO 是故障恢复时间目标,多久恢复;RPO 是恢复点目标,能容忍丢多少数据。高可用方案的核心指标就是这两个。
</details>
题 13:什么是半同步复制?
<details>
<summary>参考答案</summary>
主库提交事务后,等至少一个从库收到 binlog 并写 relay log,才返回客户端。减少异步复制丢数据的风险。超时自动降级为异步。
</details>
题 14:为什么推荐 binlog 用 ROW 格式?
<details>
<summary>参考答案</summary>
ROW 记录每行变更前后的值,主从执行结果完全一致,而且可以闪回误操作。STATEMENT 记 SQL,像 NOW() 这种函数主从结果可能不一样。
</details>
题 15:什么是脑裂?怎么避免?
<details>
<summary>参考答案</summary>
脑裂是两个主库同时接受写入,数据冲突。VIP 切换没做好健康检查容易脑裂。避免方法:用 MGR 这种 Paxos 协议的方案,或者 VIP 切换加脚本检查。
</details>
题 16:从库延迟很高怎么办?
<details>
<summary>参考答案</summary>
先看 Seconds_Behind_Source 是不是持续增长。再看是不是大事务、是不是从库在跑报表。优化:拆大事务、从库只读、调并行度、SSD。
</details>
题 17:什么是 GTID?
<details>
<summary>参考答案</summary>
全局事务 ID,每个事务在主库生成一个唯一 ID,从库根据 GTID 自动找同步点,不用记 binlog 文件名和位点。主从切换更简单。
</details>
自测评分:17 道题答对 14 道以上,主从高可用这块面试基本稳了;答对 10~13 道,建议把主从复制三步和高可用方案对比再看一遍;答对 10 道以下,先把 binlog 三步背熟。
使用建议:这张速查卡建议打印出来,搭主从、做切换前翻一遍命令。
面试前重点过:主从复制三步、主从延迟原因、高可用方案对比。这三块是必考题。
线上遇到主从延迟,先查 Seconds_Behind_Source,再查是不是大事务,最后查从库性能。
高可用切换前,一定要确认从库追上主库,不然丢数据。
线上主从延迟超过 30 秒就要告警,超过 5 分钟要介入处理。
主从切换是高危操作,一定要在测试环境演练过再上生产。
线上主从配置一定要用 GTID,切换方便,不用记位点。
(本章完)
下一篇预告:第 80 章 速查卡:分库分表与分布式
文章回复
0 条公开回复