MySQL主从复制是指将一个MySQL实例(主库)的数据变更同步到多个其他MySQL实例(从库)的过程,核心目标是实现数据冗余、读写分离和负载均衡。整个同步过程依赖日志记录和线程协作完成,不需要人工干预即可自动同步主库的所有数据变更。

MySQL主从复制的核心组件
主从复制的运行依赖三个核心日志文件和三个关键线程,这些组件共同保障了数据同步的完整性和连续性。
核心日志文件
- binlog(二进制日志):主库上记录所有数据变更操作的日志,包括增删改操作和表结构变更,是主从复制的数据来源。
- relay log(中继日志):从库上临时存储从主库拉取到的binlog内容的日志,从库的SQL线程会读取这个日志执行同步操作。
- master.info文件:从库上记录主库连接信息、同步位点等信息的文件,重启从库后会读取这个文件恢复同步进度。
关键线程
- 主库Binlog Dump线程:主库为每个连接的从库创建该线程,负责读取主库的binlog内容,发送给从库的IO线程。
- 从库IO线程:从库上负责连接主库,接收主库Binlog Dump线程发送的binlog内容,写入本地relay log。
- 从库SQL线程:从库上负责读取relay log中的内容,解析成具体的SQL语句并在从库上执行,完成数据同步。
MySQL主从复制的完整流程
主从复制的整体流程可以分为三个步骤,从主库数据变更开始,到从库完成数据重放结束。
第一步:主库记录数据变更到binlog
当主库执行一条数据变更SQL(比如INSERT、UPDATE、DELETE)时,首先会执行该SQL修改内存中的数据,然后将变更操作记录到binlog中。binlog有三种格式:STATEMENT(记录SQL语句)、ROW(记录行的变更内容)、MIXED(混合前两种格式),生产环境通常使用ROW格式,避免主从数据不一致问题。
我们可以通过以下命令查看主库的binlog相关配置:
-- 查看binlog是否开启 SHOW VARIABLES LIKE 'log_bin'; -- 查看当前正在写入的binlog文件 SHOW MASTER STATUS;
第二步:从库IO线程拉取binlog到relay log
从库启动后,IO线程会连接主库,携带上一次同步的binlog位点信息。主库的Binlog Dump线程接收到请求后,从对应的binlog位点开始读取内容,发送给从库的IO线程。从库IO线程接收到数据后,将其写入本地的relay log文件,同时更新master.info文件中的同步位点信息。
从库上可以通过以下命令查看IO线程的运行状态:
SHOW SLAVE STATUSG -- 关注Slave_IO_Running字段,值为Yes表示IO线程正常运行
第三步:从库SQL线程重放relay log
从库的SQL线程会持续监听relay log的变化,当relay log有新内容写入时,SQL线程会读取其中的变更记录,解析成对应的SQL语句,然后在从库上执行这些语句,完成数据的同步。执行完成后,SQL线程会更新relay log的读取位点,避免重复执行。
同样可以通过SHOW SLAVE STATUSG命令查看SQL线程状态,关注Slave_SQL_Running字段,值为Yes表示SQL线程正常运行。
MySQL主从复制的三种同步模式
根据主库写入binlog后,是否需要等待从库确认接收,主从复制分为三种同步模式,适用不同的业务场景。
| 同步模式 | 原理说明 | 优点 | 缺点 |
|---|---|---|---|
| 异步复制 | 主库写入binlog后立即返回成功,不等待从库接收确认 | 主库性能最高,写入延迟低 | 主库宕机后可能存在数据丢失,从库数据可能落后主库 |
| 半同步复制 | 主库写入binlog后,至少等待一个从库接收binlog并写入relay log后,才返回成功 | 保证至少有一个从库有完整数据,降低数据丢失风险 | 主库写入延迟比异步复制高,依赖从库响应速度 |
| 全同步复制 | 主库写入binlog后,等待所有从库都接收并写入relay log后才返回成功 | 数据一致性最高,所有节点数据完全一致 | 主库写入延迟极高,性能差,很少在生产环境使用 |
常见问题说明
很多开发者会疑惑为什么主从复制会出现延迟,通常原因包括从库硬件性能比主库差、从库上运行了其他耗时查询、主库有大事务导致binlog一次性生成过多内容等。可以通过增加从库数量、提升从库硬件配置、拆分主库大事务等方式缓解延迟问题。
另外需要注意,主从复制默认是异步的,如果业务对数据一致性要求高,建议开启半同步复制,避免主库宕机后从库数据缺失。同时定期监控主从同步状态,及时发现IO线程或SQL线程的异常,保障同步链路正常运行。