🗄️ 第09章 · 主从复制简介

主从原理与配置

主从复制简介

这一章介绍 MySQL 主从复制(Master-Slave / Primary-Replica)最核心的原理和一套可用的配置流程。它的价值不只是"备份",而是读写分离、高可用、扩展读能力的基石。本机是单机 MySQL,但理解主从是运维进阶必备。

主从复制解决的问题

场景 价值
读写分离 写走主库,读走从库,分摊读压力
高可用 主库挂了,从库顶上(配合探活/切换)
容灾/备份 从库作为一份"几乎实时"的异地副本
数据分析 直接用从库跑重查询,不影响线上写

复制原理一句话

主库把所有变更写入 binlog(二进制日志);从库的 I/O 线程拉取 binlog 到自己的 relay log,再由 SQL 线程顺序回放,从而复现主库的每一个写操作。

主库: 写操作 → binlog
         │ (dump 线程推送)
从库: I/O线程 拉取 → relay log
         ↓
        SQL线程 顺序回放 → 数据一致

主库侧配置

/etc/mysql/mysql.conf.d/mysqld.cnf:

[mysqld]
server-id = 1            # 集群内唯一
log-bin = mysql-bin      # 开启 binlog
binlog_format = ROW      # 建议 ROW
-- 建一个专门用于复制的账号(允许从库 IP 连接)
CREATE USER 'repl'@'%' IDENTIFIED BY '强密码';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;

-- 锁定只读,记下从此刻开始的 binlog 位置(用于从库设定起点)
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;      -- 记录 File 和 Position
-- 然后做一次全量导出给从库,再 UNLOCK TABLES

注意 | server-id 每台机器必须不同;log-bin 必须开启,否则没有可供复制的 binlog。

从库侧配置与启动

从库 mysqld.cnf:

[mysqld]
server-id = 2
read_only = 1            # 从库一般只读,防误写

将主库全量备份导入从库后,设定开始复制的位点:

CHANGE MASTER TO
  MASTER_HOST='主库IP', MASTER_USER='repl', MASTER_PASSWORD='强密码',
  MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=NNN;   -- 用上面 SHOW MASTER STATUS 的值

START SLAVE;
-- 查看复制状态
SHOW SLAVE STATUS\G

看复制是否健康(SHOW SLAVE STATUS 关键字段)

字段 健康值 说明
Slave_IO_Running Yes I/O 线程在拉 binlog
Slave_SQL_Running Yes SQL 线程在回放
Seconds_Behind_Master 接近 0 从库落后主库多少秒(延迟)
Last_IO_Error 空 拉 binlog 报错(网络/账号/权限)
Last_SQL_Error 空 回放报错(如主键冲突)

常见坑 | 只要有一个 Running 是 No,或 Last_*_Error 非空,复制就停了。解决后用 START SLAVE 重新拉;若主键冲突,用 SET GLOBAL sql_slave_skip_counter = 1; START SLAVE; 跳过冲突(仅临时,需定位为什么冲突)。

高可用 / GTID 进阶

  • 较新版本推荐用 GTID(全局事务 ID)替代文件+位点定位,GITD 自动定位更简单:CHANGE MASTER TO ... MASTER_AUTO_POSITION=1;。
  • 故障切换:主库挂 → 从库执行 STOP SLAVE; RESET SLAVE ALL; 后升级为新的主库,再让其他从库指向它。有工具(如 MHA、Orchestrator)做自动切换。

一句话总结与延伸

主从复制成熟可靠,但它偏"异步":主库写入成功即返回,从库可能落后几毫秒到几秒。想要更强的数据一致性可以了解 半同步复制(semi-sync) 或 组复制(MGR / InnoDB Cluster),那是更高阶的高可用方案。

相关命令

  • 主库:SHOW MASTER STATUS;、SHOW BINARY LOGS;
  • 从库:SHOW SLAVE STATUS\G、START SLAVE、STOP SLAVE、CHANGE MASTER TO ...
  • 查看 binlog 内容:mysqlbinlog mysql-bin.000001