MySQL 主从复制搭建实战:原理、配置与监控全流程
数据库是大多数应用的核心,单点 MySQL 一旦宕机意味着全站不可用。主从复制是数据库高可用和读写分离的基础方案。本文从复制原理到实战配置,再到日常监控和常见问题处理,给出完整的落地指南。
一、主从复制原理
MySQL 主从复制基于 Binary Log(binlog) 实现,整个流程分三步:
主库(Master) 从库(Slave)
───────────── ──────────────
写操作 → 记录 binlog I/O Thread:连接主库,拉取 binlog
│ │
│──── binlog events ────────────→ Relay Log(中继日志)
│
SQL Thread:回放 relay log → 执行 SQL
- binlog:主库上所有数据变更的二进制日志,是复制的数据源
- relay log:从库暂存接收到的 binlog,由 SQL Thread 按顺序回放
- 复制延迟:SQL Thread 单线程回放是传统复制的最大瓶颈(MySQL 5.7+ 可开启并行复制)
二、主库配置
# /etc/mysql/mysql.conf.d/mysqld.cnf(Ubuntu)或 /etc/my.cnf(CentOS) [mysqld] server-id = 1 # 主库 server-id,必须全局唯一 log_bin = /var/log/mysql/mysql-bin.log # 开启 binlog binlog_format = ROW # 推荐 ROW 格式:记录实际数据变更,避免函数不一致 expire_logs_days = 7 # binlog 保留7天自动清理 max_binlog_size = 100M # 单文件超过100M自动滚动 # 可选:指定复制的数据库范围 # binlog_do_db = mydb # 只复制 mydb # binlog_ignore_db = test # 忽略 test 库
# 重启 MySQL 后创建复制专用账号 mysql -u root -p CREATE USER 'repl'@'192.168.1.%' IDENTIFIED BY 'StrongPass@2026'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%'; FLUSH PRIVILEGES; # 查看主库状态(记录 File 和 Position,下一步要用) SHOW MASTER STATUS\G # File: mysql-bin.000003 # Position: 154
三、从库配置
# 从库 my.cnf [mysqld] server-id = 2 # 从库 ID 必须与主库不同 relay_log = /var/log/mysql/mysql-relay-bin.log read_only = ON # 从库只读,防止误写入 log_slave_updates = ON # 从库也记录 binlog(级联复制时需要)
# 配置复制关系 mysql -u root -p CHANGE MASTER TO MASTER_HOST='192.168.1.10', MASTER_USER='repl', MASTER_PASSWORD='StrongPass@2026', MASTER_LOG_FILE='mysql-bin.000003', # 主库 SHOW MASTER STATUS 的值 MASTER_LOG_POS=154; # 对应 Position START SLAVE; SHOW SLAVE STATUS\G # 验证复制状态
四、验证复制状态
执行 SHOW SLAVE STATUS\G 后,重点关注以下字段:
| 字段 | 期望值 | 含义 |
|---|---|---|
| Slave_IO_Running | Yes | IO Thread 正常,已连接主库 |
| Slave_SQL_Running | Yes | SQL Thread 正常,正在回放日志 |
| Seconds_Behind_Master | 0 或接近 0 | 复制延迟(秒),越小越好 |
| Last_Error | 空字符串 | 最近的错误信息 |
五、GTID 模式(推荐,MySQL 5.6+)
GTID(全局事务标识符)让每个事务都有唯一 ID,复制时无需手动记录 File 和 Position:
# 主库和从库都需要配置 gtid_mode = ON enforce_gtid_consistency = ON # 从库配置复制(无需指定 File 和 Position) CHANGE MASTER TO MASTER_HOST='192.168.1.10', MASTER_USER='repl', MASTER_PASSWORD='StrongPass@2026', MASTER_AUTO_POSITION=1; # 自动同步位点
六、并行复制优化(解决延迟问题)
# MySQL 5.7+ 从库 my.cnf slave_parallel_type = LOGICAL_CLOCK # 并发策略(推荐) slave_parallel_workers = 4 # 并行线程数,一般设为 CPU 核心数 slave_preserve_commit_order = ON # 保证提交顺序与主库一致
七、常见故障处理
从库复制中断(SQL Thread 报错)
# 查看错误 SHOW SLAVE STATUS\G # 查看 Last_SQL_Error # 方法1:跳过一个错误事务(谨慎使用,可能导致数据不一致) STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE; # 方法2:GTID 模式下跳过 SET GTID_NEXT='主库GTID:事务号'; BEGIN; COMMIT; # 提交空事务 SET GTID_NEXT='AUTOMATIC'; START SLAVE;
从库延迟过大
- 检查 SQL Thread 是否单线程,开启并行复制
- 检查从库磁盘 IO,改用 SSD 或调整 innodb_flush_log_at_trx_commit
- 主库大批量写入(如 ETL)是延迟高的常见原因,错开时间窗口执行
八、监控脚本示例
#!/bin/bash
# check_slave.sh - 监控复制延迟
DELAY=$(mysql -u monitor -p'xxx' -e "SHOW SLAVE STATUS\G" | grep "Seconds_Behind_Master" | awk '{print $2}')
if [ "$DELAY" = "NULL" ] || [ "$DELAY" -gt 60 ]; then
echo "ALERT: Slave delay=${DELAY}s" | mail -s "MySQL 复制延迟告警" admin@example.com
fi
总结
MySQL 主从复制是中小网站数据库高可用的入门方案。搭建时推荐使用 GTID 模式,开启并行复制降低延迟,为从库设置 read_only 防止误操作。定期检查复制状态、监控延迟,是维持复制健康的关键习惯。
