SQL主从复制通过将主库的变更日志同步到从库重放,实现数据冗余和读写分离,但运行中常出现同步延迟、复制中断等异常,影响业务可用性。
SQL主从复制基础原理
主从复制的核心流程分为三步:主库将事务变更写入binlog二进制日志,从库的IO线程拉取主库binlog并写入本地relay_log中继日志,从库的SQL线程读取relay_log并重放完成数据同步。
核心组件说明
- binlog:主库的事务记录日志,有STATEMENT、ROW、MIXED三种格式
- relay_log:从库存储拉取到的主库binlog的本地日志
- server_id:主从实例的唯一标识,冲突会导致复制失败
同步延迟的成因与排查
同步延迟指从库的数据更新落后于主库,通常可以通过show slave statusG命令查看Seconds_Behind_Master字段判断延迟秒数。
常见延迟原因
- 主库写入压力大,大量事务产生的
binlog超出从库拉取速度 - 从库硬件性能不足,SQL线程重放速度跟不上
relay_log写入速度 - 从库执行大事务,比如大批量删除、更新操作,阻塞后续同步
- 从库开启了查询耗时较长的业务,占用CPU、IO资源影响同步
- 网络带宽不足,主从之间的
binlog传输速度慢
延迟排查示例
首先查看从库同步状态:
-- 查看从库复制状态 show slave statusG -- 关注以下字段 -- Seconds_Behind_Master:延迟秒数,0表示无延迟 -- Slave_IO_Running:IO线程是否运行,YES为正常 -- Slave_SQL_Running:SQL线程是否运行,YES为正常
如果Seconds_Behind_Master持续升高,可进一步查看主库当前事务提交情况,以及从库的CPU、IO使用率,定位瓶颈点。
常见复制故障分析与处理
复制故障通常表现为Slave_IO_Running或Slave_SQL_Running状态为NO,需要结合错误日志定位问题。
典型故障场景
| 故障类型 | 错误表现 | 处理方案 |
|---|---|---|
| server_id冲突 | IO线程报错,提示server_id重复 | 修改从库server_id,重启从库实例后重新开启复制 |
| binlog格式不兼容 | SQL线程报错,提示无法解析binlog事件 | 统一主从binlog格式,或修改不兼容的事务逻辑 |
| 主从数据不一致 | SQL线程执行事件时提示主键冲突、记录不存在 | 使用数据校验工具修复不一致数据,跳过错误事务或重新搭建从库 |
| 网络中断 | IO线程断开连接,状态为NO | 恢复主从网络连通性,重启IO线程即可恢复同步 |
故障处理代码示例
如果是从库SQL线程执行报错,可先跳过错误事务:
-- 停止从库复制 stop slave; -- 跳过1个错误事务 set global sql_slave_skip_counter=1; -- 重新开启复制 start slave;
如果是从库数据不一致导致反复报错,可先导出主库全量数据,重新导入从库后重置复制:
-- 主库导出全量数据 mysqldump -u root -p --all-databases --master-data=2 > full_backup.sql -- 从库导入数据 mysql -u root -p < full_backup.sql -- 从库重置复制配置 reset slave all; -- 重新配置主从复制 change master to master_host='192.168.0.1',master_user='repl',master_password='repl_pass',master_log_file='binlog.000001',master_log_pos=154; -- 开启复制 start slave;
日常运维优化建议
为了减少主从复制异常的发生,日常运维中可做好以下工作:
- 从库硬件配置尽量与主库保持一致,避免性能瓶颈
- 控制主库大事务的执行,拆分成小批量操作
- 定期校验主从数据一致性,及时发现数据差异
- 监控
Seconds_Behind_Master指标,设置延迟告警阈值 - 避免从库承担过重的查询业务,优先将读请求路由到多个从库分散压力