1、数据库故障概述
SQL server数据库的数据无法被读取。

2、故障分析

SQL server数据库文件无法被读取,是由于底层File Record被截断为0,无法找到文件开头,数据表结构也被损坏。镜像文件的前面80M左后的空间,还有中间一部分被覆盖掉,导致系统表被损坏,所以无法读取,考虑用自动备份文件来提取表结构。
日志中的操作记录:
实用案例 - SqlServer数据库数据无法读取解决方法_第1张图片
由于系统表被损坏,有大量数据表的结构无法被确定,只能靠工程师根据经验进行恢复工作。

3、解决方案

备份用户数据,对丢失数据的硬盘。做全盘备份,以确保数据的安全性。
分析备份文件中旧数据的数据库。
从旧数据库中寻找数据表的结构。
从日志中提取一部分数据表的结构。
从日志中和残留数据中提取完好的数据。
根据日志恢复对应的数据,并检查数据是否正确。
核对数据没问题后恢复所有数据。

4、数据恢复实施过程

4.1备份用户数据
由于数据全部都放在客户的原盘中,先交给硬件部门检测硬盘是否存在物理故障。经检测没问题后对每块硬盘做全盘镜像,使用专用工具将硬盘中所有扇区镜像到一块备份硬盘中。

4.2扫描镜像文件
用winhex打开残留文件,仔细分析硬盘底层数据,发现硬盘底层中还残留着许多以前SQL server的日志和备份文件。经过细心察看和分析,发现日志中有数据库很多包括插入语句的操作记录,这些记录可以考虑提取出来。还有备份文件,打开备份文件可以发现有建表语句,还有一部分旧数据。
但由于整个硬盘太大,人工去搜索SQL server相关数据部分会很慢,因此编写一个提取数据库相关数据的小程序,对整个硬盘中所有存在的数据库残留做扫描,提取所有数据。
4.3分析扫描数据
对扫描到的所有日志文件进行分析,发现日志文件中也分数据页,有着固定的开头和结尾,其中每条数据都在固定的位置有自己的object ID号,在接下来的扫描文件中,继续搜寻有同样的object Id的数据记录,发现结构相同,可以确定这是完好的数据,可以提取。
再对扫描到的备份文件进行分析,发现可以从中提取出很多建表语句,可以得到一部分表结构。剩余的表结构,由于截断为0的部分刚好在系统表,没有办法提取表结构,只能从日志中提取的数据来猜测表结构和数据类型。
4.4提取数据
根据之前分析的结论,先编写程序从备份文件中提取建表语句,根据建表语句分析出表结构与各种数据类型,同时在残留的系统表中寻找22H、07H、05H表,根据这些建立表与OBJECT_ID的对应关系。然后编写新的程序对日志中的记录进行提取(我是在这一步无法把numeric类型的字节码解析成数据,所以卡住了),根据object ID来对数据和表进行对应,并插入到新表中。
4.5验证所有数据
经验证,数据恢复出来的新表与人工观察到的数据基本一致。
数据恢复成功。