一排按顺序排列的备份目录,其中一格与后一格之间的编号不衔接,被巡检表标成红色待处理项

一、链式备份靠三个数说话,少一个都不可信

链式备份的组织方式并不神秘:每个备份目录里会留下一个检查点文件,记录这一份的备份类型与起止位点;增量份要指向上一次成功备份的目录作为基线;工具在做增量之前会做一件事——把父份的结束位点和自己记录的起始位点拿出来比对,不相等就报错退出。这里的位点,本质上是数据库日志序列中的一个位置标记,各家的字段名不同,含义是一样的:它是一个数,不是一个文件时间。

由此得到父子判据的三条:类型、起止位点、基线指向。三者缺任一条,这份备份就不可信,即使它的作业状态写着成功。

这句话要展开成一个容易被忽略的区分:作业状态和链状态是两件事。作业状态描述”这次任务有没有跑完”,链状态描述”这份能不能被接进恢复路径”。监控只看前者,就会出现一片绿灯而实际不可恢复的库。我们在值守里坚持把它拆成两个字段,原因就在这里。

排查手段也直接来自这个结构:逐级读出各个目录里检查点记录的位点值,把它们抄成一张表做比对。位点对不上的那一格,就是断点。命令只是取数的手段,重点是抄出来的这张表要在断的时候还能查到。

二、没做完的那一份是怎么污染链条的

典型的成因不是备份工具算错了位点,而是”上一次没做完的那份被当成了新基线”。三条路径都会走到这个结果。

第一条,基线选取规则写成了”取目录里时间戳靠后的那一份”。作业失败时,目录可能已经创建、检查点文件可能已经写出但不完整,甚至写出了一个只包含起始位点的半份。下一次增量按”时间靠后”去取基线,就取到了一个不该被当父份的目录,校验必然不过。

第二条,清理策略按目录时间删除,以”份”为单位而不是以”链”为单位。删掉中间任何一份,它后面所有派生的增量都失去父份;剩下的一份虽然自身完好,但已经无法从基线走到它。这种断链在备份目录里完全看不出来,只有恢复时才暴露。

第三条,写入被打断或环境变了。磁盘余量不足导致检查点没写全;目录权限或属主变更导致后续作业能读不能写;备份窗口与大量写入或其它作业冲突,位点在两份之间跳了一段。第三种最难查,因为现象是间歇性的。

还有一条容易被归错的原因:目标实例做过调整(换版本、改参数、迁路径、动过插件),而链台账里没记录配置版本。这份库的旧链在新配置上的可用性是未验证的,不能假定能接着用。

三、排查四步,顺序不要换

发现校验不过或需要确认链是否连续时,按下面四步走,目标是把”断在哪一格”说清楚,而不是立刻重做全量。

  1. 逐级回读位点。从链上靠后的那份开始,按基线指向逐个回退,把每目录的类型、起始位点、结束位点、声称的父目录抄进一张表。抄到某一步发现父目录不存在或位点对不上,断点就在这一格。
  2. 核对基线指向的正确性。光看”父目录存在”不够,要确认被指向的那一份自身状态是成功且校验通过的,且它的链根与当前份一致。指向了一份失败的目录,是脚本按时间挑选的典型后果。
  3. 比对作业日志、磁盘与权限。确认失败发生在写出之前还是之后——之前意味着目录是空的或残留,之后意味着内容可用但状态字段没落。这两类处置完全不同,前者只能剔除,后者可以补齐状态后复用。
  4. 确认是否有并发写入或其它作业打断。核对同时间窗内的作业记录、日志切换、空间告警与权限变更。间歇性断链多半来自这一条,而不是配置错。

四步做完,应当能回答三个问题:断在哪一格、为什么断、断的那一段有没有可用替代。回答不了第三个问题就不要动手清理。

四、核心交付物:链台账、校验方法与失败处置

链台账是把上面所有事情固定下来的唯一办法。它不是备份目录列表,而是一张每份都有父指、并且能被查询的表。

字段 含义 校验方法 校验不过时的处置
备份标识与目录 这一份的唯一编号与存放路径 目录是否存在、内容是否非空 剔除出可用链并标记为不可选作基线
类型 全量、增量、日志备份三类之一 与链根的规则比对:增量必须有全量根 类型与父份规则冲突,直接判不可用
起始位点与结束位点 覆盖的日志区间两端 与父份结束位点做等值比对 不等即断链,记录断点区间,触发重建
父份指向 本份声明的基线目录 父份存在、状态成功、链根一致 改指向链上靠前且校验通过的那一份,或重做本份
链根与链序号 从哪一次全量派生、在链中第几环 从当前份回溯到根,环数是否连续 有空洞则本链只能用于恢复到空洞之前
作业状态 任务是否跑完 作业日志与退出码 单独一列,不参与可用性判定
链状态 校验通过与否 上面三项的综合判定结果 不可用时告警,按重建流程处理
目标实例与配置版本 属于哪个库、当时实例的配置版本 与恢复环境做一致性比对 不一致时该链只允许在同配置环境演练
大小与耗时 用于趋势与异常发现 与历史同类型偏离度 偏离过大先查完整性再决定是否可用
末次演练结论与时间戳 这条链最后一次被真实恢复验证的结果 由演练作业回写 超期未演练按不可用对待
负责人 出问题找谁 值守排班表核对 无人认领的链不进交付清单

校验的触发时机有三处:作业结束时做一次(自身完整性)、下一次增量开始前做一次(父子衔接)、演练时做一次(端到端可用性)。三次缺一不可,因为前两次只看数,只有第三次能证明这些数合起来真的能起来一个可用的库。

五、恢复侧的验证:作业成功但不可恢复的三种典型

恢复链路的顺序是先按链把各份合并应用,再做一致性与就绪处理,最后才是能否启动对外服务。校验通过只保证第一段能跑,不保证后两段没问题。三种”备份全都成功但库起不来”的情形各有原因。

第一种,缺中间份。表现为合并到某一步没有可应用的日志区间,只能恢复到空洞之前的时点。这类问题在清理策略改动之后出现,且往往在真正需要恢复时才发现,因此清理规则必须与链台账联动:删除前先确认没有后继份指向它。

第二种,只备了数据目录,没备事务日志。结果是位点无法衔接,数据文件与日志位置不匹配,即使文件都在也只能得到一个不一致的快照。判断方法很简单:检查点里的起止位点区间是否被日志备份覆盖。这一条要在台账里显式列一栏,不要靠人记。

第三种,目标实例配置与源不一致。路径、参数、排序规则、插件或字符集的差异,会让恢复过程报错或者起来之后行为不对。这一类不是备份问题,但一定会被先当成备份问题来处理,因此演练必须固定在与生产等价的环境上做,并且把配置版本记进台账。

按时间点恢复还多一层要求:日志备份的位点与数据份的位点要能衔接上目标时点。链连续但日志断档,同样做不到任意时点。这一项只能在演练里验,不能靠推理。

六、治理动作与交付时的备份矩阵

真正能把这件事从”运气”变成”能力”的动作只有几条,而且都发生在平时。

  1. 保留策略以链为单位。禁止删除链的中间环节;要清理只能整条旧链一起退,或者按”保留到第几个全量根”来表达。
  2. 每次全量之后强制做一次恢复演练并记录结论。演练不是加分项,它是把”作业成功”翻译成”能恢复”的唯一手段。
  3. 告警条件换成”末次成功恢复演练的时点是否超期”,而不是”末次备份是否成功”。前者的告警量会明显更大,因为它第一次开始说真话。
  4. 断链之后的处置要有预案而不是临场决定:立刻做一次全量作为新链根,同时把断链区间与影响范围(可恢复到的时点)记进台账并向业务方说明。
  5. 链台账由作业自己回写,人工补录只允许出现在事后修正,且必须留下修正原因。

交付给客户时,我们带的是一张备份矩阵,粒度到库:库名、备份方式与频率、保留策略、末次成功演练的时点、负责人、以及该库当前链能不能支持任意时点恢复。频率这一栏我们不给统一建议——同一个系统里不同库的变更量与恢复目标差别很大,只能由业务方按自己的恢复点目标填。

洹拓科技做值守交接时,把矩阵里三件事当验收线:能不能查出任意一个库当前的链是否连续;断链时有没有书面的重建与告知流程;末次演练的结论是谁签的。三条都有明确答案,这个库的备份才算交付过;只有作业调度截图的,都还在”看起来在备”的阶段。