SQL Server 2000中包含了数据库维护计划向导,它可以为你自动完成所有的维护任务。然而,你需要了解,在现场和你的维护计划后面,什么是隐藏的可能给你带来麻烦的东西。
数据库维护计划是通过一系列的DBCC命令和系统存储过程实现的。DBCC的意思是数据库一致性检测(database consistency check)或者数据库控制台命令(database console command)。有非常多的写入文档的和没有写入文档的DBCC命令,但是只有一小部分可以用于维护。这里我将回顾一些与数据库维护的各个方面相关的DBCC命令和系统存储过程。
通常的数据库维护时间表都具有如下的活动。点击活动,可以获得与此相关的DBCC命令和系统存储过程。
1、检测数据库一致性和数据的完整性
DBCC CHECKDB是最广泛使用的,检测数据库中所有对象的工具。这个语句可以为每一个表和索引视图,以及文本和图像对象,检测所有的数据和索引页面的分配和结构上的完整性。DBCC CHECKDB保证了所有的数据和索引页面都正确链接,并且指针都是一致的。在指定的数据库中,用户和系统表都会被检测到。DBCC CHECKDB对数据库中每个对象都都执行DBCC CHECKALLOC和 DBCC CHECKTABLE语句,所以如果你使用DBCC CHECKDB,你就不需要再执行DBCC CHECKALLOC和DBCC CHECKTABLE了。
DBCC CHECKDB的某些选项(REPAIR_FAST, REPAIR_REBUILD 和 REPAIR_ALLOW_DATA_LOSS)需要数据库在单用户的模式下运行。如果不是单用户模式的化,语句就失败了。注意,当用户连接在上面的时候,不要将数据库设置成单用户模式。
如果你执行不带参数的DBCC CHECKDB并且发现错误的时候,你应该将你的数据库设置在单用户模式,然后尝试修复这个问题。首先,确保执行那些不会导致数据丢失的语句——REPAIR_FAST 和 REPAIR_REBUILD。如果你还是遇到错误,那么执行DBCC CHECKDB,带着参数REPAIR_ALLOW_DATA_LOSS。还要确保在显性事务中关闭语句。如果发生了可接受的数据丢失,你可以提交这个事务。否则,你还可以通过语句来回滚所作的修改。
请注意,运行DBCC CHECKDB是一项非常消耗资源的操作。你应该在限制用户在数据库服务器上的活动的时候运行这个语句。
DBCC CHECKTABLE与DBCC CHECKDB相同,除了它是在一个单个的表、索引视图或者即使是一个索引上,而不是在整个数据库上。
DBCC CHECKALLOC检测某个数据库的磁盘空间分配结构的一致性。因为DBCC CHECKDB包括了与DBCC CHECKALLOC同样的检测,那么如果执行了CHECKDB的话就没有必要再执行DBCC CHECKALLOC了。实际上,我们推荐只使用DBCC CHECKALLOC,如果用DBCC CHECKDB或者 DBCC CHECKTABLE会报告说产生分配错误的话。
DBCC CHECKCONSTRAINTS在某个数据库中,检测某些特定的约束或者全部约束的一致性。DBCC CHECKCONSTRAINTS总是在当前数据库的上下文环境中执行。
注意,DBCC CHECKCONSTRAINTS并不进行磁盘或者文件级别的一致性检测;它只是确保外键定义的一致性,同时检测约束——仅仅是确认数据有效。如果你希望检测磁盘上表和索引的一致性,你应该执行DBCC CHECKDB或者在所有的表上执行DBCC CHECKALLOC和 DBCC CHECKTABLE的组合。
首先,为什么会发生约束违规?当数据库创建的时候,外键和一致性检测也许并不存在。开发人员和数据库管理员也许使用了WITH NOCHECK选项来创建约束,这个选项只能防止约束违规的进一步扩展,而不是会检测已经存在的数据。更进一步的说,通过外键链接的数据可能会过期并且从母表中删除,但是仍然会留在相关的表中,因为它在下级表中仍然具有相关记录。
DBCC CHECKCATALOG在某个数据库的系统表内或者之间检测一致性。很多类似DBCC CHECKCONSTRAINTS的命令都不会检测页面分配的一致性;它只是检测系统表中的数据。DBCC CHECKCATALOG报告错误意味着有些人手工从系统表中添加、修改或者删除记录了。如果你没有注意此类活动,那么你应该看紧你的安全措施了——看看谁具有系统管理员和数据库主任的全县,然后评估你的安全策略。
2、重建索引
当数据行从表中INSERTED, UPDATED and DELETED的时候,索引就产生了碎片。碎片越多,索引的效率越低。数据库管理员必需确保碎片的级别很低或者根本不存在。碎片级别可以通过在某个索引上执行DBCC SHOWCONTIG语句来找到。
这里有三种方法可以去掉碎片:
1、 使用CREATE INDEX……WITH DROP EXISTING语句来删除并重新创建索引
2、 执行DBCC DBREINDEX
3、 执行DBCC INDEXDEFRAG
DBCC DBREINDEX重新构建一个特定的索引或者某个特定的表上的所有的索引。这个语句允许强制PRIMARY KEY和UNIQUE约束的索引重新构建,而不需要删除约束。你不需要知道索引的类别和名称,你同样可以使用。使用DBCC DBREINDEX比单独为表上的每个索引编写DROP INDEX 和CREATE INDEX语句简单。时刻记住,重新构建聚簇索引也会引起非聚簇索引的重建。
DBCC INDEXDEFRAG可以删除某个聚簇索引或者非聚簇索引的碎片。与DBCC DBREINDEX不同,这个语句需要指定某个特别的索引,并且不能运行在表上所有索引上。删除碎片也是一项在线操作,因此不会妨碍用户对表进行操作。DBCC INDEXDEFRAG给系统增加了额外的负担,因为它产生了额外的I/O负担。它还会影响到索引页面,并且会在压缩之后删除所有遗留的没有数据的页面。
删除碎片的频率依赖于在你的数据库中,数据修改的级别。需要每天处理几百万个事务的系统应该至少每个星期都进行一次索引重建。另一方面,在几乎没有修改的数据库上,即使你每个月进行一次索引重建,数据库都会运行得不错。
2、重建索引
当数据行从表中INSERTED, UPDATED and DELETED的时候,索引就产生了碎片。碎片越多,索引的效率越低。数据库管理员必需确保碎片的级别很低或者根本不存在。碎片级别可以通过在某个索引上执行DBCC SHOWCONTIG语句来找到。
这里有三种方法可以去掉碎片:
1、 使用CREATE INDEX……WITH DROP EXISTING语句来删除并重新创建索引
2、 执行DBCC DBREINDEX
3、 执行DBCC INDEXDEFRAG
DBCC DBREINDEX重新构建一个特定的索引或者某个特定的表上的所有的索引。这个语句允许强制PRIMARY KEY和UNIQUE约束的索引重新构建,而不需要删除约束。你不需要知道索引的类别和名称,你同样可以使用。使用DBCC DBREINDEX比单独为表上的每个索引编写DROP INDEX 和CREATE INDEX语句简单。时刻记住,重新构建聚簇索引也会引起非聚簇索引的重建。
DBCC INDEXDEFRAG可以删除某个聚簇索引或者非聚簇索引的碎片。与DBCC DBREINDEX不同,这个语句需要指定某个特别的索引,并且不能运行在表上所有索引上。删除碎片也是一项在线操作,因此不会妨碍用户对表进行操作。DBCC INDEXDEFRAG给系统增加了额外的负担,因为它产生了额外的I/O负担。它还会影响到索引页面,并且会在压缩之后删除所有遗留的没有数据的页面。
删除碎片的频率依赖于在你的数据库中,数据修改的级别。需要每天处理几百万个事务的系统应该至少每个星期都进行一次索引重建。另一方面,在几乎没有修改的数据库上,即使你每个月进行一次索引重建,数据库都会运行得不错。