6.10.4 复制与高可用故障处理

在复制与高可用场景中,故障处理需围绕“快速止血、确保数据一致、恢复服务、复盘改进”的流程展开。常见形态包括主从复制、半同步复制、MGR/InnoDB Cluster、读写分离与自动故障切换组件。排查应先确认业务影响范围,再确定当前主从拓扑、复制状态与一致性风险。

一、原理与架构草图(含关键组件)

文章图片

二、快速诊断要点与示例
1. 主从状态核查

-- 从库查看复制状态(MySQL 8.0)
SHOW REPLICA STATUS\G
-- 关注字段:
-- Seconds_Behind_Source / Last_IO_Error / Last_SQL_Error / Retrieved_Gtid_Set / Executed_Gtid_Set
  1. 主库位点核对
-- 主库查看当前binlog位点
SHOW MASTER STATUS;
-- 记录 File/Position,用于与从库 Read_Master_Log_Pos 对比
  1. 命令解释与判断
    - Seconds_Behind_Source=0:从库追平主库
    - Last_IO_Error:多为网络/权限/账号问题
    - Last_SQL_Error:多为数据冲突/DDL冲突/GTID缺失

三、常见故障处理(含排错命令)
1. 复制中断(网络/权限/账号变更)

# 从库检查网络连通
ping -c 3 master_ip
nc -vz master_ip 3306

# 验证复制账号权限
mysql -h master_ip -u repl -p -e "SHOW GRANTS FOR 'repl'@'%';"

# 重启复制线程
mysql -e "START REPLICA;"

预期效果SHOW REPLICA STATUS\GReplica_IO_Running: YesReplica_SQL_Running: Yes

  1. SQL线程报错(重复键/缺失行/DDL冲突)
    - 非GTID场景临时跳过(谨慎)
STOP REPLICA;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START REPLICA;
  • GTID场景建议重建从库或数据修复后再接入
STOP REPLICA;
RESET REPLICA ALL;
-- 重新导入全量备份后再 CHANGE REPLICATION SOURCE TO
  1. 主库崩溃与快速切换
# 从库中选择Executed_Gtid_Set最大者作为新主(示例)
mysql -e "SHOW REPLICA STATUS\G" | egrep "Executed_Gtid_Set|Seconds_Behind_Source"

# 提升新主(在候选从库执行)
mysql -e "STOP REPLICA; RESET REPLICA ALL; SET GLOBAL read_only=OFF; SET GLOBAL super_read_only=OFF;"

预期效果:候选节点可写,其他从库指向新主。

  1. 半同步降级
-- 主库检查半同步状态
SHOW STATUS LIKE 'Rpl_semi_sync_master_status';
SHOW VARIABLES LIKE 'rpl_semi_sync%';

排错:检查从库延迟、网络RTT;必要时调整 rpl_semi_sync_master_timeout

  1. MGR/Group Replication故障
SELECT * FROM performance_schema.replication_group_members;
SELECT * FROM performance_schema.replication_group_member_stats;

排错:多数存活时剔除异常节点,少数存活时避免脑裂,按主控节点恢复集群。

四、数据一致性校验与修复(含安装与使用)
1. 安装 Percona Toolkit(示例:CentOS/RHEL)

sudo yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
sudo percona-release enable tools
sudo yum install -y percona-toolkit
  1. 一致性检查
# 在主库执行
pt-table-checksum --nocheck-replication-filters \
  --host=master_ip --user=admin --password='pwd' \
  --databases=prod_db --tables=orders

预期效果:从库 checksum 表出现差异记录。

  1. 差异修复
# 在从库执行修复
pt-table-sync --replicate=percona.checksums \
  --host=slave_ip --user=admin --password='pwd' \
  --databases=prod_db --tables=orders --execute

五、切换与回切操作范例(含配置与命令)
1. 切换前检查

-- 从库确认追平
SHOW REPLICA STATUS\G
-- 期待 Seconds_Behind_Source = 0
  1. 切换执行(示例步骤)
# 停写(业务侧或代理层)
# 代理层切到只读路由(示例:ProxySQL)
mysql -h proxysql_ip -u admin -p -e "UPDATE mysql_servers SET status='OFFLINE_SOFT' WHERE hostgroup_id=10; LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;"
-- 提升新主
STOP REPLICA;
RESET REPLICA ALL;
SET GLOBAL read_only=OFF;
SET GLOBAL super_read_only=OFF;
  1. 回切策略
# 旧主重建为从库(示例:CHANGE REPLICATION SOURCE TO)
mysql -e "CHANGE REPLICATION SOURCE TO SOURCE_HOST='new_master_ip', SOURCE_USER='repl', SOURCE_PASSWORD='pwd', SOURCE_AUTO_POSITION=1; START REPLICA;"

六、典型排错清单(可直接执行)

# 检查MySQL服务与端口
systemctl status mysqld
ss -lntp | grep 3306

# 检查磁盘与IO
df -h
iostat -x 1 3

# 检查延迟与线程状态
mysql -e "SHOW REPLICA STATUS\G" | egrep "Replica_IO_Running|Replica_SQL_Running|Seconds_Behind_Source"

七、练习与演练
1. 练习1:模拟复制中断并恢复
- 步骤:停止从库IO线程 → 观察告警 → 重新启动复制线程

STOP REPLICA IO_THREAD;
SHOW REPLICA STATUS\G;
START REPLICA;
  1. 练习2:模拟SQL冲突
    - 在从库手工插入重复主键数据,触发SQL线程报错 → 修复冲突数据 → 重新启动复制
-- 在从库
INSERT INTO prod_db.orders(id, user_id) VALUES(1, 100);
-- 观察错误后修复
DELETE FROM prod_db.orders WHERE id=1;
START REPLICA;
  1. 练习3:切换演练
    - 选取从库提升为新主 → 更新代理路由 → 回切旧主为从库
    - 记录用时与业务影响窗口,形成SOP

八、预防措施(含明确指标)
- 告警阈值:复制中断、延迟>30s、半同步降级、磁盘>80%
- 变更控制:DDL/大事务需审批窗口
- 月度演练:主从切换+回切+一致性校验,形成复盘报告