人人都会AI编程

19.3 主从搭建、状态监控、常见故障处理

更新时间:2026-07-10

主从复制是 MySQL 高可用和读写分离的基础设施。搭建过程本身并不复杂,但细节决定稳定性。本节提供一个可操作的搭建流程、核心监控指标和常见故障的排查思路。

19.3.1 主从搭建(基于 GTID)

从 MySQL 5.6 开始,推荐使用 GTID(全局事务标识符)复制模式,它比传统基于日志位置的方式更可靠,故障切换时无需人工计算偏移量。以下步骤假设主库和从库均为 MySQL 8.0,操作系统为 Linux。

1. 主库配置

编辑主库的配置文件 /etc/my.cnf,在 [mysqld] 段增加:

server-id = 1                           # 唯一ID,主库通常为1
log_bin = /data/mysql/binlog/mysql-bin   # 开启二进制日志
binlog_format = row                      # 推荐ROW格式
gtid_mode = on                           # 开启GTID
enforce_gtid_consistency = on            # 强制GTID一致性
expire_logs_days = 7                     # 日志保留天数,按需调整

重启主库使配置生效,然后登录 MySQL 创建复制专用账号:

CREATE USER 'repl'@'192.168.1.%' IDENTIFIED BY 'StrongPassword!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%';
FLUSH PRIVILEGES;

2. 从库配置

编辑从库配置文件,添加:

server-id = 2                           # 必须与主库不同
gtid_mode = on
enforce_gtid_consistency = on
log_bin = /data/mysql/binlog/mysql-bin   # 从库也建议开启,便于级联或切换
read_only = on                           # 从库通常设为只读

重启从库。

3. 初始化数据并建立复制

如果主库已有业务数据,需要先做一次全量备份并恢复到从库。生产环境推荐使用 xtrabackup 进行物理备份,避免锁表。简单场景下也可用 mysqldump

# 在主库执行
mysqldump --single-transaction --master-data=2 --triggers --routines --databases your_db > dump.sql

dump.sql 传输到从库并导入。导入后,在从库上执行 CHANGE MASTER TO 语句:

CHANGE MASTER TO
    MASTER_HOST='192.168.1.10',
    MASTER_PORT=3306,
    MASTER_USER='repl',
    MASTER_PASSWORD='StrongPassword!',
    MASTER_AUTO_POSITION=1;               -- 基于GTID自动寻点

START SLAVE;

如果主库是全新空库,可以直接在从库执行上述 CHANGE MASTER TO 并启动复制,无需备份步骤。

4. 验证复制状态

在从库执行 SHOW SLAVE STATUS\G,重点关注这两个字段:

  • Slave_IO_RunningSlave_SQL_Running 均为 Yes,表示复制线程正常。
  • Seconds_Behind_Master 为 0 或很小,表示延迟可控。

同时可以用以下命令检查 GTID 一致性:

-- 主库
SELECT @@global.gtid_executed;
-- 从库
SELECT @@global.gtid_executed;

正常情况下从库的 gtid_executed 应该是主库的子集,且 Retrieved_Gtid_SetExecuted_Gtid_Set 应保持一致。

19.3.2 状态监控

复制搭建好之后,持续监控是预防故障的关键。以下几个指标需要重点关注。

1. 复制线程状态

定期检查 Slave_IO_RunningSlave_SQL_Running 是否都为 Yes。一个较实用的状态检查命令:

SELECT 
    SERVICE_STATE AS io_thread,
    (SELECT SERVICE_STATE FROM performance_schema.replication_applier_status) AS sql_thread
FROM performance_schema.replication_connection_status;

也可以用 MySQL 内置的 sys 库视图:

SELECT * FROM sys.replication_status;

该视图会提示复制是否正常、有无错误、延迟秒数等。

2. 复制延迟

延迟可以用 Seconds_Behind_Master 中大致取数,但注意这个值在某些场景下不准确(例如网络闪断重连后可能为 0)。更精确的方法是借助心跳表或对比主从库的 GTID 集合差异。

一个简化的延迟监控思路:在主库定期写时间戳到某张表,然后在从库查询该时间戳并与当前时间比较。这可以集成到监控脚本里,比如每 5 秒写入,从库读到的时间如果超过阈值就告警。

3. 日志传输与应用状态

performance_schema 提供了更细粒度的复制监控表:

-- 查看IO线程接收到的日志量
SELECT * FROM performance_schema.replication_connection_status\G
-- 查看SQL线程应用日志的进度
SELECT * FROM performance_schema.replication_applier_status_by_worker\G

这些信息对排查“大事务导致延迟”或“SQL线程卡在某个事务上”很有帮助。

4. 主库 Binlog 保留与磁盘

监控主库的磁盘使用率,Binlog 如果未及时清理会导致磁盘爆满。可以通过 SHOW BINARY LOGS; 查看日志列表和大小,结合监控报警。

19.3.3 常见故障与处理

故障一:IO 线程连接失败

现象:Slave_IO_RunningConnectingLast_IO_Error 提示连接被拒绝或超时。

常见原因:

  • 主库 IP、端口或账号密码错误。
  • 主库防火墙未放行 3306 端口,或 bind-address 未正确设置。
  • 复制账号的密码策略导致连接失败(如 caching_sha2_password 要求加密连接)。

处理:

  • 检查网络连通性:从从库 telnet 主库IP 3306
  • 确认账号权限:在主库执行 SHOW GRANTS FOR 'repl'@'从库IP';
  • 如果使用了 caching_sha2_password,可以考虑在从库连接时获取公钥:MASTER_PUBLIC_KEY_PATH 或先在从库用 mysql --get-server-public-key 方式连接一次。

故障二:SQL 线程中断,主键冲突或更新找不到行

现象:Slave_SQL_RunningNo,错误信息包含 Duplicate entryCan't find record

原因:可能是在从库上错误写入了数据,或者主从数据不一致。这在 STATEMENTMIXED 格式下容易出现,ROW 格式相对安全。

处理:

  • 如果是重复键错误,可以跳过冲突的事务(谨慎使用):
  SET GTID_NEXT='冲突事务的GTID';
  BEGIN;
  COMMIT;
  SET GTID_NEXT='AUTOMATIC';
  START SLAVE;
  

这相当于注入一个空事务来消耗掉该 GTID,然后继续复制。

  • 更彻底的方法是使用 pt-table-checksumpt-table-sync(Percona Toolkit)修复不一致的数据,然后重启复制。

故障三:延迟持续增大

现象:Seconds_Behind_Master 不断增高,且无明显回落。

常见原因:

  • 主库有大事务或 DDL 操作,比如一次 DELETE 上百万行数据或者 ALTER TABLE
  • 从库硬件性能不足(CPU、IO 瓶颈)。
  • 从库同时承担了大量读请求,SQL 线程被阻塞。

处理:

  • 确认延迟原因:在从库执行 SHOW PROCESSLIST 查看当前 SQL 线程正在执行的语句,是否为长时间运行的 DML 或 DDL。
  • 大事务优化:业务侧拆分大事务为小批量提交,比如每次 DELETE 1000 行,循环提交。
  • 并行复制:MySQL 8.0 支持基于 WRITESET 的逻辑时钟并行复制,可以在从库设置:
  slave_parallel_type = LOGICAL_CLOCK
  slave_parallel_workers = 4       # 根据CPU核心数调整
  

这可以大幅度提升从库回放日志的速度,但需要主库 binlog_transaction_dependency_tracking = WRITESET(8.0 默认)。

  • 若从库读压力大,适当增加只读副本数量,用中间件分散流量。

故障四:主库突然宕机,从库无法自动提升

这是复制架构中最严重的故障,需要人工介入或借助高可用工具(MHA、Orchestrator)。纯复制模式下,紧急恢复思路:

  1. 检查哪个从库的数据最新(通过 GTID 或 Binlog 的 pos 对比),选为新的主库。
  2. 将其他从库指向新主库:
   STOP SLAVE;
   CHANGE MASTER TO MASTER_HOST='新主库IP', MASTER_AUTO_POSITION=1;
   START SLAVE;
   
  1. 业务层将写入指向新主库。
  2. 修复旧主库后作为从库重新加入,或丢弃。

建议在生产环境搭配至少一套半自动切换方案(如 MHA),避免纯人肉操作的高风险和时间窗口。

故障五:磁盘空间不足导致复制中断

主库磁盘满可能导致 Binlog 无法写入,导致所有写操作卡死;从库磁盘满会导致 relay log 无法写入或应用。这类问题在业务增长期容易发生。

处理:

  • 实时监控磁盘使用率,设置报警阈值 80%。
  • 紧急处理:先清理日志,主库执行 PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY); 释放空间。
  • 设置 binlog_expire_logs_seconds(8.0 已废弃 expire_logs_days)为较短时间,配合足够的备份策略。
  • 从库及时删除 relay log:配置 relay_log_purge = on(默认),避免积压。

总之,主从复制的基本运维并不复杂,但要想在生产环境长期稳定运行,必须在配置、监控和应急方案三个层面做足功课。工具链(如 Orchestrator、ProxySQL)能大大简化管理工作,但理解底层原理和手工处理故障的能力永远是最后一道防线。