深入理解 MySQL 主从同步
在现代数据库架构中,MySQL 主从同步是实现高可用、读写分离和数据备份的核心技术。它通过复制机制将主库的数据变更同步到从库,既提高了系统的可用性,又能有效分担主库的访问压力。本文将从原理、搭建步骤到优化实践,全面解析 MySQL 主从同步。
一、主从同步的核心原理
MySQL 主从同步基于"日志复制-重放"机制,通过三个关键线程协同工作,采用从库主动拉取(Pull)的模式实现数据同步。
1. 核心组件与角色
-
主库(Master):
- 负责处理所有写操作(INSERT/UPDATE/DELETE 等)
- 将所有数据变更记录到二进制日志(binlog)
- 启动 dump 线程,响应从库的日志请求并传输 binlog
-
从库(Slave):
- 启动 IO 线程:主动连接主库,拉取 binlog 并写入本地中继日志(relay log)
- 启动 SQL 线程:读取 relay log,重放其中的 SQL 操作以同步数据
- 通常配置为只读(read_only=ON),避免直接写入破坏数据一致性
2. 同步流程详解
-
日志记录阶段:主库执行写操作时,会将操作细节按顺序记录到 binlog 中,每条记录包含操作类型、数据变更和位置信息。
-
日志拉取阶段:从库的 IO 线程主动连接主库,通过主库的 dump 线程获取指定位置后的 binlog 内容,写入本地 relay log。
-
日志重放阶段:从库的 SQL 线程读取 relay log 中的操作,按顺序在从库执行,使从库数据与主库保持一致。
这种"从库拉取"模式的优势在于:
- 主库无需关心从库状态,降低耦合度
- 从库可自主控制同步节奏,灵活应对网络波动
- 支持一主多从架构,各从库独立同步,互不影响
二、主从同步搭建实战
1. 环境准备
- 主库:MySQL 5.7+,IP:192.168.1.100
- 从库:MySQL 5.7+,IP:192.168.1.101
- 确保主从库版本兼容,网络互通(3306 端口开放)
2. 主库配置
步骤 1:开启 binlog 并配置唯一标识
编辑主库配置文件(my.cnf 或 my.ini):
[mysqld]
# 主库唯一 ID(整数,与从库不同)
server-id = 1
# 开启 binlog 并指定存储路径
log_bin = /var/lib/mysql/binlog
# 推荐使用 ROW 格式,保证主从数据一致性
binlog_format = ROW
# binlog 保留 7 天,避免磁盘占满
expire_logs_days = 7
重启主库使配置生效:
systemctl restart mysqld
步骤 2:创建同步专用账号
登录主库 MySQL,创建用于从库同步的账号并授权:
-- 创建账号(允许从库 IP 连接)
CREATE USER 'repl_user'@'192.168.1.101' IDENTIFIED BY 'StrongPassword123!';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.1.101';
-- 刷新权限
FLUSH PRIVILEGES;
步骤 3:备份主库数据并记录同步起点
为保证从库初始数据与主库一致,需先备份主库数据:
# 使用 mysqldump 备份全量数据,同时记录 binlog 位置
mysqldump -u root -p --all-databases --master-data=2 --single-transaction > master_backup.sql
参数说明:
--master-data=2
:在备份文件中记录备份完成时的 binlog 文件名和位置--single-transaction
:保证 InnoDB 表备份时的数据一致性,无需锁表
备份文件中会包含类似以下记录,标记同步起点:
-- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000005', MASTER_LOG_POS=154;
3. 从库配置
步骤 1:配置从库唯一标识
编辑从库配置文件:
[mysqld]
# 从库唯一 ID(必须与主库不同)
server-id = 2
# 配置中继日志路径(可选)
relay_log = /var/lib/mysql/relaylog
# 设置为只读(超级用户仍可写)
read_only = ON
重启从库:
systemctl restart mysqld
步骤 2:导入主库备份数据
将主库备份文件传输到从库,导入数据以保证初始一致性:
# 导入备份数据
mysql -u root -p < master_backup.sql
步骤 3:配置同步参数并启动同步
登录从库 MySQL,配置主库信息和同步起点:
-- 配置主从同步参数
CHANGE MASTER TOMASTER_HOST = '192.168.1.100', # 主库 IPMASTER_USER = 'repl_user', # 同步账号MASTER_PASSWORD = 'StrongPassword123!', # 同步密码MASTER_LOG_FILE = 'binlog.000005', # 主库备份时的 binlog 文件名MASTER_LOG_POS = 154; # 主库备份时的 binlog 位置-- 启动同步
START SLAVE;
步骤 4:验证同步状态
-- 查看同步状态
SHOW SLAVE STATUS\G
关键验证指标:
Slave_IO_Running
:Yes(IO 线程正常运行)Slave_SQL_Running
:Yes(SQL 线程正常运行)Seconds_Behind_Master
:0(无延迟,或数值较小)
若以上指标正常,说明主从同步已成功搭建。
三、主从同步进阶:GTID 复制
在 MySQL 5.6 及以上版本,推荐使用 GTID(全局事务标识符)复制,它通过唯一标识每个事务,简化了同步配置和故障恢复。
1. 启用 GTID
主库和从库配置文件中添加:
[mysqld]
gtid_mode = ON
enforce_gtid_consistency = ON
重启数据库后,每个事务会被分配一个唯一的 GTID。
2. GTID 模式配置同步
从库配置简化为:
CHANGE MASTER TOMASTER_HOST = '192.168.1.100',MASTER_USER = 'repl_user',MASTER_PASSWORD = 'StrongPassword123!',MASTER_AUTO_POSITION = 1; # 自动通过 GTID 定位同步起点START SLAVE;
GTID 模式的优势:
- 无需手动指定 binlog 文件名和位置,配置更简单
- 故障恢复时自动定位同步位置,减少人工干预
- 更易监控和管理分布式环境中的事务
四、常见问题与优化实践
1. 主从延迟问题
主从延迟是指从库数据落后于主库的时间,常见优化方法:
- 优化从库 SQL 线程性能:开启
slave_parallel_workers
支持并行复制 - 减少大事务:大事务会导致 binlog 传输和重放耗时增加
- 提升网络带宽:避免网络传输成为瓶颈
- 合理配置 binlog 格式:ROW 格式虽然一致性好,但日志体积大,可根据场景选择 MIXED 格式
2. 同步中断处理
若同步中断,可通过以下步骤恢复:
-- 停止同步
STOP SLAVE;-- 跳过错误(谨慎使用,仅适用于非关键错误)
SET GLOBAL sql_slave_skip_counter = 1;-- 重新启动同步
START SLAVE;
对于 GTID 模式,可通过重置同步位置恢复:
STOP SLAVE;
RESET SLAVE ALL; # 清除原有配置
CHANGE MASTER TO ... # 重新配置同步
START SLAVE;
3. 最佳实践
- 定期监控同步状态:使用
SHOW SLAVE STATUS
或第三方工具(如 Percona Monitoring) - 主库 binlog 保留时间应长于从库同步周期,避免日志被删除导致同步失败
- 从库建议配置为只读,防止误写入
- 生产环境推荐使用 GTID 复制,简化管理
- 重要业务建议部署双主或多从架构,提高可用性
五、总结
MySQL 主从同步通过"从库拉取 binlog-重放日志"的机制,实现了数据的异步复制,是构建高可用、高性能数据库架构的基础。