如何在大型的并且有表分区的数据库中进行DBCC CHECKDB操作
其实这个问题已经在《SQLSERVER企业级平台管理实践》里徐老师已经讲过了,不过我想用自己的语言再讲详细一些
笔记链接:笔记19-徐 如何在超大型数据库上运行DBCC CHECKDB
先来看一下表分区的概念图
很多时候你或者因为性能问题而使用表分区技术,将一些数据放到不同的分区,而这些数据实际上是被逻辑的放到不同的文件组里
大家知道:不管是索引还是数据,文件组都是这些索引和数据存放的最小逻辑单位
文件组是文件的命名集合,用于简化数据存放和管理任务(例如,备份和还原操作,文件组备份和文件组还原)
MSDN 使用文件和文件组 :http://msdn.microsoft.com/zh-cn/library/ms187087(v=sql.90).aspx
那么假如我有一个表使用了表分区技术,如下图
表中索引和数据放在这3个文件组中,其中历史数据/归档数据放在文件组1,索引放在文件组2,当前数据放在文件组3
当然,真实环境中的大型数据库会有更多的文件组用来存放不同的历史数据和索引!!
对于使用了分区表机制的数据库,对于存储历史数据的分区文件组,由于数据本身已经不会发生修改,我们可以把文件组类型设成只读模式,
防止任何误修改。
步骤一:
我们可以对文件组1进行一次DBCC CHECKFILEGROUP检查,如果没有错误,就将文件组1设置为只读,
这样以后就不用再执行DBCC CHECKFILEGROUP检查了,因为文件组1是只读的,不会再对它进行修改
我们使用下面SQL语句检查文件组1是否有错误
1 USE [partionTest]
2 GO
3 DBCC CHECKFILEGROUP(1)
4 GO
从结果中可以看到只检查了文件组1里的错误
如果是检查文件组2的话就用下面的SQL语句,将1改为2就行了
1 USE [partionTest]
2 GO
3 DBCC CHECKFILEGROUP(2)
4 GO
从结果中可以看到只检查了文件组2里的错误
步骤二:
如果发现文件组1有错误,我们需要使用DBCC CHECKDB来修复错误或者还原文件组备份
1 DBCC CHECKDB([partionTest],REPAIR_ALLOW_DATA_LOSS)
步骤三:设置文件组1为只读文件组
设置文件组1为只读文件组之前需要断开所有对业务数据库的连接
1 USE master
2 GO
3 ALTER DATABASE [partionTest] SET OFFLINE
4
5 --语法
6 ALTER DATABASE [partionTest] MODIFY FILEGROUP 文件组名 READONLY
7
8 ALTER DATABASE [partionTest] MODIFY FILEGROUP FileGroup001 READONLY
步骤四:对于存储当前的数据的分区文件组(不是历史数据),每个星期或者一星期两次的DBCC CHECKFILEGROUP即可
因为表中的索引和表中的现有数据是随时变化的,今年2013年还没有过完,所以文件组3中的数据和文件组2中的索引肯定会变化的
这个只能定期做DBCC CHECKFILEGROUP了
小结:
对于大型数据库,SQLSERVER针对是否使用了多个文件组的数据库提供了比较灵活的DBCC CHECKDB的方法
如果使用了多个文件组,就使用DBCC CHECKFILEGROUP
注意:这里除了表分区会用到多个文件组之外,不用表分区也可以使用多个文件组,在创建表的时候或者创建索引的时候
可以指定表和索引建立在哪个文件组上!!
没有使用表分区技术的数据库或者只有一个默认文件组的数据库
可以使用下面几个语句把DBCC CHECKDB里的关键任务分解在每天运行
周一到周三:每天运行一组,假如32张GPOSDB表,32/3=10张表/每天
1 DBCC CHECKTABLE()
周四: DBCC CHECKALLOC(gposdb) + 一组 DBCC CHECKTABLE()
1 DBCC CHECKALLOC(gposdb)
2 DBCC CHECKTABLE()
周五周六:每天运行一组 DBCC CHECKTABLE()
1 DBCC CHECKTABLE()
周日: DBCC CHECKALLOC(gposdb) + DBCC CHECKCATALOG(gposdb) + 一组DBCC CHECKTABLE()
1 DBCC CHECKALLOC(gposdb)
2 DBCC CHECKCATALOG(gposdb)
3 DBCC CHECKTABLE()
SQLSERVER提供给大家的一些DBCC CHECKDB选项
并行检查对象
若要限制DBCC检查可使用的处理器的最大数目,请使用
1 EXEC sys.sp_configure @configname = 'max degree of parallelism', -- varchar(35)
2 @configvalue = 0 -- int
使用跟踪标识 /T 2528 可以禁用并行检查
PHYSICAL ONLY
对大表使用physical_only可以节省时间,检查索引,noindex可以让SQL不用去做费事费力的
非聚集索引检查
1 DBCC CHECKDB(GPOSDB,NOINDEX) WITH physical_only
除了DBCC CHECKDB之外,DBCC CHECKFILEGROUP和DBCC CHECKTABLE也有PHYSICAL ONLY和noindex选项
详细的可以看msdn
CHECKFILEGROUP:http://msdn.microsoft.com/zh-cn/library/ms187332.aspx
CHECKTABLE:http://msdn.microsoft.com/zh-cn/library/ms174338(v=sql.105).aspx
CHECKCATALOG:http://msdn.microsoft.com/zh-cn/library/ms186720(v=sql.105).aspx
CHECKALLOC:http://msdn.microsoft.com/zh-cn/library/ms188422(v=sql.90).aspx
总结
个人感觉其实SQLSERVER的东西挺灵活的,提供的选项也比较多,关键是你怎麽去用,你知道他内部的一些原理有多少
就像DBCC CHECKDB这个简单的命令其实也可以做得很灵活,一些不会用的人对于大型数据库随便
执行DBCC CHECKDB,结果就是无限期的等待
就像徐老师在《SQLSERVER企业级平台管理实践》里说的
根据2009年的经验,一个大于1TB的数据库如果没有错误,CHECKDB在某些机器上用20小时就能够跑完
,而一个有上百上千错误的数据库,哪怕只有两三百GB,有可能一天都跑不完。这个区别很显著