先简单交代一下背景。一台服务器的存储阵列采用的是RAID5方案,由5块2TB硬盘组成。这个阵列划分了LUN挂载到一台Windows服务器上,服务器上跑着SQL Server 2008数据库。阵列存储空间被分成了三个逻辑分区,容量分别是500GB、800GB和2.3TB。
问题来了:服务器上的5套业务数据库文件全部丢失,涉及的数据表总量大约6000张。其中3个核心数据库容量分别为8GB、15GB和20GB。数据丢失的具体诱因不明,而且更棘手的是,根本没法确定原始数据库文件存放在哪个分区。文件丢失后服务器一直开着机,不过期间没有大批量数据写入,数据被覆盖的风险相对较低。
初步检测时,工程师采集了阵列底层的RAID参数和磁盘数据块特征,完成了RAID阵列的虚拟重组。

从重组后的阵列LUN中,工程师完整提取了3个逻辑分区的镜像文件。随后对分区镜像做了文件系统级的全盘扫描,检索删除记录,结果没有匹配到丢失的数据库原始文件。初步结论很明确:数据库文件已经彻底丢失,依靠文件系统恢复手段不可能找回数据,必须走底层数据页提取方案来做深度恢复。
接下来是具体的实施流程,一共九个步骤。
1、定制专项恢复方案
既然原始数据库文件已经丢失,文件系统恢复也失效了,那么思路就是底层扫描SQL数据页,解析并提取页面里的业务记录。
2、分区镜像底层数据页扫描,定位存储分区
工程师用自研的数据页扫描工具,对三份分区镜像分别做了全盘数据页检索。

扫描结果显示:500GB系统分区有效数据页存量非常少,而且页面碎片、断裂问题严重;另一个分区则检出了海量完整的SQL数据页。据此判定,这个分区就是数据库原始的存储分区。
3、系统表解析遇阻,调取客户备份辅助恢复
SQL Server依靠系统表来统一管理用户表信息,包括字段数量、数据类型、约束规则等核心结构。工程师在解析提取的数据页时发现系统表损坏,无法读取表结构元数据。与客户对接后确认,客户保留了有效的数据库备份,而且备份生成后没有对数据表结构做过大规模调整——备份文件里的系统表信息是完整可用的。
4、恢复备份,提取完整表结构
导入客户备份文件完成还原。

分别导出3套核心数据库全部数据表的建表结构。

5、解析存储表结构元数据
批量解析数据表结构脚本,将字段名称、类型、长度、约束等信息统一入库存储,为后续数据页匹配提供参照。


6、关联系统表ID与分区原始数据页
解析备份系统表获取各用户表的唯一标识ID,建立表结构与底层扫描数据页的关联映射。出于客户数据隐私保护,数据表名称和原始业务数据相关的步骤没有配截图。
7、新建恢复库,批量导入解析记录
搭建独立的恢复环境,新建空白数据库,通过解析工具读取分区内提取的数据页原始记录,批量写入恢复数据库。
8、数据清洗去重处理
目标分区除了业务数据库,还存放了多份历史备份文件,导入后存在大量重复业务数据。工程师编写了专用的SQL存储过程,对全量数据执行去重清洗。

剔除冗余重复记录。
9、客户校验与交付
全部数据整理完成后交由客户核验,客户确认恢复数据完整可用。随后将恢复后的数据库迁移至客户自有存储设备,本次数据恢复工作就此完成。
