跳到主要内容

主从复制与读写分离

问题

MySQL 主从复制的原理是什么?有哪些复制模式?主从延迟怎么处理?读写分离如何实现?

答案

一、主从复制原理

核心流程(三个线程)

线程位置职责
binlog dump主库读取 binlog 并发送给从库
IO thread从库接收 binlog,写入 relay log
SQL thread从库重放 relay log 中的事件

二、复制模式

1. 异步复制(默认)

主库提交 → 写 binlog → 返回客户端 → 异步发给从库
  • 优点:性能最好,主库不等待从库
  • 缺点:主库宕机时,从库可能丢失已提交的事务

2. 半同步复制(Semi-Sync)

主库提交 → 写 binlog → 等待至少一个从库确认收到 → 返回客户端
  • 优点:至少一个从库有完整数据,数据更安全
  • 缺点:性能有一定下降(等待从库确认的延迟)
参数说明
rpl_semi_sync_master_wait_point=AFTER_SYNC增强半同步(5.7+),等 binlog sync 后再等从库确认
rpl_semi_sync_master_timeout=1000超时退化为异步的毫秒数
AFTER_SYNC vs AFTER_COMMIT
  • AFTER_COMMIT(旧版):主库提交后等从库确认,宕机可能出现幻读
  • AFTER_SYNC(5.7+ 增强):主库 sync binlog 后等从库确认再提交,不会出现幻读

3. 全同步复制

所有从库都确认后才返回。性能最差,实践中很少使用。

4. GTID 复制(推荐)

GTID(Global Transaction Identifier)= server_uuid:transaction_id

GTID = 3E11FA47-71CA-11E1-9E33-C80AA9429562:23
传统复制GTID 复制
基于 binlog 文件名 + 位置基于全局事务 ID
搭建/切换需要手动定位自动找点,简化运维
手动指定 MASTER_LOG_FILE/POS自动定位 MASTER_AUTO_POSITION=1

GTID 复制的优势:

  • 主从切换(故障转移)时自动找到正确的复制位置
  • 可以确认从库是否已执行某个事务

三、并行复制

从库的 SQL 线程是单线程重放 relay log 的,这严重限制了从库的重放速度,导致主从延迟。

版本并行策略粒度
5.6按 schema(数据库)并行不同库的事务可以并行
5.7基于组提交的并行(LOGICAL_CLOCK)同一组提交的事务可并行
8.0基于 writeset 的并行不冲突的事务可并行,效果最好
-- MySQL 5.7+ 配置并行复制
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
SET GLOBAL slave_parallel_workers = 8; -- 并行线程数

四、主从延迟

延迟原因

原因说明
从库机器性能差IO/CPU 不足以跟上主库
从库承担查询压力读请求占用从库资源
大事务一个大事务在从库重放耗时很长
DDLALTER TABLE 等操作阻塞从库
单线程重放5.6 以前只有一个 SQL 线程
网络延迟跨机房部署

延迟监控

SHOW SLAVE STATUS\G
-- 关键字段:
-- Seconds_Behind_Master: 延迟秒数
-- Slave_IO_Running: IO 线程是否运行
-- Slave_SQL_Running: SQL 线程是否运行

延迟解决方案

方案做法
并行复制开启多线程重放
强制走主库关键读操作直接查主库
半同步复制保证至少一个从库不落后太多
避免大事务大事务拆分为小事务
从库性能保证从库机器配置不低于主库

五、读写分离

实现方式

方式代表优点缺点
代码层Spring 主从数据源灵活,可控业务侵入
中间件ShardingSphere、ProxySQL对应用透明多一层组件
DNS/VIP读写分离 DNS简单不够灵活

中间件方案示例

应用 → ProxySQL/ShardingSphere → 写请求 → 主库
→ 读请求 → 从库1 / 从库2(负载均衡)

读写分离的主从延迟问题

写完主库后立即读从库,可能读不到最新数据:

方案做法适用场景
强制走主关键业务写后立即读主库对一致性要求高的操作
延迟检查查从库前检查延迟,超过阈值走主库通用场景
等待复制写后等待从库同步完成再返回半同步复制
会话一致性同一会话的写后读走主库用户级一致性
实践建议
  • 不要追求「所有读都走从库」
  • 写后读走主库 是最简单实用的策略
  • 统计报表、数据分析等非实时查询适合走从库

六、高可用架构

MHA(Master High Availability)

主库宕机时,MHA 自动选择数据最新的从库提升为新主库。

主流高可用方案对比

方案切换方式数据安全复杂度
MHA自动主从切换尽量补齐差异日志
MGR组复制,Paxos 协议强一致
Orchestrator自动发现、拓扑管理依赖复制模式
InnoDB ClusterMGR + Router + Shell强一致,官方方案

常见面试问题

Q1: 主库宕机了怎么办?

答案

  1. 检测宕机:VIP 检测/MHA 心跳检测
  2. 选择新主:选择数据最新的从库(Relay_Log_File 最大的)
  3. 补齐日志:其他从库向新主库同步差异日志
  4. 切换流量:VIP 漂移或 DNS 切换到新主库
  5. 修复旧主:旧主恢复后作为从库挂载到新主

Q2: GTID 复制的限制有哪些?

答案

  • 不支持 CREATE TABLE ... SELECT 语句
  • 不支持在同一事务中同时操作 InnoDB 表和 MyISAM 表
  • 不支持 CREATE TEMPORARY TABLE(在事务中)
  • 使用 ENFORCE_GTID_CONSISTENCY=ON 会拒绝上述操作

Q3: 一主多从和多主的适用场景?

答案

  • 一主多从:读多写少的场景,多个从库分担读压力。简单可靠。
  • 双主(互为主从):写高可用场景,一个主写,另一个待切换。注意自增 ID 步长配置避免冲突。
  • 多主多从(MGR):高可用 + 强一致场景,但复杂度高。

相关链接