6.6.2 主从复制原理与配置

主从复制是 MySQL 高可用与读写分离的基础机制,通过将主库(Master)的变更持续复制到从库(Replica),实现数据冗余与扩展读能力。复制基于二进制日志(binlog)与中继日志(relay log),由主库生成变更事件,从库获取并回放以保持一致。

原理草图(主从复制数据流)

文章图片

工作原理与流程
1. 主库写入与记录:主库事务提交后将变更写入 binlog。
2. 从库 I/O 线程拉取:从库连接主库,持续读取 binlog 事件写入本地 relay log。
3. 从库 SQL 线程回放:从库读取 relay log 并执行,完成数据同步。
4. 位点控制:复制进度由主库 binlog 文件名+位置(或 GTID)标识,便于重启与故障恢复。

复制模式
- 异步复制:默认模式,主库提交不等待从库,性能高但存在丢数据风险。
- 半同步复制:主库等待至少一个从库确认收到 binlog 后提交,降低丢失风险(详见后续章节)。


安装与初始化(示例:基于通用二进制包/包管理)#

说明:以下示例以 Linux 为例,假设主从已安装 MySQL 8.x,并确保防火墙放行 3306 端口。

主库与从库安装(示例)

# RHEL/CentOS
yum install -y mysql-server

# 启动并设置开机自启
systemctl enable --now mysqld

# 初始化安全配置
mysql_secure_installation

验证服务与版本

mysql -uroot -p -e "SELECT VERSION();"

主从复制配置步骤(完整示例)#

1)主库配置与账号#

主库配置文件 /etc/my.cnf

[mysqld]
server_id=1
log_bin=/var/lib/mysql/mysql-bin
binlog_format=ROW
binlog_expire_logs_seconds=604800

重启服务并创建复制账号

systemctl restart mysqld

mysql -uroot -p <<'SQL'
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl_pass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
SQL

获取主库位点

mysql -uroot -p -e "SHOW MASTER STATUS\G"

预期输出示例(记录 File 与 Position):

File: mysql-bin.000001
Position: 157

2)从库配置与复制启动#

从库配置文件 /etc/my.cnf

[mysqld]
server_id=2
relay_log=/var/lib/mysql/relay-bin
read_only=ON

重启从库

systemctl restart mysqld

在从库设置主库信息并启动复制

-- 登录从库
mysql -uroot -p

-- 配置主库信息
CHANGE MASTER TO
  MASTER_HOST='主库IP',
  MASTER_USER='repl',
  MASTER_PASSWORD='repl_pass',
  MASTER_LOG_FILE='mysql-bin.000001',
  MASTER_LOG_POS=157;

-- 启动复制
START REPLICA; -- MySQL 8.0 推荐用 REPLICA

查看复制状态

SHOW REPLICA STATUS\G

重点字段解释:
- Replica_IO_Running=Yes:I/O 线程正常
- Replica_SQL_Running=Yes:SQL 线程正常
- Seconds_Behind_Master:复制延迟(秒)


数据初始化与一致性保障(示例)#

方案一:逻辑备份(mysqldump)

# 在主库执行逻辑备份并携带位点
mysqldump -uroot -p --single-transaction --master-data=2 \
  --databases appdb > /tmp/appdb.sql

# 将备份传输到从库
scp /tmp/appdb.sql root@从库IP:/tmp/

从库导入并按位点启动复制

mysql -uroot -p < /tmp/appdb.sql

-- 确认备份文件中注释的 MASTER_LOG_FILE 与 MASTER_LOG_POS
-- 重新执行 CHANGE MASTER TO 以保证位点一致

方案二:物理备份(XtraBackup)
- 适合数据量大、需要更快恢复的场景(详见备份章节)


常见问题与排错(含命令)#

问题1:复制中断,IO线程为 No

SHOW REPLICA STATUS\G

排查与修复:

# 1) 检查主库账号权限
mysql -uroot -p -e "SHOW GRANTS FOR 'repl'@'%';"

# 2) 测试网络连通
telnet 主库IP 3306

# 3) 查看从库错误日志
tail -n 50 /var/log/mysqld.log

问题2:SQL线程停止(如主键冲突)

SHOW REPLICA STATUS\G
-- 查找 Last_SQL_Error

修复示例(仅用于非关键数据或已确认安全场景):

STOP REPLICA;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START REPLICA;

问题3:延迟较大

SHOW REPLICA STATUS\G

排查建议:
- 检查从库资源(CPU/IO)
- 查看慢查询与大事务
- 优化 binlog_format=ROW 与业务事务粒度


关键命令速查与说明#

# 查看主库当前位点
mysql -uroot -p -e "SHOW MASTER STATUS\G"

# 查看从库复制状态
mysql -uroot -p -e "SHOW REPLICA STATUS\G"

# 启停复制
mysql -uroot -p -e "START REPLICA;"
mysql -uroot -p -e "STOP REPLICA;"

练习与实操#

  1. 练习1:搭建一主一从
    - 按步骤完成主从复制,验证 Replica_IO_RunningReplica_SQL_Running 均为 Yes。
  2. 练习2:验证延迟
    - 主库插入 100 万行数据,从库观察 Seconds_Behind_Master 变化。
  3. 练习3:故障模拟
    - 停止从库 SQL 线程,制造复制中断,定位 Last_SQL_Error 并恢复。

最佳实践#

  • 主从统一设置 binlog_format=ROW,降低不确定性。
  • 主从时间同步(NTP),便于日志审计。
  • 从库 read_only=ON 防止误写。
  • 使用独立复制账号,最小权限。
  • 定期检查复制健康与延迟,结合监控告警。