跳到主要内容

主从复制原理

问题

MySQL 主从复制的原理是什么?binlog 有几种格式?GTID 和传统复制有什么区别?

答案

主从复制原理

三个关键线程

  • Master Binlog Dump Thread:主库发送 binlog 给从库
  • Slave IO Thread:从库接收 binlog,写入 relay log
  • Slave SQL Thread:从库重放 relay log 中的事件

Binlog 格式

格式记录内容优势劣势
STATEMENT原始 SQL 语句日志量小不确定函数(NOW/RAND)不安全
ROW每行数据的变更精确、安全日志量大
MIXED智能混合兼顾优势实现复杂
推荐

生产环境推荐 ROW 格式:虽然日志量大,但能保证主从数据一致。MySQL 8.0 默认使用 ROW。

复制模式

异步复制(默认)

问题:主库提交后立即返回,如果主库崩溃,已提交但未同步到从库的数据会丢失。

半同步复制(Semi-Sync)

至少一个从库确认收到 binlog 后,主库才返回成功。如果超时(默认 10s),自动降级为异步复制。

-- 主库开启半同步
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
SET GLOBAL rpl_semi_sync_master_timeout = 10000; -- 10 秒

-- 从库开启半同步
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled = 1;

全同步复制

所有从库都确认后才返回。性能最差,很少使用。MySQL Group Replication 提供了类似的强一致方案。

GTID 复制

GTID(Global Transaction ID)是 MySQL 5.6 引入的全局事务标识符:

GTID = server_uuid:transaction_id
例如:3E11FA47-71CA-11E1-9E33-C80AA9429562:23
对比传统复制GTID 复制
定位binlog 文件名 + 偏移量GTID
切换主库需计算偏移量自动定位
一致性手动保证GTID 保证不重复执行
配置复杂简单
-- 开启 GTID(my.cnf)
-- gtid_mode = ON
-- enforce_gtid_consistency = ON

-- 配置从库使用 GTID
CHANGE MASTER TO
MASTER_HOST = '192.168.1.1',
MASTER_USER = 'repl',
MASTER_PASSWORD = 'password',
MASTER_AUTO_POSITION = 1; -- GTID 自动定位

主从延迟

主从延迟是最常见的运维问题:

延迟原因

原因说明
从库单线程回放主库并发写入,从库单 SQL 线程串行回放
大事务一个大 DELETE/UPDATE 在从库回放很慢
从库性能差从库硬件配置低于主库
网络延迟主从跨机房/跨地域

监控延迟

SHOW SLAVE STATUS\G
-- Seconds_Behind_Master: 主从延迟秒数
-- 0 = 无延迟,NULL = 复制断开

优化手段

  1. 多线程复制(MySQL 5.7+):
SET GLOBAL slave_parallel_workers = 8;
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';
  1. 避免大事务:分批执行大 UPDATE/DELETE
  2. 从库升级硬件:SSD、更多内存
  3. 业务容忍:写后读强制走主库

常见面试问题

Q1: 主从复制有几种模式?区别是什么?

答案

模式数据安全性能说明
异步复制可能丢数据最好默认模式
半同步复制至少一个从库收到略慢推荐生产使用
全同步复制所有从库确认最慢很少使用

Q2: binlog 的 ROW 和 STATEMENT 格式怎么选?

答案

推荐 ROW 格式

  • STATEMENT 格式对不确定函数(NOW()UUID())可能导致主从不一致
  • ROW 格式记录每行的修改,保证精确一致
  • MySQL 8.0 默认 ROW
  • 缺点是日志量大,可用 binlog_row_image=MINIMAL 只记录变更列

Q3: GTID 复制相比传统复制有什么优势?

答案

  1. 主从切换简单:不需要计算 binlog 位置,GTID 自动定位
  2. 一致性保证:同一 GTID 不会在从库重复执行
  3. 故障恢复快:从库知道自己执行到哪个 GTID,重新同步时自动跳过已执行的
  4. 更易运维:MHA/Orchestrator 等工具基于 GTID 更容易实现高可用切换

Q4: 如何解决主从延迟?

答案

  1. 多线程复制:开启 slave_parallel_workers,按事务组并行回放
  2. 避免大事务:大 DML 分批执行
  3. 写后读走主库:关键业务写入后立即读取时,强制查主库
  4. 升级硬件:从库用 SSD
  5. 减少从库负载:避免在从库上执行重查询

相关链接