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

《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数据库的一致性时,头脑中的第一反应该是“DBCC”。在SQL Server 7.0中,DBCC代表数据库一致性检查,但在随后版本,SQL Server 2000中,微软改变了定义,它变成了数据库控制台命令。这也折射出一个事实:DBCC命令已经远远超出一致性检查的范围。

尽管SQL Server本身不会引起数据库损坏(corruption)。但是I/O子系统(所有的在SQL Server缓冲池和磁盘驱动的金属氧化物metal oxide)确实会引起压倒性的多数corruption。(为此),一个常见的妙招是预先执行常规的一致性检查因为所有的数据库服务器都有某种排序的I/O子系统。通常地说,一周执行一次一致性检查是可接受的。

一致性检查是检验数据库的物理和逻辑结构的进程,它的目的是确保没有损坏而阻止存储引擎能处理数据库的其他部分或可能导致某些不正确的行为,例如:

◆一个持久的计算列中的持久值的位置已经损坏,以致于它不再匹配计算的结果。

◆一个(页头部的)Page ID所在的数据页位置破损。

◆一个记录的键顺序所在位置的索引损坏。

在SQL Server7.0时代已经正式推出一致性检查,该版本中它们被用于运行离线操作(也就是说,表锁被请求)时。SQL Server 2000中,一致性检查默认在线运行,这是一种新的高效的扫描数据库的机制。在SQL Server2005中,存储引擎内部的一致性检查和修复代码显著重写和增强。SQL Server2008增加了新的功能,更进一步调整了性能和伸缩性。

在某个数据库中执行性能一致性检查的最广泛的方法是使用DBCC CHECKDB,详细用法,请参考:http://technet.microsoft.com/zh-cn/library/ms176064.aspx

MSDN注释:在 SQL Server 的早期版本中,用于每个表、每个索引行计数和页计数的值可能不正确。在特定情况下,其中的一个或多个值甚至会变为负值。在 SQL Server 2005 及更高版本中,这些值始终会得到正确的维护。因此,在 SQL Server 2005 及更高版本中创建的数据库绝不会包含错误的计数;但是升级到 SQL Server 2005 及更高版本的数据库则可能包含错误的计数。这不是数据库中存储的任何数据的损坏。DBCC CHECKDB 已得到增强,可以检测计数值之一变为负值这一情况。 

DBCC CHECKDB的主要步骤如下:
1、创建一个事务级的完整的、静态数据库视图。

2、执行关键系统分类的low-level的一致性检查。

3、执行分配数据库的一致性检查。

4、执行数据库中每个表的一致性检查。

5、前面步骤没有发现错误,下列跨表一致性检查被执行:
◆执行service broker 元数据的一致性检查。

◆执行各种系统分类(catalog)之间的一致性检查。

◆执行索引视图的一致性检查。

◆执行XML索引的一致性检查。

◆执行空间索引的一致性检查。 

6、输出结果

在本章中,我们将

1、基于上面的六步,了解SQL Server 2008中DBCC CHECKDB工作的内幕

2、对于每一个能被定义的选项,将如何影响DBCC CHECKDB行为。

3、如何修复工作和关于其他的DBCC一致性检查命令。

得到一个数据库的持久视图

一个数据库的持久视图是必须的,因为DBCC CHECKDB必须分析数据库的所有分配页,检查multiple  pages中的各个结构之间的链接。这意味着被分析的(整个数据库的)页,在一致性检查正在运行时,不能改变。否则DBCC CHECKED报告各种不正确的结果。由于DBCC CHECKDB命令瞬时不能读取数据库中的所有已分配页,因此,数据库的持久视图必须被持续到一致性检查结束。另外,数据库被简单冻结一段时间也不充分,数据库的持久视图也必须是事务级的完整,以使在DBCC CHECKDB命令看到的视图有未完成的改变。

这里有一个例子:考虑插入一条记录到一个有非聚集索引的表,同时假定一致性检查的进程在运行,却没有强制数据库的一个持久视图。查询处理器工作的方式是首先插入表记录,接着插入匹配非聚集索引记录。因为这个假定的一致性检查进程没有持久性视图,它可能读取表记录而没有读取非聚集索引,结果导致一个非聚集索引没有和表同步的报告。

这是如何发生的?后面我们会讲到。DBCC CHECKDB以某种特定顺序读取数据库页,以改善性能。使用这个机制,这个例子继续,它可能在非聚集索引记录被插入前读取非聚集索引页,也可能在表记录被插入后读取表页。它可能得出结论有损坏存在。实际上,问题是它看到了一个内部冲突事务的局部结果。

获取一个持久视图

在SQL Server7.0中,事务级的持久视图通过锁定在各个在数据库中不同的级别而被获取。这对工作负载性能是非常有害的。因此。SQL Server2000推出在线一致性检查,不再需要阻塞锁。DBCC CHECKED在扫描数据库后分析事务日志,必要时运行数据库内部视图的恢复,这样,产生了一个事务级的数据库持久视图。

因为种种原因,SQL Server2000解决方案是笨拙而难于驾驭的,因此在SQL Server2005中它被数据库快照取代。在SQL Server2008中使用相同的机制。这大大降低了复杂性。

在第三章中已经提到,数据库快照非常节省空间。仅仅包含自快照被创建起发生改变的数据库页。数据库快照内容的组合和数据库中未变化的页给出了一个未改变的,事务级的数据库持久视图。

这正是DBCC CHECKDB需要在线运行的准确原因。创建一个数据库快照,运行数据库快照上的一致性检查运算与运行在数据库的只读副本的一致性检查运算概念上是一样的。

DBCC CHECKDB创建一个不能被用户访问的数据库快照,它必须隐藏。这个隐藏的数据库快照与常规数据库快照有一些细小的差异。常规快照对应源数据库的每个数据文件仅有一个快照文件,每个文件必须在数据库快照被创建时显式命名。DBCC CHECKDB不允许任何用户为隐藏的数据库快照输入指定的文件名,而是为每个已经存在的数据库数据文件创建一个NTFS替代流。你可以把这个快照看成是一个文件系统的隐含文件。

磁盘空间冲突

有时在隐藏的数据库快照运行空间耗尽而产生一个冲突。因为使用已存在有的数据文件的替代流而实现的,数据库快照在数据文件相同的位置使用空间。如果数据库被检查时有一个重的工作负载,越来越多的页被被推进数据库快照,使它快速增长。此时,数据库所在的卷,如果没有足够的空间,那么快照没有空间可用,DBCC CHECKDB出错而停止。

这种情况下的解决方案是创建自己的数据库快照。放在一个有足够空间的卷,然后再运行DBCC CHECKDB,此时,DBCC CHECKDB识别已经在运行的数据库快照,并不会试图创建新快照。

如果一个快照被DBCC CHECKED创建,一旦一致性检查运算完成,它将被自动丢弃。

在创建数据库快照的同时(如果必需),Filestream 垃圾回收器进程在DBCC CHECKDB运行时被挂起,这允许一致性检查运算看到任何File Stram数据容器的一个FileStream数据的事务级持久视图。这在本章后面还有介绍。

使用数据库快照的替代方案

在下列条件下不需要数据库快照:

◆定义的数据库是一个数据库快照自身

◆定义的数据库是只读的,单用户模式或合并模式

◆服务以-m命令行选项在单用户模式启动

在以上情况下,数据库已经必须是完整的,因为没有其他活动连接做出破坏一致性检查的变化。

在下列条件下不能创建数据库快照:

◆定义的数据库被存储在一个非NTFS文件系统(此时,数据库快照不能被创建因为它依赖NTFS稀疏文件技术)

◆定义的数据库是tempdb(tempdb不能创建数据库快照)

◆TABLock选项被定义

如果因为任何原因数据库快照不能被创建,DBCC CHECKDB试图作用锁来获取一个事务级的数据库持久视图。

首先,它得到一个数据库级的排他锁,以便它能没有变化发生的前提下执行分配一致性检查。这在master数据库是不可能的,也就是说离线一致性检查不能运行在Master上。也不可能在tempdb,即会跳过tempdb(SQL Server2000中也是如此)。这个排他锁不是无限期的,DBCC CHECKDB等待20秒(或会话中配置的锁超时时间)后,报错:

 

DBCC CHECKDB('msdb') with tablock;
go

 

 

如果锁被请求得到,分配检查完成后,排他锁被drop,表级共享锁被请求得到,同时表级的逻辑一致性检查被执行。相同的超时应用到这些表级锁上。

不管怎样,DBCC CHECKDB得到了一个它所检查的数据库的事务级的一致性视图,之后,它能开始处理数据库。

下文将关注有效处理数据库的几个方法:事实生成、使用查询处理器、批处理、读取数据页到进程和并行机制。


posted @ 2010-07-17 00:35  邀月  阅读(2218)  评论(2编辑  收藏  举报