《Microsoft Sql server 2008 Internals》读书笔记--第十一章DBCC Internals(8)
《Microsoft Sql server 2008 Internals》读书笔记订阅地址:
http://www.cnblogs.com/downmoon/category/230397.html/rss
《Microsoft Sql server 2008 Internals》索引目录:
《Microsoft Sql server 2008 Internal》读书笔记--目录索引
前面几篇主要介绍了per-table一致性检查,本文我们关注交叉表的一致性检查,主要包括:Service Broker一致性检查,交叉目录(cross-catalog)一致性检查,索引视图一致性检查,XML索引一致性检查,空间索引(spatial-index)一致性检查。
■交叉表一致性检查
交叉表一致性检查包括验证数据库中的表之间的各种非物理的关系。一些例子如下:
◆表的元数据必须匹配描述列的元数据(这两套数据在不同的系统目录中)
◆primary XML索引必须精确代表它索引的XML列(primary XML索引作为内部表存储,与包含它所索引的XML列隔离)
◆索引视图必须精确代表视图定义。
交叉表一致性检查只有在涉及的表的一致性检查完成并没有一致性问题(或问题已修复时)才会运行。
例如,设想一个XML索引建在一个基于表T1的XML列。表T1有一个页损坏,它似乎是空的(即一些记录是不可访问)。如果XML索引检查在表T1检查之前,它可能从XML索引中额外的信息得知索引是损坏的。但实际上,是T1表已损坏,XML索引需要在表T1的任何修复后重建。
看起来,这是一个微妙的差别,但DBCC CHECKDB需要报告一阶(first-order)一致性错误。持有同样的逻辑来执行的其他交叉表一致性检查,因此,根据什么一致性错误在早期阶段发现,交叉表一致性检查中的某些可能被跳过。
1、Service Broker一致性检查
服务代理内容使用数据库的两种类型的表:
◆在数据库中使用的服务代理(例如,对话,端点,队列)相关的存储元数据的系统目录
◆用于存储服务代理序列的内部表
这两种类型表都拥有用户表的物理结构,但因为行为和可访问性不同而有不同的属性。它们的物理结构被如前所提到的逻辑一致性检查所检查。该检查验证如下:
◆一个对话(conversation)必须有两个端点(endpoint)。
◆一个服务必须相关到一个有效的契约
◆一个服务必须相关到一个有效的序列
◆一个消息必须有一个有效的消息类型
这些检查并非DBCC CHECKDB执行,相反,他们被服务代理子系统(代表DBCC CHECKDB)本身执行。如果发现任何错误的一致性,他们报告DBCC CHECKDB一个8997的错误,加上8992交叉目录的一致性检查错误。
2、交叉目录(cross-catalog)一致性检查
在SQL Server2005以前的版本中,CHECKCATALOG什么时候应该被运行以验证各种系统目录之间的关系是一个极易混淆的问题,为此,SQL Server 2005将CHECKCATALOG集成在DBCC CHECKED中。
SQL Server 2005中,关系引擎中的整个元数据子系统被重写,SQL Server 2008进一步补充为一个系统目录一致性检查SQL Server 2000中相应的检查DBCC CHECKDB(代表元数据子系统进行,也可以使用DBCC CHECKCATALOG执行命令)。
这些检查操作仅仅在系统目录上处理关系引擎元数据。
存储引擎元数据系统目录在每表一致性检查期间被检查。在检查的一些例子包括以下内容:
◆对所有元数据,匹配表元数据必须存在
◆计算列中引用的列定义必须存在
◆包括在一个索引定义的所有列必须存在
如果任何一致性检查出错,报给DBCC CHECKED,然后转化为8992错误:
Msg 8992, Level 16, State 1, Line 1
Check Catalog Msg 3853, State 1: Attribute (object_id=1977058079) of row
(object_id=1977058079,column_id=1) in sys.columns does not have a matching row
(object_id=1977058079) in sys.objects.
Msg 8992, Level 16, State 1, Line 1
Check Catalog Msg 3853, State 1: Attribute (object_id=1977058079) of row
(object_id=1977058079,column_id=2) in sys.columns does not have a matching row
(object_id=1977058079) in sys.objects.
注意:这些检查不运行在tempdb数据库
3、索引视图一致性检查
尽管索引视图是数据库中的一个First-class对象,它被存储作为一个带一个聚集索引的内部表,因而它的物理结构在per-table一致性检查时被检查。这些一致性检查并不检查索引视图的内容是否匹配视图定义。
描述索引视图一致性检查最简单的方法是,它使用了索引视图的定义(在系统目录中)来生成一个索引视图的临时副本。然后,它使用查询处理器执行两个实际索引视图和临时索引视图之间的左反半联接。此查询报告实际索引视图任何丢失或额外的行。
在现实中,索引视图的临时副本实际上可能没有完全建立在它的整体--这取决于该查询计划查询处理器在运行时使用的查询。DBCC CHECKDB采用的查询类似于非聚集索引使用深潜交叉检查(deep-dive cross-checking),查询格式:
SELECT <identifying columns of missing rows>
FROM <materialize the view temporarily> tOuter WITH (NOEXPAND)
WHERE NOT EXISTS
(
SELECT 1
FROM <actual view> tInner WITH (INDEX = 1)
WHERE
(
([tInner].<view columns> = [tOuter].<view columns>) OR
([tInner].<view columns> IS NULL AND [tOuter].<view columns> IS NULL)
)
)
UNION ALL
SELECT <identifying columns of extra rows>
FROM <actual view> tOuter WITH (INDEX = 2)
WHERE NOT EXISTS
(
SELECT 1
FROM <materialize the view temporarily> tInner WITH (NOEXPAND)
WHERE
(
([tInner].<view columns> = [tOuter].<view columns>) OR
([tInner].<view columns> IS NULL AND [tOuter].<view columns> IS NULL)
)
)
在查询中使用的NOEXPAND提示指示查询处理器执行索引视图扫描,而不是扩展到它的各个组成部分。索引视图中的任何额外的行被报为8907错误,丢失行则报8908错误。
这个检查非常耗时和耗空间。索引视图定义越复杂,它被定义的表就越大,具体化一个索引视图的临时副本花费时间更长,越可能在tempdb占用更多的空间。该检查SQL Server2008默认不执行,必须使用extended_logical_checks选项才能启用。
4、XML索引一致性检查
一个primary的XML索引被存储为一个带聚集索引的内表。一个secondary的XML索引被作为primary XML索引内表的一个非聚集索引存储。一致性检查必须验证XML索引包含用户表的XML值的一个精确的碎片代表。
这种机制类似于索引视图一致性检查,并且可以类似查询样式的可视化,即使T-SQL查询并没有使用。在此情况下,两个左反半联接可以被看作是实际的XML索引和一个XML索引子系统产生的XML索引的临时副本。
XML索引的任何额外的行被报8907错误,丢失行则会报8908错误。
这个检查运行成本非常高。XML架构越复杂,XML列值越大,生成XML索引的临时副本花费的时间更长,越有可能在tempdb中占用更多的空间。该检查SQL Server2008默认不执行,必须使用extended_logical_checks选项才能启用。
5、空间索引(spatial-index)一致性检查
一个空间索引被存储为一个带聚集索引的内表。一致性检查必须验证空间索引包含用户表的空间值的一个精确的碎片代表。
这种机制类似于索引视图一致性检查,并且可以类似查询样式的可视化,即使T-SQL查询并没有使用。在此情况下,两个左反半联接可以被看作是实际的空间索引和一个空间索引子系统产生的空间索引的临时副本。
空间索引的任何额外的行被报8907错误,丢失行则会报8908错误。
这个检查可能是耗时和耗空间的,这取决于空间索引如何被定义。在每个索引边界盒内部的每个Grid级别的分解的单元格的数量越高,每空间值存储的匹配grid单元格的数量越高,生成空间索引的临时副本花费的时间更长,越有可能在tempdb中占用更多的空间。该检查SQL Server2008默认不执行,必须使用extended_logical_checks选项才能启用。
本文主要介绍了交叉表的一致性检查。下文将介绍DBCC CHECKED Output