数据库出问题时,最容易被忽略的一步是先看备份。在动手扫数据文件之前,把备份、日志、从库这三条线确认清楚,往往比任何恢复工具都有效。碎片提取是最后的手段,不是第一选择。
一、先判断属于哪一类
- 误删数据行(DELETE):数据页上的记录被标记为可覆盖,空间并未立即擦除,页内仍留有痕迹。这是碎片提取最有把握的场景。
- 误删表或截断(DROP/TRUNCATE):表定义与数据页的归属关系被解除,需要先重建表结构,再按页特征把数据捞回来,难度高一层。
- 数据文件被删除或分区被格式化:文件系统层面的丢失,数据页可能完整存在,走底层扫描按页结构提取。
- 文件损坏、页校验失败:需要先评估损坏范围,能用备份或日志补齐的优先补齐。
四类问题的共同前提是一样的:数据库必须停止写入,数据文件所在磁盘不能再有任何写操作。
二、两种库的组织方式
MSSQL:数据文件(MDF/NDF)以 8KB 页为基本单位,页头记录页类型与归属对象,页内行数据按槽位组织。恢复的关键是识别页头结构、判断页归属,再把行数据按表结构解出来。
ORACLE:数据文件(DBF)以块为单位,块大小可配置(常见 8KB),块内有行目录与行数据。控制文件与重做日志记录着数据文件的结构变更,日志是否完整直接影响能恢复到哪个时间点。
两种库的碎片提取都不是“打开文件就能看到表”。它做的是三件事:按页/块特征扫描数据文件,剔除已被覆盖或已释放的页,把剩下的页按对象归属重组,最后用表结构把二进制行数据翻译成可读记录。
三、碎片提取能做什么
- 数据文件还在、但库无法附加或挂载时,直接从文件层提取记录。
- 误删行、误删表之后,在数据块被覆盖前把残留记录捞回。
- 数据文件被误删或所在分区被格式化后,按页结构做底层扫描。
提取出来的是记录集合,通常以脚本或表格形式交付,需要按业务口径核对重复与缺失,不能直接当生产数据回灌。
四、碎片提取做不到什么
- 被覆盖的页找不回来。新数据写进同一位置,原页内容被替换,这是覆盖的本质。
- 不能替代日志恢复。需要恢复到某个时间点的,完整的事务日志是最可靠的路径,碎片提取给不了时间点的精确性。
- 不能补回缺失的表结构。数据结构本身丢了,需要从备份、脚本或系统表残留里还原定义,否则提取出的二进制无法翻译。
- 无法确保记录完整。碎片按页捞,跨页的大字段、被拆分的行可能缺失,结果以实际扫描为准。
五、操作要求
- 立即停库。停止数据库服务与所有写入应用,不要让业务继续跑。
- 不要在原机原盘上做实验。把数据文件、日志文件整盘做镜像,后续所有分析在镜像上做。
- 先确认备份与日志。有可用的完整备份加日志链,优先按日志恢复到故障前的时间点。
- 评估范围与目标。需要的是几张表、还是整库;时间点要求到什么精度。这决定后续是走日志、走备份、还是走碎片提取。
- 提取结果单独落盘,用测试库还原核对,不与生产环境混用。
数据库场景不建议自助硬扛。涉及阵列、集群、加密表空间、大型表的场景,误操作一次可能连带影响日志,把本来能恢复的路堵死。这类情况把库版本、数据文件大小、故障操作与发生时间整理清楚,走人工评估更划算。
六、常见问题
DELETE 之后马上停库,能全部恢复吗?
恢复程度取决于后续写入量。停得越早、覆盖越少,可提取的记录越完整;已经写入新数据的页,内容被替换后无法还原。
有备份是不是不用做碎片提取?
优先用备份,这是原则。备份只能回到备份时点,备份之后产生的数据要靠日志补齐;日志链断了,才轮到碎片提取兜底。
数据库装在虚拟机上,直接还原快照可以吗?
可以,而且通常是最快的方式。但要注意还原后与原环境的一致性,尤其是日志与从库的同步关系,避免还原后出现主从不一致。
提取出来的数据能用吗?
需要核对。碎片提取给的是记录集合,可能含重复、缺失或版本不一致的行,导入前应做完整性校验与业务口径核对。
同栏目延伸阅读
免责说明:恢复结果取决于介质故障程度与数据覆盖情况,本程序不承诺恢复成功;已被新数据覆盖的部分通常无法恢复。物理故障(异响、摔落、进水、烧毁)请立即断电停用,不要反复通电尝试,也不要自行拆解。