数据库备份这件事有个残酷的悖论:平时它毫无产出,关键时刻它是唯一救命的——所以它的质量不能靠”平时看起来在跑”来保证,只能靠恢复演练来证明。本篇拆一套真实在跑的 MySQL 物理备份一键化方案:CentOS 7 离线环境、XtraBackup 加压缩、七天全量加每日增量链、保留九十天,外加一个恢复演练脚本和一段”增量链四连自愈”的修复实录。
这个方案的脚本量不大(一个安装入口、一个备份脚本、一个恢复脚本),但注释里沉淀的四次修复记录,几乎覆盖了增量备份运维的全部经典坑。上一篇运维篇·上讲集群与监控,本篇讲数据的最后防线。
一、选型与形态:为什么是 XtraBackup 加压缩
选型三问三答。为什么物理备份不用 mysqldump? 量级:几十 GB 的库,逻辑备份导出导入是小时级,物理备份(直接拷数据文件加日志)是十分钟级,且物理备份恢复后无需重放索引——量大了逻辑备份的窗口根本不够。版本对应要先背:XtraBackup 2.4 系只支持 MySQL 5.7,8.0 要换 8.0 系工具——工具和数据库的大版本绑定是选型的第一约束。为什么加压缩? 备份产物要保留九十天,压缩比接近原文几分之一,磁盘成本直接除;压缩用配套的专用压缩工具在备份管道里流式完成——边备份边压缩,不落中间盘。
离线环境的一键安装也值得一提:十二个依赖 RPM(主工具、压缩工具、事件库、数据库客户端驱动……)全部本地化打包,一条命令本地安装加版本校验——离线运维的每个依赖都要有一条明确的落盘路线,和运维篇·上的镜像搬运路线是同一个纪律。
备份策略:每七天一个全量,其余每天增量(增量基于最新有效基准),保留九十天,夜间低峰执行。脚本参数集中在一个配置区——并行线程数、压缩线程数、备份目录、保留天数——改策略不改逻辑。
二、增量链的自愈:四次修复的实录
增量备份的原理决定了它的脆弱性:每个增量都以”上一次备份”为基准,链上任何一环损坏,其后所有增量作废。这套方案注释里记录的四次修复,正好是四类经典故障:
修复一:坏基准卡死整条链。 某次备份中途失败,留下一个没有 checkpoints 文件的半成品目录——而选基准的逻辑是”取最新目录”,于是之后每天的增量都挂在这个坏基准上,连续失败一整周才被发现。修复:选基准前校验 checkpoints 文件存在性,坏目录跳过并告警——基准的有效性校验是增量链的第一道闸。
修复二:失败提前退出吞噬了清理。 原逻辑备份失败直接退出,过期备份清理段在退出之后永不执行——失败堆积让磁盘雪上加霜。修复:失败路径收敛,保证清理和告警段必达。教训是脚本里的失败分支要把”必做的收尾”前置于退出——和业务代码里”事务回滚也要发通知”是同一条纪律。
修复三:孤儿增量。 全量被清理后,基于它的一串增量成了孤儿(没有基准可恢复)——清理逻辑按时间删全量,没检查增量链的完整性。修复:孤儿链式识别连带清理。**保留策略的单位是”链”不是”文件”**——删任何一段都要看它的下游。
修复四:在线 DDL 的脏页。 备份期间撞上在线 DDL,工具报”操作需要重试”直接失败。修复:识别该错误码自动等待重试(有限次数、足够间隔)。教训:备份窗口和业务变更窗口的重叠是常态,工具的已知可重试错误要有白名单。
四次修复的共同哲学:备份系统的健壮性不在正常路径,在它面对”上一轮失败”时的行为——这和任务篇的任务幂等、库存篇的自愈对账是同一个主题在备份域的变奏。
三、恢复演练:备份不算完,恢复才算数
这套方案最有价值的产出不是备份脚本,是恢复演练脚本。它支持三种模式:按日期恢复(自动找到对应全量加其后增量链)、恢复到指定增量点、以及只列出可恢复点做核对。流程是教科书级:解压 → 全量准备(应用日志但不回滚未完成事务,为增量留口)→ 逐个应用增量(每步同样只准备不回滚)→ 最后一步才完整回滚 → 拷回数据目录 → 修属主 → 启动实例。
两个工程细节决定了这个脚本”敢不敢在半夜被使用”。其一是防呆的分级交互:目标机 MySQL 还在运行要手动确认停止;清空数据目录要手动输入完整确认词——破坏性操作和普通操作用不同级别的确认,凌晨三点的操作者最容易犯的就是手滑。其二是参数化到”日期”粒度:恢复到昨天和恢复到上个月用的是同一个命令,不要求操作者理解增量链的构造——把链的复杂性留在脚本里。
演练的频率纪律:备份脚本上线当天必须跑一次完整恢复演练,此后定期(至少每季度)重跑——没经过恢复验证的备份,在事故现场的价值约等于零。九十天的保留期也一样:留得出 ninety 天,就要演练得出九十天前的链还能不能用。
四、防呆与通知:给半夜的操作者铺路
脚本外围还有三件小事,合起来是”凌晨三点的人机工程学”:
错配备份防呆:备份脚本校验配置里的主机地址必须是本机——背景是一次”本地跑脚本、配置却指向远端库”的错配,备份了半天备份的是别人的库。配置与执行环境的同一性校验,一行代码防一次大型事故。
成功失败都推送:钉钉机器人加签通知,备份成功推一条(含耗时大小)、失败推一条(含错误),推送失败不影响退出码——通知是旁路,不能反噬主流程(全景篇原则的运维版)。加签算法用 openssl 现算现拼,不引依赖。
资源与退出码纪律:打开文件数上限提前调高(备份线程加压缩管道的句柄开销不小);退出码统一语义化(成功/备份失败/校验失败各不同),供外部监控抓取——脚本的退出码就是它的 API。
五、面试视角:六个问题拆到底
Q1:物理备份和逻辑备份怎么选?
答:按量级和窗口选。几十 GB 以上、恢复时间敏感,物理备份(分钟级恢复、免重建索引);小库或要跨版本、跨引擎迁移,逻辑备份的可读性和灵活性才有价值。还要背版本对应:物理备份工具大版本和数据库大版本绑定,升级数据库先查备份工具兼容表。
Q2:增量备份的原理和风险?
答:原理是”基于上次备份的日志序列号位点,只拷位点之后变更的数据页”——所以它天然是链式依赖:链上任何一环坏,后续全作废。风险与对策全在链上:基准有效性校验、孤儿链识别、失败不推水位——我们用四次修复换来了”坏一环不影响发现、修一环不重跑全链”。
Q3:备份策略怎么定?
答:按恢复点目标(能丢多少)和恢复时间目标(能停多久)倒推。我们要的是”最多丢一天、恢复控制在小时级”:七天全量加日增量、压缩保留九十天、夜间低峰执行——策略是业务需求的翻译,不是技术偏好。
Q4:为什么强调恢复演练?
答:备份的质量定义是”能恢复”,而不是”在跑”。不演练的备份存在三类隐形失败:链断了没人知道、恢复流程本身有 bug、权限与目录在演进中变了。我们的纪律是上线当天演练一次、此后每季度重跑——演练脚本把恢复做成一条命令,就是为了让演练便宜到不会跳过。
Q5:备份脚本的健壮性怎么设计?
答:四件事:失败路径收敛(清理与告警必达);错误白名单重试(工具已知可重试错误自动等待);配置与执行环境的同一性校验;退出码语义化供监控抓取。哲学和任务系统一致——上一轮失败时的行为,决定这个系统可不可信。
Q6:备份通知有什么讲究?
答:成功失败都要推(成功不推等于让”备份停了”变成靠人发现);通知挂旁路(推送失败不改退出码);告警带上下文(耗时、大小、错误原文)。以及一个容易漏的:通知渠道自身要测试——加签算法、机器人地址变更,都可能让”最后一道防线”静默失联。
小结
- **备份的质量定义是”能恢复”**:上线当天演练、每季度重跑——没验证过的备份等于零;
- 增量链的单位是链不是文件:基准校验、孤儿识别、清理按链算,四次修复的共同主题;
- 失败分支要把必做的收尾前置于退出:清理和告警不能被提前退出吞噬;
- 物理备份的选型第一约束是版本对应:工具与数据库大版本绑定,升级先查兼容表;
- 破坏性操作分级确认:停服务确认一次、清数据目录要完整确认词——给凌晨三点的操作者留出犯错边际;
- 通知是旁路、退出码是 API:成功失败都推、推送不反噬主流程、退出码语义化供监控消费。
运维两篇至此补齐。全系列二十七篇——主线十一、交付六、端侧工具五、收官三、运维增补二——从面试场景出发,把一套制造业系统的每个层面都翻来覆去讲了透。祝面试顺利。