DBCC CHECKDB指令可以完成两项任务:(1)检查数据库里有没有损坏发生。(2)尽力修复数据库损坏,使数据能够重新被正常访问。所以哪怕是一个正常运行的数据库,也建议定期运行这句指令,以确保没有损坏发生。对于已经发生访问错误的数据库,应该在第一时间运行这句指令,了解损坏的范围和程度。
那么DBCCCHECKDB究竟做了哪些检查呢?
在做些什么
DBCC CHECKDB通过依次执行下列操作检查指定数据库中所有对象的逻辑和物理完整性:
1. 检查一些关键的系统表。
2. 对数据库运行DBCC CHECKALLOC。
3. 对数据库中的每个表和视图运行DBCC CHECKTABLE。
4. 对数据库运行DBCC CHECKCATALOG。
5. 验证数据库中每个索引视图的内容。
6. 验证数据库中的Service Broker数据。
这意味着运行了DBCC CHECKDB,就不必再单独运行DBCC CHECKALLOC、DBCCCHECKTABLE或DBCC CHECKCATALOG命令。也意味着单独运行DBCCCHECKALLOC、DBCC CHECKTABLE和DBCCCHECKCATALOG命令,虽然不能完全完成DBCC CHECKDB的所有功能,但是至少完成了大部分功能。
检查一些关键系统表
在检查数据库之前,SQLServer需要去了解这个数据库里到底存放了什么样的数据,也就是所谓数据库的“元数据”(Metadata)。没有这些信息,SQL Server无法知道自己将要去访问什么样的表格,也没办法知道自己应该怎么解释将要读到的记录。
关键系统表有:
sysallocunits。
syshobts。
syshobtcolumnes。
sysrowsets。
sysrowsetcolumns。
对于普通用户访问,这些表都是不可见的。只有在DAC模式下的连接,才能看到它们。它们的结构对普通用户也是透明的。
这里的每一张系统表都有一个聚集索引。SQLServer会像做CHECKTABLE一样,对这些系统表做一遍检查,确保这些表格里的每一页面及页面里的每一条数据都可以正确地读出来。如果中间发现问题,例如发现某个页面不能被正常访问,SQLServer就会报错。例如:
Server: Msg 8966, Level 16, State 1, Line 1
Could not read and latch page (1:33245) with latch type SH.Sysobjects failed.
对于小的数据库,这些存放元数据库的系统表不会占用太多的页面。如果发生硬件问题,损坏的几率比较小。但是对一些有成千上万对象的数据库,这些原数据系统表本身就可能使用了很多页面,发生损坏的几率也随之增大。由于这些系统表是正确读取一切数据的根本,所以如果任意一张系统表上发生了损坏,DBCCCHECKDB都会直接失败,数据库也无法做任何修复。此时恢复数据库的唯一方法,只有恢复数据库的备份。
对数据库运行DBCC CHECKALLOC
DBCC CHECKALLOC将检查数据库中所有页的分配。它还可验证各种内部结构,这些结构可用于跟踪这些页,以及它们之间的关系。
DBCC CHECKALLOC将返回以下结果集(值可能有所不同,我们以AdventureWorks数据库为范例)。
DBCC results for 'AdventureWorks'.
***************************************************************
Table sys.sysrowsetcolumns Object ID 4.
Index ID 1, partition ID 262144, alloc unit ID 262144 (type In-rowdata). FirstIAM (1:139). Root (1:66). Dpages 0.
Index ID 1, partition ID 262144, alloc unit ID 262144 (type In-rowdata). 13 pages used in 1 dedicated extents.
Total number of extents is 1.
***************************************************************
'...'
***************************************************************
Table Production.TransactionHistoryArchive Object ID 158623608.
Index ID 1, partition ID 72057594047037440, alloc unit ID72057594053459968 (type In-row data). FirstIAM (1:804). Root (1