6.10.7 应急处置与恢复演练
应急处置与恢复演练的目标是缩短故障恢复时间、降低业务影响并形成可复用的操作手册。应急流程需做到“先止血、再复盘、后优化”,以保障数据一致性与业务连续性为核心。
应急处置流程(原理草图)
应急处置流程(示例命令与解释)
1. 快速分级与通报
- 根据P0-P3级别触发升级;记录时间线与联系人。
2. 现场保护与变更冻结
- 采集关键状态(避免重启/清理导致证据丢失):
# 基本健康状态
mysql -e "SHOW GLOBAL STATUS LIKE 'Uptime';"
mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_running';"
mysql -e "SHOW ENGINE INNODB STATUS\G" > /tmp/innodb_status.txt
# 复制状态(主从)
mysql -e "SHOW SLAVE STATUS\G" > /tmp/slave_status.txt
# 慢查询与错误日志定位
tail -n 200 /var/log/mysql/slow.log > /tmp/slow.log.sample
tail -n 200 /var/log/mysql/error.log > /tmp/error.log.sample
- 解释:
SHOW ENGINE INNODB STATUS用于锁等待/死锁信息;SHOW SLAVE STATUS用于复制延迟与错误。
- 止血与隔离
- 终止长事务、限制异常连接:
# 查找运行时间超过60秒的会话
mysql -e "SELECT ID,USER,HOST,DB,TIME,INFO FROM information_schema.processlist WHERE COMMAND!='Sleep' AND TIME>60\G"
# 终止某个阻塞会话
mysql -e "KILL 12345;"
- 解释:
TIME>60筛选长耗时;KILL终止阻塞事务,优先终止影响最小的会话。
- 恢复与验证
- 切主/回滚/恢复/重放,根据预案执行,完成一致性验证。
典型故障应急策略与排错示例
- 主库不可用:快速切换
# 通过MHA/Orchestrator或脚本切换,这里演示手工确认步骤
mysql -h new_master -e "SHOW MASTER STATUS\G"
mysql -h new_master -e "SHOW SLAVE HOSTS;"
# 应用侧切换(示例)
sed -i 's/old_master/new_master/g' /etc/app/db.conf
systemctl restart app
- 解释:确认新主库已可写并包含最新GTID;应用连接更新后重启服务。
- 误删数据:PITR时间点恢复
# 1) 全量恢复到临时实例
xtrabackup --prepare --target-dir=/backup/full_2024-01-10/
xtrabackup --copy-back --target-dir=/backup/full_2024-01-10/
chown -R mysql:mysql /var/lib/mysql
# 2) 从binlog回放到误删前一分钟
mysqlbinlog --start-datetime="2024-01-10 10:00:00" \
--stop-datetime="2024-01-10 10:29:00" \
/var/log/mysql/binlog.000123 | mysql -u root -p
- 解释:
mysqlbinlog可将binlog回放到指定时间;先全量恢复,再回放增量。
- 复制中断或延迟飙升
# 查看错误与延迟
mysql -e "SHOW SLAVE STATUS\G" | egrep "Seconds_Behind|Last_Error|Relay_Master_Log_File"
# 跳过单条错误事务(谨慎)
mysql -e "STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE;"
- 解释:只在确认错误可忽略时使用跳过策略;否则需重建从库。
- 锁等待与死锁
# 查询等待的锁
mysql -e "SELECT * FROM information_schema.innodb_lock_waits\G"
# 查看阻塞事务
mysql -e "SHOW ENGINE INNODB STATUS\G" | sed -n '/LATEST DETECTED DEADLOCK/,+20p'
- 解释:定位阻塞事务后,按影响最小原则KILL会话。
- 磁盘空间耗尽
# 检查空间
df -h /var/lib/mysql
# 清理旧binlog(确保备份与复制安全)
mysql -e "PURGE BINARY LOGS TO 'binlog.000120';"
- 解释:
PURGE BINARY LOGS会删除binlog,需确认从库已追上且备份可用。
恢复演练设计(含脚本样例)
- 演练场景:主从切换、PITR恢复、误删恢复、跨机房故障、监控失效。
- 指标:RTO、RPO、成功率、告警触达率、自动化覆盖率。
#!/bin/bash
# /opt/drill/pitr_drill.sh
# 模拟误删并按时间点恢复(仅演练环境)
mysql -e "CREATE DATABASE IF NOT EXISTS drill; USE drill; CREATE TABLE t(id INT PRIMARY KEY, v VARCHAR(20)); INSERT INTO t VALUES (1,'ok');"
echo "记录时间点:$(date '+%F %T')" | tee /opt/drill/pitr_time.txt
mysql -e "DELETE FROM drill.t WHERE id=1;"
# 回放恢复(假设binlog可用)
START_TIME=$(cat /opt/drill/pitr_time.txt | awk '{print $2" "$3}')
mysqlbinlog --start-datetime="$START_TIME" /var/log/mysql/binlog.000123 | mysql
- 解释:脚本记录时间点后删除数据,再用binlog回放恢复。
恢复验证清单(示例命令)
# 一致性校验(示例对单表)
pt-table-checksum --user=root --password=xxx --databases=drill --tables=t
# 复制状态
mysql -e "SHOW SLAVE STATUS\G" | egrep "Seconds_Behind|Last_Error"
# 业务健康检查(示例)
curl -s http://app-health.local/health | jq .
演练与排错练习
1. 在测试环境构建主从,模拟主库宕机,完成切换并记录RTO。
2. 模拟误删表数据,使用xtrabackup + mysqlbinlog恢复到指定时间点。
3. 制造锁等待(大事务+更新),练习定位阻塞并终止会话。
4. 触发磁盘满(填充文件),验证告警与PURGE BINARY LOGS策略。
通过规范化的应急流程、可执行的命令脚本与周期性演练,能够显著提升MySQL故障恢复能力与业务连续性。