《Microsoft Sql server 2008 Internals》读书笔记--第十一章DBCC Internals(4)

《Microsoft Sql server 2008 Internals》读书笔记订阅地址:

http://www.cnblogs.com/downmoon/category/230397.html/rss

《Microsoft Sql server 2008 Internals》索引目录:

《Microsoft Sql server 2008 Internal》读书笔记--目录索引

从本文开始,我们了解几种类型的一致性检查,先来看两个:原始的系统目录一致性检查和分配的一致性检查。

 

原始的系统目录一致性检查

在SQL Server 2008中,存储引擎定义了三类系统目录:

sys.sysallocunits
sys.sysrowsets
sys.sysrscols

在SQL Server 2005中,有两个更为重要的系统表sys.syshobts和sys.syshobtcolumns,但是这两个都被纳入sys.sysrowsets和sys.sysrscols表。总的来说,这些和老的sysindexes、sysobjects和syscolumns表是等价的。他们容纳所有的基元数据(存储引擎需要它们在表和索引结构间导航)。出于这个目的,DBCC CHECKDB也使用它们,虽然是间接地在相关引擎通过元数据子系统。

这些系统目录每个都有一个聚集索引,有的也有非聚集索引。DBCC CHECKDB需要聚集索引的叶级是否没有明显的破损以便使它调用一个元数据函数从它们中的某一个提取信息时,元数据函数成功的机率较大。

这三个聚集索引的叶级上,下列检查被执行:

◆每页被读进缓冲池。

这将检查没有关于页的I/O问题(例如一个页校验失败,无效的页ID,或读取页的I/O子系统的明显失败)。这个操作失败时报告7985错误。

◆每页被审核

页审核后面会提到。基本上,它确认页结构和页头看上去有效。页必须是一个数据页,而且必须被分配到正确的分配单元。如果失败则报告7984错误。

◆叶级链接列表被检查

一个索引某个级的的所有页都在一个双链接列表。一旦该叶级的所有页被读进缓冲池并被审核,页的连接在叶级中被下一个页连接检查,以确认前一个页连接真实地指向前一个页。如果连接列表破坏,报7986或7987错误。

◆叶级列表被循环检查

当链接列表连接被检查到有两个指针在列表中时,该检查发生。如果它们曾经在faster-advancing的指针到达叶级的右半侧时指向相同的页,不会循环。重要的是没有连接循环,否则,一个边界扫描可能转化为一个不明确的循环。如果循环被探测到,报出7988错误。

如果这些检查中的任何一个失败,DBCC CHECKED以相关的信息终止。比如可能是:
DBCC CHECKDB ('TestDB') WITH NO_INFOMSGS, ALL_ERRORMSGS;
GO
Msg 7985, Level 16, State 2, Line 1
System table pre-checks: Object ID 4. Could not read and latch page (1:65) with latch type
SH. Check statement terminated due to unrepairable error.
DBCC results for 'TestDB'.
Msg 5233, Level 16, State 98, Line 1
Table error: alloc unit ID 262144, page (1:65). The test (IS_OFF (BUF_IOERR, pBUF->bstat))
failed. The values are 12584969 and -4.
CHECKDB found 0 allocation errors and 1 consistency errors not associated with any single
object.
CHECKDB found 0 allocation errors and 1 consistency errors in database 'TestDB'.

DBCC CHECKED终止是因为这些关键的(DBCC CHECKED检查数据库的剩余部分必需的)系统目录。注意:在DBCC CHECKED输出中没有推荐的修复级别。这些错误不能被修复--仅有的选项是从备份中恢复。

如果没有任何问题被发现,下一步是运行数据库级的分配一致性检查。

 

分配的一致性检查

这些检查校验跟踪数据库中的页和分区分配的各种结构之间的内容及关联性。这些调用的结构如下:

◆PFS页,跟踪一个独立页的分配状态,一个数据文件中的64MB部分片段(一个PFS间隔)

◆GAM页,跟踪所有分区的分配状态,一个数据文件中的4GB部分片段(一个GAM间隔)

◆SGAM页,跟踪所有至少有一个可用页(用于分配)的混合分区(一个GAM间隔)

◆IAM页,跟踪从一个GAM间隔的分配到一个分配单元的页和分区

◆IAM链,链接一个分配单元的所有IAM页的一个链接列表

◆三个关键系统表的存储引擎元数据

分配一致性检查是非常快的,实际上,相比Per-table和交叉表一致性检查可以算是巨快了。原因很简单,必须被读取以执行分配一致性检查的数据页的数量比用于每表和交叉表一致性检查的数量少的多的多。
 ■1、检查分配事实

在任何分配一致性检查运行前,需要从各种分配结构中采集所有必需的信息,并存储作为事实(fact)

对数据库中的每个联机的文件组的每个数据文件,下列动作被执行:

◆数据库的引导页(file 1的页(1:9))和每个数据文件页的文件Header页(page 0)被审核(audit),检查失败,报5250错误,DBCC CHECKED终止。

◆所有PFS页被读取并处理。这提供了一个文件中所有IAM页的位图。同时PFS页也跟踪IAM页,提供了一个来自混合分区的文件中的页的位图。每一个位图集占用比文件中的所有PFS页小的空间,因为PFS页存储每一个数据文件页的8字节信息。
 ◆所有GAM页被读取和处理。这提供了一个文件中的所有已分配分区的位图。

◆所有SGAM(Shared Global Allocation Map)页被读取和处理。这提供了一个文件中所有(至少有一个可用页的)混合分区的一个位图。

◆DCM(Differential Changed Map)页和ML Map(Minimally Logged Map)页(在GAM分区被处理时)被读取。仅仅确保它们能被正确的读取。

在每个GAM间隔的开始,是一个特殊的分区,称为GAM分区,包含该GAM间隔的GAM和SGAM页,也包含两个其它的页,用以跟踪该GAM间隔的分区(extent),即DCM和ML Map页。DCM页跟踪GAM间隔中的(自上一次完整数据库备份开始以来)所有分区变化。ML Map页跟踪(自上次事务日志备份以来)在GAM间隔中通过最小化的日志操作而改变的分区。

◆所有IAM页被读取和处理,这提供了:

1、文件中所有混合页的列表。

2、文件中所有有效IAM页的列表。

3、文件中所有的已分配的分区列表。

4、所有IAM链的链接信息。

所有在一个IAM链的所有IAM页都被链接在一个双链接列表中。它们也包含一个序列号,在链中的第一个IAM页,自0开始,每个IAM页回到链时加1。

如果任何分配页因为Header破坏而不能读取,报8946错误,或破坏的IAM页报7965错误。这意味着数据库的大range被从一致性检查中排除,此时会报错8998。

在所有的per-file信息采集时,存储引擎元数据被如下处理:

1、每个IAM链的的第一个IAM页的页ID被存储在系统目录。该页ID用于生成IAM链的的第一个IAM页的页的父事实(fact),这应该在per-file期间匹配一个生成的实际事实。在此期间,所有的系统目录被检查以确定它们被存储在数据库的主文件组。如果不在,报8995错误。

2、关于当前等待被“deffered-dropped”IAM链的信息被存储在一个内部的队列。

deffered-drop是一个SQL 2005推出的优化,用于防止一个事务在删除一个IAM链时运行时锁定内存。

如果DBCC CHECKED不扫描内部(作为分配事实生成的处理的一部分的)队列,它可能检查各种各样的(与各种分配位图一起的)不完整。

分配事实被传送到查询处理器,在那儿被存储和在一起分组,然后被传回到DBCC CHECKED以使它们能被聚集并找到任何错误。

 ■2、检查分配事实

分配事实聚集算法执行下列一致性检查:

  ◆检查每个GAM间隔的每个分区是否被正确的分配。分配可能是下列中的一个:

1、GAM页中被标记为可分配

2、SGAM页中被标记为一个非完整的混合分区

3、在一个准确的IAM页中被标记作GAM间隔的封面(Marked in exactly one of the IAM pages that cover the GAM interval)

4、没有被标记为分配位图的任何一个。

下表列出了可能的组合:Possible Combinations of Allocation Bitmaps

GAM SGAM IAM Legal Meaning Error
0 0 0 Y Mixed extent with all pages allocated N/A
0 0 1 Y Dedicated extent allocated to an IAM N/A
0 1 0 Y Mixed extent with available pages N/A
0 1 1 N Illegal 8904
Y Extent is not allocated N/A
N Illegal 8904
N Illegal 8903
N Illegal 8904

 如果两个IAM页有相同的已分配分区,会报8904错。8904和8913通常相连。如果一个分区是一个混合分区,但混合页中没有一个可见,报8905错误。

 ◆检查每个混合的IAM页的PFS字节是否正确。如果检查失败,报8948错误。

  ◆检查被一个PFS页标记为作为一个混合页(出现在一个IAM页的某个单页的slot数组)的每个页。检查失败,报错8906.

Msg 8906, Level 16, State 1, Line 1
Page (1:50139) in database ID 13 is allocated in the SGAM (1:3) and PFS (1:48528), but
was not allocated in any IAM. PFS flags 'MIXED_EXT ALLOCATED 0_PCT_FULL'.

  ◆检查每一个混合页是否被分配在仅仅一个单个IAM页的单页slot数组,如果检查失败(即在两个分配页中),报8910错误

◆检查IAM链的IAM页是否有单调递增序列数字。如果检查失败,报2577错误

◆检查同一个IAM链的两个IAM页是否映射到相同的GAM间隔。如果检查失败,报8947错误

◆检查一个IAM链的所有IAM页是否属于相同的分配单元。失败,报8959错误

◆检查IAM页是否映射到数据文件的有效portions(比如没在File ID 0或2),如果检查失败,报8968错误

◆检查一个IAM链的IAM页之间的链接列表是否正确。包括来自于sys.sysallocunits目录的指针。如果检查失败,报8969,或2575,2576错误

例如:Msg 2576, Level 16, State 1, Line 1
The Index Allocation Map (IAM) page (0:0) is pointed to by the previous pointer
of IAM page (1:79969) in object ID 0, index ID -1, partition ID 0, alloc unit ID
107504789946368 (type Unknown), but it was not detected in the scan.

◆检查一个IAM页是否映射相同文件组的一个GAM间隔,如果任何页面检查失败,报8996错误

◆检查映射最终GAM间隔的所有IAM,GAM和SGAM页是否有分区被标记为已分配,并超出文件的物理终点。如果检查失败,报2579错误

一旦分配一致性检查完成,逻辑一致性检查的根基已经打成,下一步是per-table一致性检查。

 

 

posted @ 2010-07-31 13:10  邀月  阅读(1706)  评论(0编辑  收藏  举报