判断数据损坏
案例1
    石化软件:曾有一用户SQL SERVER 2000数据库PlanDetail表损坏,Select * 时会报错。
使用“DBCC CHECKDB”命令检查数据库时,正常时的信息如下图:
今天我想你了
损坏时报:
使用“DBCC CHECKDB”命令检查数据库时,会有表的错误信息出现。
网上到的修复方法:
处理这种数据库,分为两个大的步骤:
第一步:处理可以访问的数据表
1)出哪些表不可访问,即:sql server系统表中哪些记录损坏;
2)SQL server DTS把能够访问的用户数据表导入一个新的DataBase
在导库时,不能选折(1)中不能访问的数据表。
第二步:处理不可访问的数据表:
1)出系统表中错误记录的ID
2)根据错误记录的ID”,删除律师事务所排名sysobjectssysindexessyscolumns 表错误的记录;
3)根据错误记录的ID” ,重建系统表记录;
4)重建完毕,如果该表可以访问,那么用DTS单独将此表导入新的DataBase
说明:重建sql server系统表方式不一定会成功,比如由于DISK I/O错误,如果仅仅是保存系统表的磁盘扇区出错,那么重建系统表方式可以挽回数据。 如果保存用户数据表的磁盘扇区出错,那么即使重建系统表也不能解决问题。如果重要的用户数据表无法导库,如:t_Voucher IcStockbillICSale等,那么可以用用第二步中的方法一试。
当时使用的是第一次方式,处理方式为手工。
自动:
文件隐藏--默认实例使用
net stop MSSQLSERVER
net start MSSQLSERVER
--SQL2005实例使用
net stop "SQL Server (SQL2005)"
net start "SQL Server (SQL2005)"
--设置单用户
sp_dboption 'PetroChemical',single,true
use master
go
DBCC CHECKDB('PetroChemical'),repair_allow_data_loss) --修复
select count(*) from plandetail
sp_dboption 'PetroChemical',single,false
--CHECKDB 3个参数:
--REPAIR_ALLOW_DATA_LOSS
--  执行由 REPAIR_REBUILD 完成的所有修复,包括对行和页进行分配和取消分配以改正分配错误、结构行或页的错误,以及删除已损坏的文本对象。这些修复可能会导致一些数据丢失。修复操作可以在用户事务下完成以允许用户回滚所做的更改。如果回滚修复,则数据库仍会含有错误,应该从备份进行恢复。如果由于所提供修复等级的缘故遗漏某个错误的修复,则将遗漏任何取决于该修复的修复。修复完成后,备份数据库。
--REPAIR_FAST 进行小的、不耗时的修复操作,如修复非聚集索引中的附加键。这些修复可以很快完成,并且不会有丢失数据的危险。
--REPAIR_REBUILD 执行由 REPAIR_FAST 完成的所有修复,包括需要较长时间的修复
(如重建索引)。执行这些修复时不会有丢失数据的危险。
案例2
      客户报告中午正常使用的系统,下午无法打开,报告的是连接数据库错误。电话中初步判断是数据库启动失败。首先告知客户无法立即恢复,先转成手工操作。
      到达客户处,首先检查“事件查看器”,发现系统日志文件损坏,事件查看器无法显示系统日志。只能首先删除清空,并重建事件日志文件。然后再启动sqlserver,这时候就可以在事件查看器中看到sqlserver启动失败的错误信息了。错误大概是说 “启动过程中master汕尾凤山数据文件损坏,数据库无法恢复”。由于master是系统数据库,因此SQLSERVER无法启动。
      此服务器以前曾经发生过windows2000操作系统崩溃,曾经备份过有开发商开始卖现房SQLSERVER DATA 目录,万幸,把master的两个数据文件覆盖过来(master.mdf,mastlog.ldf)后,数据库就可以启动了。
      测试一下,怎么程序还是不能打开,都快出汗了。一看,客户数据库居然是“质疑”的。再看事件查看器有"Disk"错误,连忙备份,好在管理员在前一天中午做过数据备份。恢
复并将数据文件转移到另一个硬盘分区上,至此系统操作正常。至于丢失的一天数据让客户时间再补入系统。
      分析原因:客户表示没有非法关机,停电等故障。因此有可能是硬盘出现坏道,或者是内存品质不良。
案例3
      某天给客户升级报表,第二天早上,客户打电话来说系统不能打开。初步判断也是数据库启动失败。询问客户也没有修改过机器名,管理员密码。通过VNC连上客户服务器发现,还是MASTER数据库损坏。
      这时候情况比较复杂,由于是新安装的系统,运行还不满一个月。实施时由于疏忽没有做过任何备份。只能尝试将其他电脑上的master数据文件拷贝过来。我笔记本上的SQLSERVERdesktop版,与服务器上安装的不符。没办法,只能死马当活马医了。压缩,发送,折腾了半个小时才把文件发送到客户服务器上。覆盖... 启动... ,绿箭头出来了。居然成功了。
      打开企业管理器,这时,客户数据库的属性都变成和我笔记本上的数据库一样了。密
码,用户数据库。当然由于部分数据文件不一样,所有的用户数据库都是质疑的。删除不存在的用户数据库,然后附加客户自己的数据库。
      通常,附加数据库后,系统应该就可以使用了。但没想到的是这个客户数据文件也是损坏的,附加数据库失败。这下恢复过程陷入僵局。虽然数据没用多少天,但库中有关键数据必须恢复。
 附加数据库错误提示:
 错误3456:未能恢复日志记录(xxx:xxx:x)事务 ID0:xxxxx......等等
    怀疑是日志文件损坏,只能寄希望于数据文件没有损坏。删除数据库日志文件,单独附加数据库文件,结果还是失败,报告日志文件不符
    由于远程操作过于缓慢,只能将客户数据文件压缩传回本地,再想办法进行修复。
    由于数据日志中还有活动事务,文中第一种方法显然不适用我这种情况。遂按照第二种方法将数据库设置为紧急模式。当做到 DBCC CHECKDB 时。结果就与文章表示的不同了。
服务器: 消息 3908,级别农业银行信用卡 16,状态 1,行 2
未能在数据库 'sttzjg' 中运行 BEGIN TRANSACTION,因为该数据库处于回避恢复模式。
 
    此时网上的文章都没有提示不到进一步的处理方法了。这时直接做DTS数据导出也是报错:DTS Wizard报告说初始化上下文发生错误
    不过万幸的是,这时候已经可以SELECT数据了。但有几个表 SELECT的时候报告:
服务器: 消息 601,级别 12,状态 3,行 1
由于数据移动,未能继续以 NOLOCK 方式扫描。
 
      不能使用DTS, 常用的mssql2工具也不行。没有办法了,只能用SELECT手工恢复数据。首先新建一个新的业务数据库new,然后使用 "insert into new.dbo.table select * from xxx "一个一个拷贝数据表。化了一个多小时,最后只剩下那三个SELECT也报错的表了。
 
      试试bcp,也报错,不过数据倒是导出来了,这下就好办了。用bcp把能导出的数据导到新库。至此数据库基本恢复。检查报表,发现也是丢失了一天的数据。时间节点上看,
大概就是增加报表之后的一天的数据全部丢失,主要就是那三张SELECT报错的表中。
      继续检查事件查看器中的内容,没有发现严重的磁盘错误。开关机的日志也很正常,很奇怪,不知道什么情况会造成一整天的事务日志没有完成,而且还造成master数据库损坏。想不出来原因,还是先给客户设置好每日的数据自动备份。以后再出现这种情况也好处理一些。
      总结:我们的客户使用的服务器都很一般,数据库备份相当重要,培训客户做好备份,减少由于系统故障造成的数据损失。
了解到的问题分三种
1、 数据库表损坏(包括部分被置疑数据库,前提是被置疑库为表或表索引损坏):
使用DBCC CHECKDB(‘问题库')可以检查出错误并修复
2、 DISK I/O损坏:
3、 Master表损坏:
4、 日志文件损坏:
后三种错误实际上并不容易很清楚的判断,因为常常是并发的,如:日志损坏可能伴有Master损坏,或是原因是DISK I/O坏造成日志坏等
可以确定的是,如果在连接时即报错,首先怀疑是系统日志文件损坏,而原因可能只是日志坏了,也有可能是DISK I/O损坏,但这只有修复日志后才能发现。因此,最好的办法是还原数据库操作。建议把master库也进行备份,在还原时删除原库再进行还原操作,如果失败,进行master库的还原。