《Microsoft Sql server 2008 Internals》读书笔记--目录索引
上文主要介绍有效处理数据库的几个方法:事实生成、使用查询处理器。本文关注批处理、读取数据页到进程和并行机制。
■批处理
在per-table逻辑检查期间,DBCC CHECKED通常并不同时处理数据库所有的表,也通常不会在某个时间处理一个单表。它将表分组进批处理(Beatches),并在批处理中的所有表上运行事实生成和聚集算法。所有批处理被处理完后,数据库中的所有表都被一致性检查完毕。
DBCC CHECKED为什么要将数据库分割为一系列的批处理呢?主要是tempdb数据库(为事实存储而)需求的空间数量的限制。每个生成的事实占用一定数量的空间,取决于事实的类型的内容。一个架构越复杂,必须生成(以允许将要被一致性检查的表架构的所有方面)的事实越多。
正如你所想像,对一个非常大的数据库来说,如果数据库所有的表在一个批处理中被进行一致性检查,用来存储所有事实的空间数量很快达到tempdb的可用存储。
批处理中的表集当DBCC CHECKED(在Per-table逻辑检查开始时期)扫描关于表的元数据时被确定。批处理总是至少有一个表(再加上它的非聚集索引),每个批处理的大小被限定于下列规则之一:
◆如果被定义了任何修复选项,生成批处理在它包含一个单表时停止。这会确保修复被正确地排序。
◆当一个表被加到一个批处理,批处理中的所有表的索引的总数达到512个,生成批处理终止。
◆当一个表被加到一个批处理,总的、最坏情况下,tempdb用于批处理中的所有表的所有事实所需的空间达到32MB,生成批处理终止。
一旦批处理生成,事实生成(fact-Generation)和事实聚集(fact-aggregation)算法被在批处理的所有表上运行。当一个批处理完成时,各种deep-dive的算法可能被触发以找到不匹配的文本时间戳值,或不匹配的非聚集索引记录。此时,未经核查的程序集(assemblies)可能也会被清除。如果一个表依赖于一个(用于实现一个CLR用户定义数据类型(UDT)或计算列的)CLR程序集,随后,程序集被使用带有With unchecked Data选项的alter assembly改变,所有依赖于程序集的所有表被在系统目录中标记为有未经核查的程序集。清除这个设置的机制是为了运行DBCC一致性检查时尽可能不影响表。如果没有错误出现,未经检查的程序集设置被清除。
■读取页到进程
事实生成和事实聚集算法的性能部分取决于包含批处理的表和索引的页的事实是否被有效读取。正如之前所说,页并不需要被以任何指定的顺序读取,当所有相关页被读取时,事实被聚集,所有事实生成。
从数据文件中读取页集最快的方式是以allocation order(页在数据文件中的物理顺序)读取。这允许磁头在磁盘间作连续的移动而不是做随机的IOs和经受磁头的长时间过度寻道。
包含批处理的表和索引的页和分区(Extent)被(用于各种表管索引的分配单元的)IAM链跟踪。一旦批处理被生成,所有这些IAM链被合并为一个大的位图(bitmap),它被一个DBCC CHECKED内部的一个扫描对象管理。该位图以已排序的物理顺序设置(包含批处理中的所有平和索引的)所有的页和分区(extent)。
使用该位图,所有必需的页可以被接近连续地读取。扫描对象在页上执行预读(read-ahead),以确信CPU(s)从不等待下个要处理的页被读进缓冲池。预读机制,与存储引擎的其余部分非常类似,只不过,它自逻辑数据文件被创建起被在物理值之间轮询调度。这样做是尽量扩展I/O工作负荷,DBCC CHECKED会处理更多的I/O。
无论何时,下个页需要被处理时,一个调用被转化为扫描对象,返回一个页给调用者。页返回的类型,对象或索引是完全相关的,因为事实生成和聚集算法的天性(nature)。
应该注意到,有时随机I/Os是必需的,因为被读取的页上的某些行可能(因为行溢出内容)有部分(存储在不同页的)行,DBCC CHECKED在内存中实现一个完全的行(除了行外LOB列),它可能调用一个随机的I/O读取行的行溢出部分。
■并行机制
DBCC CHECKED有能力使用多处理器内核并行运行,以更加有效使用系统资源,更快地处理数据库。如果下列条件为真,它可以并行运行当前的批处理:
◆SQL Server实例是企业版、企业评估版、开发版。
◆当前批处理的所有表和索引包含的页大于64个。
◆在批处理中的表中没有基于T-SQL或基于CLR的计算列。
◆并行机制没有(用跟踪标志2528)显式禁用。
如果所有这些条件都为真,DBCC CHECKED发信号给查询处理器:当它遇到内部查询冲突时,可以被并行化。查询处理器最后决定是否使用并行线程。查询处理器基于以下因素决定是否并行化:
◆服务器的MAXDOP设置
◆针对并行的预期的查询成本
◆在批处理的DBCC CHECKED查询被编译用于执行时服务器的可用资源
决定是否并行化内部查询在每次查询冲突时被执行,这意味着DBCC CHECKED一个单个的执行中的不同的批处理可能运行不同的degree of paralleism。
当内部查询运行在并行模式时,数据的概念流程如下:
当内部查询并行运行时,每个并行度(degree of parallelism)的一个线程被创建。在算法的事实生成分配(portion)时期,每个线程负责从扫描对象请示到进程,在每页处理完进程。一个页仅仅被单个线程处理。同时每个线程负责聚集一个隔离的,自包含的事实流(意味着一个对象结构的特殊部分的所有的恰当的事实,必须被设置到一个线程--没有跨线程的事实聚集)。
没有控制哪个线程处理哪个页,因此,组成单个对象的页可能被多个线程处理。这在事实生成期间可能导致问题,如果真的应该被聚集在一起的事实被包含在不同线程的已排序的和已聚集的事实流。因为这个原因,当内部查询并行时,所有的事实(fact)被它们的ROWSET_COLUMN_FACT_KEY元素哈希,通过互换在被排序前传递到per-thread哈希桶。这确保一个对象结构的特殊部分的所有事实被设置到仅仅一个线程。
注意:DBCC CHECKTABLE和DBCC CHECKFILEGROUP命令也能经这种方式使用并行机制。但DBCC CHECKALLOC不可以。
如果确定并行命令设置太大的工作负荷在服务器上,可以在DBCC命令中使用跟踪标志2528以禁用并行。注意这个禁用会花费较长的时间。
为了允许高效的并行机制和可伸缩性而不导致人为瓶颈,DBCC CHECKED内部的所有部分被设计为多线程访问而不引起伸缩性冲突,至少可以并行32个处理器内核。
邀月注:本文版权由邀月和CSDN共同所有,转载请注明出处。
助人等于自助! [email protected]