19.9.3 备份一致性与应用停机窗口管理
备份一致性与应用停机窗口管理的目标是:在可控的业务影响下获得可恢复且一致的备份点。实践中需明确一致性级别(强一致/最终一致/会话一致)与“数据面依赖顺序”(数据库→缓存→消息队列→配置中心→对象存储),并记录时间点与位点,避免跨组件时间点不一致。
一致性实现分为应用层与存储层:
- 应用层:只读模式、停写、冻结事务、流量切换(写流量切走)。
- 存储层:文件系统/存储阵列快照、数据库原生备份机制。
示例:MySQL 一致性备份(XtraBackup)
1) 安装与准备(Debian/Ubuntu):
# 安装 Percona XtraBackup(示例)
sudo apt-get update
sudo apt-get install -y percona-xtrabackup-80
# 确认版本
xtrabackup --version
2) 建立短只读窗口并记录位点:
# 进入 MySQL
mysql -uroot -p -e "SHOW MASTER STATUS\G"
# 推荐使用备份锁(MySQL 8.0)
mysql -uroot -p -e "LOCK INSTANCE FOR BACKUP;"
# 说明:锁住DDL/备份相关操作,不阻塞读取
3) 执行热备并记录位点:
# 备份目录
sudo mkdir -p /data/backup/mysql/full_$(date +%F)
# 执行备份
sudo xtrabackup --backup \
--target-dir=/data/backup/mysql/full_$(date +%F) \
--user=backup --password='***'
# 释放备份锁
mysql -uroot -p -e "UNLOCK INSTANCE;"
# 查看备份元数据(含 binlog 位点)
cat /data/backup/mysql/full_$(date +%F)/xtrabackup_binlog_info
预期效果:xtrabackup_binlog_info 输出 binlog.000xxx 1234567,表示一致性位点。
4) 备份校验与抽样恢复:
# 生成校验和
cd /data/backup/mysql/full_$(date +%F)
find . -type f -print0 | xargs -0 sha256sum > SHA256SUMS
# 抽样恢复到测试实例
sudo systemctl stop mysql
sudo rm -rf /var/lib/mysql/*
sudo xtrabackup --prepare --target-dir=/data/backup/mysql/full_$(date +%F)
sudo xtrabackup --copy-back --target-dir=/data/backup/mysql/full_$(date +%F)
sudo chown -R mysql:mysql /var/lib/mysql
sudo systemctl start mysql
示例:Redis 一致性点(RDB/AOF)
# 进入只读窗口(应用层切写)
# 触发 RDB 快照
redis-cli BGSAVE
# 查看状态
redis-cli info persistence | egrep "rdb_bgsave_in_progress|rdb_last_save_time"
# 如使用 AOF,强制重写减小体积
redis-cli BGREWRITEAOF
# 备份文件
cp /var/lib/redis/dump.rdb /data/backup/redis/dump_$(date +%F).rdb
cp /var/lib/redis/appendonly.aof /data/backup/redis/aof_$(date +%F).aof
预期效果:rdb_bgsave_in_progress:0 且 rdb_last_save_time 更新。
示例:Kafka 一致性点(停写+offset记录)
# 暂停生产者(应用层停写/流控)
# 记录 consumer group 的 offset
kafka-consumer-groups.sh --bootstrap-server kafka01:9092 \
--describe --group order-service \
> /data/backup/kafka/order-service.offsets.$(date +%F)
# 备份日志目录(示例,需保证停写)
rsync -a /var/lib/kafka/logs/ /data/backup/kafka/logs_$(date +%F)/
预期效果:offset 记录文件可用于恢复点对齐。
停机窗口管理流程示例(脚本化)
#!/usr/bin/env bash
# /usr/local/bin/backup_window.sh
# 1) 写流量切走 2) 应用只读 3) 执行备份 4) 恢复写入
set -e
echo "[1/4] 切写流量到只读节点"
# 示例:标记上游为只读(具体依赖 LB/服务治理)
curl -X POST http://gateway/api/traffic/switch?mode=read-only
echo "[2/4] 应用进入维护模式"
curl -X POST http://app/api/maintenance/enable
echo "[3/4] 触发数据库备份"
xtrabackup --backup --target-dir=/data/backup/mysql/full_$(date +%F)
echo "[4/4] 恢复应用写入"
curl -X POST http://app/api/maintenance/disable
curl -X POST http://gateway/api/traffic/switch?mode=read-write
echo "done."
预期效果:窗口内写流量被限制,备份完成后恢复读写。
常见排错清单
- 备份阻塞或耗时过长
- 排查:SHOW PROCESSLIST; 查找长事务
- 处理:协调业务缩短事务或提前“只读窗口”
- MySQL 备份失败:xtrabackup: Error: log scan aborted
- 可能原因:磁盘空间不足或权限不足
- 处理:df -h 检查空间;确保备份目录可写
- Redis BGSAVE 失败:MISCONF
- 可能原因:磁盘写入失败或 stop-writes-on-bgsave-error
- 处理:修复磁盘后 CONFIG SET stop-writes-on-bgsave-error no
练习
1) 在测试库中执行一次 MySQL 热备并记录 binlog 位点,随后在新实例恢复并验证数据一致性。
2) 模拟 Kafka 生产者停写 5 分钟,记录 offset 并备份日志目录,验证恢复后消费一致。
3) 编写并运行 backup_window.sh,完成“切写→维护→备份→恢复”的全流程演练,并记录窗口耗时与成功率。