真正的数据恢复现场,从来不会按照文档教你的做
最早写 PDU 文档的时候,我的想法其实很直接:把 PostgreSQL 数据恢复这件事尽量讲清楚,让人可以照着做。
现在文档站里的内容已经算比较完整了:
https://pduzc.com/docs
各种模式、参数和使用方式基本都写明白了。如果只看这些内容,大概会觉得恢复是一件可以按步骤完成的事情:准备好数据目录,读取系统表,找到 relation 文件,把 tuple 导出来,再导回数据库。
从工具设计的角度来说,这条路径没有问题。
但过去这一年里,我真正做过的恢复,没有一次是完全按这条路径走完的。
每一次都会在某个地方出现一点不一样的情况,而真正需要花时间处理的,往往正是这些地方。
慢慢就会发现,文档里描述的是一种结构完整的世界,而恢复现场更像是一个被打断之后重新拼起来的状态。两者之间的差别不会写在任何参数说明里,但一旦真正开始恢复,就很难忽略它。
有些场景看起来没有问题,真正处理的时候才知道难在哪里
第一次是误删表的数据恢复,虽然是半夜凌晨,但是第一次真正投身到数据恢复的行业里,让人异常兴奋。
文件都在,没有损坏,结构也能识别。刚拿到数据的时候基本可以判断,这一类应该能顺利做完。
真正开始导数据才发现,那是一张一百多列的表。类型分布很杂,没有TOAST 。tuple 可以正常解析,但扫描和导出的过程明显比预想的复杂得多,一些原本不明显的细节开始变成实际的问题。
更重要的是,那个时候我并没有参透WAL日志重放的真意,意识到自己根本做不到的那一刻,脑袋一下子嗡地一声,大半夜的,只能听到自己难堪的呼吸声。
直到后来把WAL日志恢复的原理确认下来了,一些处理逻辑也逐渐固定下来,也被整理进了 PDU。现在再碰到误删数据/误更新的这种表,基本可以直接完成。
但第一次遇到的时候,很难提前想到问题会出在哪。
有些数据能读出来,但不代表已经恢复完成
带复杂数据类型的数据表恢复也有过一次很典型的经历。
page 虽然能读,但是真正现场生产环境的复杂数据类型是实验室模拟不出来的,例如PostGIS数据被压缩之后还存在了TOAST表里,寻寻觅觅找了半天才发现报错原因。将bug修完之后,终于抽取出来的数据看起来没有明显异常,如果只是停在这一步,很容易觉得恢复已经结束了。
真正尝试把数据导入数据库测试的时候,发现问题才开始。
字节本身没有错,但某些字段的解释方式稍微偏一点,结果就会不对。花了很久导出来的多个schema导入均有问题,而且都是同样的类似问题。
要是一开始导出一个schema就导入发现问题,那能给客户节省多少时间啊。
后来处理 pg_vector 数据的时候也遇到过类似情况。
这些场景都有一个共同点:从物理结构看没有问题,但真正恢复成数据库可用的数据还需要多走一步。文档里能写清楚的是前一部分,而后一部分往往要等真正做过才知道需要注意什么。
有些恢复面对的甚至不是一个完整的实例
印象最深的一次,是 rm 根目录之后的数据恢复。
磁盘恢复工具拿回了一批文件,看起来像 PGDATA,但没有人能确定里面到底还剩多少有效内容。
目录结构大体还在,relation 文件也能找到,只不过,这是一个基于PG的国产数据库。
纯血PG肯定是说不上了,国产数据库对PG数据页的改造总在黯然销魂处。
虽然最后文件里的数据还是被PDU顺利导出来了,但整个过程更像是在处理一组历史遗留下来的文件,而不是在恢复一个系统。
这种经历做多了之后,会慢慢习惯一种感觉:恢复的时候不一定存在一个清晰的起点,反而有的时候就像是一场接力,从上一位专家的手中接过接力棒的时候,就是你的表演时刻,把握好这些机会。
有些能力是在事故里慢慢长出来的
过去一年里遇到的一些场景,后来被整理进了 PDU。
一些早期必须手动干预的步骤,也逐渐变成了工具里的常规流程。 但也有一些情况始终没法完全标准化。
例如有一次恢复里,四张系统表都有固定字节数量的损坏。catalog 已经无法完整解析,但仍然能看出一些关系线索。真正恢复数据时,需要先用GDB调试把这些信息单独处理出来,再让工具继续运行,这个功能当然可以做到软件里,但最近在忙别的,还没顾得上。
类似的事情没法预先设计出一个统一方案,因为每一次损坏的方式都不会完全一样。
整库 drop database 的恢复现在还是束手无策,虽然也试过把客户现场磁盘里长得像pg数据页的8k字节全都揉在一起,整了个大大的二进制文件拷贝回来,里面数据字典我是能分辨出来,但是整库表的量还是太大了,依然没有太好的办法。
这些工作最后往往不会写进文档里,但却是恢复过程中不可避免的一部分。
恢复过程往往是边走边判断的
很多人第一次接触数据恢复时,总会问有没有一个标准流程。
这种想法很自然,因为数据库操作通常都有明确步骤。
真正开始恢复之后才会发现,命令本身反而不是最关键的部分。更重要的是先看清楚手里的数据到底是什么状态,然后再决定接下来该怎么做。
有时候需要先确认 relation 是否还能对应起来,有时候需要判断 catalog 剩下的信息是否足够,有时候只是先找出哪些文件还值得继续处理。
这些事情不会体现在参数说明里,但几乎每一次恢复都会遇到。
工具能提供的是一条尽量稳定的路径,而不是对所有情况的提前描述。
文档更像是一张地图
后来慢慢会觉得,文档和真实恢复之间的关系有点像地图和实地环境。
地图必须简化世界,否则就没人能用它。
但真正走到现场的时候,总会遇到地图上没有标出来的东西。有时候只是多走几步,有时候需要重新找方向。
PDU 文档描述的是 PostgreSQL 恢复中那些稳定存在的结构,而真实恢复现场则是这些结构在各种意外条件下的实际样子。
两者并不冲突。
只是文档解决的是确定的部分,而恢复工作永远会留下不确定的空间。
也正因为这样,工具才会随着每一次事故慢慢变化。新的能力往往不是设计出来的,而是在真正做过之后才知道这个功能迫切地需要存在。
在PG数据库恢复这条路上,有什么是你最想了解的,留言区欢迎你的靓影📢
夜雨聆风
