如何在大型的并且有表分区的数据库中进行DBCC CHECKDB操作

JavaScript08

如何在大型的并且有表分区的数据库中进行DBCC CHECKDB操作,第1张

很多时候你或者因为性能问题而使用表分区技术,将一些数据放到不同的分区,而这些数据实际上是被逻辑的放到不同的文件组里

大家知道:不管是索引还是数据,文件组都是这些索引和数据存放的最小逻辑单位

文件组是文件的命名集合,用于简化数据存放和管理任务(例如,备份和还原操作,文件组备份和文件组还原)

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 GO3 DBCC CHECKFILEGROUP(1)4 GO

1 partionTest的 DBCC 结果。 2 sys.sysrowsetcolumns的 DBCC 结果。 3 对象 'sys.sysrowsetcolumns' 的 5 页中有 552 行。 4 sys.sysrowsets的 DBCC 结果。 5 对象 'sys.sysrowsets' 的 1 页中有 84 行。 6 sysallocunits的 DBCC 结果。 7 对象 'sysallocunits' 的 1 页中有 95 行。 8 sys.sysfiles1的 DBCC 结果。 9 对象 'sys.sysfiles1' 的 1 页中有 6 行。10 sys.syshobtcolumns的 DBCC 结果。11 对象 'sys.syshobtcolumns' 的 5 页中有 552 行。12 sys.syshobts的 DBCC 结果。13 对象 'sys.syshobts' 的 1 页中有 84 行。14 sys.sysftinds的 DBCC 结果。15 对象 'sys.sysftinds' 的 0 页中有 0 行。16 sys.sysserefs的 DBCC 结果。17 对象 'sys.sysserefs' 的 1 页中有 95 行。18 sys.sysowners的 DBCC 结果。19 对象 'sys.sysowners' 的 1 页中有 14 行。20 sys.sysprivs的 DBCC 结果。21 对象 'sys.sysprivs' 的 1 页中有 120 行。22 sys.sysschobjs的 DBCC 结果。23 对象 'sys.sysschobjs' 的 1 页中有 50 行。24 sys.syscolpars的 DBCC 结果。25 对象 'sys.syscolpars' 的 7 页中有 424 行。26 sys.sysnsobjs的 DBCC 结果。27 对象 'sys.sysnsobjs' 的 1 页中有 1 行。28 sys.syscerts的 DBCC 结果。29 对象 'sys.syscerts' 的 0 页中有 0 行。30 sys.sysxprops的 DBCC 结果。31 对象 'sys.sysxprops' 的 0 页中有 0 行。32 sys.sysscalartypes的 DBCC 结果。33 对象 'sys.sysscalartypes' 的 1 页中有 27 行。34 sys.systypedsubobjs的 DBCC 结果。35 对象 'sys.systypedsubobjs' 的 1 页中有 1 行。36 sys.sysidxstats的 DBCC 结果。37 对象 'sys.sysidxstats' 的 2 页中有 151 行。38 sys.sysiscols的 DBCC 结果。39 对象 'sys.sysiscols' 的 2 页中有 263 行。40 sys.sysbinobjs的 DBCC 结果。41 对象 'sys.sysbinobjs' 的 1 页中有 23 行。42 sys.sysobjvalues的 DBCC 结果。43 对象 'sys.sysobjvalues' 的 24 页中有 151 行。44 sys.sysclsobjs的 DBCC 结果。45 对象 'sys.sysclsobjs' 的 1 页中有 20 行。46 sys.sysrowsetrefs的 DBCC 结果。47 对象 'sys.sysrowsetrefs' 的 1 页中有 4 行。48 sys.sysremsvcbinds的 DBCC 结果。49 对象 'sys.sysremsvcbinds' 的 0 页中有 0 行。50 sys.sysxmitqueue的 DBCC 结果。51 对象 'sys.sysxmitqueue' 的 0 页中有 0 行。52 sys.sysrts的 DBCC 结果。53 对象 'sys.sysrts' 的 1 页中有 1 行。54 sys.sysconvgroup的 DBCC 结果。55 对象 'sys.sysconvgroup' 的 0 页中有 0 行。56 sys.sysdesend的 DBCC 结果。57 对象 'sys.sysdesend' 的 0 页中有 0 行。58 sys.sysdercv的 DBCC 结果。59 对象 'sys.sysdercv' 的 0 页中有 0 行。60 sys.syssingleobjrefs的 DBCC 结果。61 对象 'sys.syssingleobjrefs' 的 1 页中有 138 行。62 sys.sysmultiobjrefs的 DBCC 结果。63 对象 'sys.sysmultiobjrefs' 的 1 页中有 102 行。64 sys.sysdbfiles的 DBCC 结果。65 对象 'sys.sysdbfiles' 的 1 页中有 6 行。66 sys.sysguidrefs的 DBCC 结果。67 对象 'sys.sysguidrefs' 的 1 页中有 4 行。68 sys.sysqnames的 DBCC 结果。69 对象 'sys.sysqnames' 的 1 页中有 91 行。70 sys.sysxmlcomponent的 DBCC 结果。71 对象 'sys.sysxmlcomponent' 的 1 页中有 93 行。72 sys.sysxmlfacet的 DBCC 结果。73 对象 'sys.sysxmlfacet' 的 1 页中有 97 行。74 sys.sysxmlplacement的 DBCC 结果。75 对象 'sys.sysxmlplacement' 的 1 页中有 17 行。76 sys.sysobjkeycrypts的 DBCC 结果。77 对象 'sys.sysobjkeycrypts' 的 0 页中有 0 行。78 sys.sysasymkeys的 DBCC 结果。79 对象 'sys.sysasymkeys' 的 0 页中有 0 行。80 sys.syssqlguides的 DBCC 结果。81 对象 'sys.syssqlguides' 的 0 页中有 0 行。82 sys.sysbinsubobjs的 DBCC 结果。83 对象 'sys.sysbinsubobjs' 的 0 页中有 0 行。84 sys.queue_messages_1977058079的 DBCC 结果。85 对象 'sys.queue_messages_1977058079' 的 0 页中有 0 行。86 sys.queue_messages_2009058193的 DBCC 结果。87 对象 'sys.queue_messages_2009058193' 的 0 页中有 0 行。88 sys.queue_messages_2041058307的 DBCC 结果。89 对象 'sys.queue_messages_2041058307' 的 0 页中有 0 行。90 无法处理对象 "testPartionTable" (ID 2073058421)、索引 "testPartionTable" (ID 0)的行集 ID 72057594038321152,因为它驻留在文件组 "FileGroup001" (ID 2)中,但未选中该文件组。 91 无法处理对象 "testPartionTable" (ID 2073058421)、索引 "testPartionTable" (ID 0)的行集 ID 72057594038386688,因为它驻留在文件组 "FileGroup002" (ID 3)中,但未选中该文件组。 92 无法处理对象 "testPartionTable" (ID 2073058421)、索引 "testPartionTable" (ID 0)的行集 ID 72057594038452224,因为它驻留在文件组 "FileGroup003" (ID 4)中,但未选中该文件组。 93 无法处理对象 "testPartionTable" (ID 2073058421)、索引 "testPartionTable" (ID 0)的行集 ID 72057594038517760,因为它驻留在文件组 "FileGroup004" (ID 5)中,但未选中该文件组。 94 无法处理对象 "aa" (ID 2105058535)、索引 "aa" (ID 0)的行集 ID 72057594038583296,因为它驻留在文件组 "FileGroup001" (ID 2)中,但未选中该文件组。 95 无法处理对象 "rr" (ID 2121058592)、索引 "rr" (ID 0)的行集 ID 72057594038648832,因为它驻留在文件组 "FileGroup001" (ID 2)中,但未选中该文件组。 96 CHECKFILEGROUP 在数据库 'partionTest' 中发现 0 个分配错误和 0 个一致性错误。97 DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

View Code

从结果中可以看到只检查了文件组1里的错误

如果是检查文件组2的话就用下面的SQL语句,将1改为2就行了

1 USE [partionTest]2 GO3 DBCC CHECKFILEGROUP(2)4 GO

1 partionTest的 DBCC 结果。 2 sys.sysowners的 DBCC 结果。 3 对象 'sys.sysowners' 的 0 页中有 0 行。 4 sys.sysschobjs的 DBCC 结果。 5 对象 'sys.sysschobjs' 的 0 页中有 0 行。 6 sys.syscolpars的 DBCC 结果。 7 对象 'sys.syscolpars' 的 0 页中有 0 行。 8 sys.sysnsobjs的 DBCC 结果。 9 对象 'sys.sysnsobjs' 的 0 页中有 0 行。10 sys.syscerts的 DBCC 结果。11 对象 'sys.syscerts' 的 0 页中有 0 行。12 sys.sysscalartypes的 DBCC 结果。13 对象 'sys.sysscalartypes' 的 0 页中有 0 行。14 sys.systypedsubobjs的 DBCC 结果。15 对象 'sys.systypedsubobjs' 的 0 页中有 0 行。16 sys.sysidxstats的 DBCC 结果。17 对象 'sys.sysidxstats' 的 0 页中有 0 行。18 sys.sysbinobjs的 DBCC 结果。19 对象 'sys.sysbinobjs' 的 0 页中有 0 行。20 sys.sysclsobjs的 DBCC 结果。21 对象 'sys.sysclsobjs' 的 0 页中有 0 行。22 sys.sysremsvcbinds的 DBCC 结果。23 对象 'sys.sysremsvcbinds' 的 0 页中有 0 行。24 sys.sysrts的 DBCC 结果。25 对象 'sys.sysrts' 的 0 页中有 0 行。26 sys.syssingleobjrefs的 DBCC 结果。27 对象 'sys.syssingleobjrefs' 的 0 页中有 0 行。28 sys.sysmultiobjrefs的 DBCC 结果。29 对象 'sys.sysmultiobjrefs' 的 0 页中有 0 行。30 sys.sysguidrefs的 DBCC 结果。31 对象 'sys.sysguidrefs' 的 0 页中有 0 行。32 sys.sysqnames的 DBCC 结果。33 对象 'sys.sysqnames' 的 0 页中有 0 行。34 sys.sysxmlcomponent的 DBCC 结果。35 对象 'sys.sysxmlcomponent' 的 0 页中有 0 行。36 sys.sysxmlplacement的 DBCC 结果。37 对象 'sys.sysxmlplacement' 的 0 页中有 0 行。38 sys.sysasymkeys的 DBCC 结果。39 对象 'sys.sysasymkeys' 的 0 页中有 0 行。40 sys.syssqlguides的 DBCC 结果。41 对象 'sys.syssqlguides' 的 0 页中有 0 行。42 sys.sysbinsubobjs的 DBCC 结果。43 对象 'sys.sysbinsubobjs' 的 0 页中有 0 行。44 sys.queue_messages_1977058079的 DBCC 结果。45 无法处理对象 "sys.queue_messages_1977058079" (ID 1993058136)、索引 "queue_clustered_index" (ID 1)的行集 ID 72057594037927936,因为它驻留在文件组 "PRIMARY" (ID 1)中,但未选中该文件组。 46 无法处理对象 "sys.queue_messages_1977058079" (ID 1993058136)、索引 "queue_secondary_index" (ID 2)的行集 ID 72057594037993472,因为它驻留在文件组 "PRIMARY" (ID 1)中,但未选中该文件组。 47 对象 'sys.queue_messages_1977058079' 的 0 页中有 0 行。48 sys.queue_messages_2009058193的 DBCC 结果。49 无法处理对象 "sys.queue_messages_2009058193" (ID 2025058250)、索引 "queue_clustered_index" (ID 1)的行集 ID 72057594038059008,因为它驻留在文件组 "PRIMARY" (ID 1)中,但未选中该文件组。 50 无法处理对象 "sys.queue_messages_2009058193" (ID 2025058250)、索引 "queue_secondary_index" (ID 2)的行集 ID 72057594038124544,因为它驻留在文件组 "PRIMARY" (ID 1)中,但未选中该文件组。 51 对象 'sys.queue_messages_2009058193' 的 0 页中有 0 行。52 sys.queue_messages_2041058307的 DBCC 结果。53 无法处理对象 "sys.queue_messages_2041058307" (ID 2057058364)、索引 "queue_clustered_index" (ID 1)的行集 ID 72057594038190080,因为它驻留在文件组 "PRIMARY" (ID 1)中,但未选中该文件组。 54 无法处理对象 "sys.queue_messages_2041058307" (ID 2057058364)、索引 "queue_secondary_index" (ID 2)的行集 ID 72057594038255616,因为它驻留在文件组 "PRIMARY" (ID 1)中,但未选中该文件组。 55 对象 'sys.queue_messages_2041058307' 的 0 页中有 0 行。56 testPartionTable的 DBCC 结果。57 无法处理对象 "testPartionTable" (ID 2073058421)、索引 "testPartionTable" (ID 0)的行集 ID 72057594038386688,因为它驻留在文件组 "FileGroup002" (ID 3)中,但未选中该文件组。 58 无法处理对象 "testPartionTable" (ID 2073058421)、索引 "testPartionTable" (ID 0)的行集 ID 72057594038452224,因为它驻留在文件组 "FileGroup003" (ID 4)中,但未选中该文件组。 59 无法处理对象 "testPartionTable" (ID 2073058421)、索引 "testPartionTable" (ID 0)的行集 ID 72057594038517760,因为它驻留在文件组 "FileGroup004" (ID 5)中,但未选中该文件组。 60 对象 'testPartionTable' 的 2 页中有 126 行。61 aa的 DBCC 结果。62 对象 'aa' 的 0 页中有 0 行。63 rr的 DBCC 结果。64 对象 'rr' 的 0 页中有 0 行。65 CHECKFILEGROUP 在数据库 'partionTest' 中发现 0 个分配错误和 0 个一致性错误。66 DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。

View Code

从结果中可以看到只检查了文件组2里的错误

步骤二:

如果发现文件组1有错误,我们需要使用DBCC CHECKDB来修复错误或者还原文件组备份

1 DBCC CHECKDB([partionTest],REPAIR_ALLOW_DATA_LOSS)

步骤三:设置文件组1为只读文件组

设置文件组1为只读文件组之前需要断开所有对业务数据库的连接

1 USE master2 GO3 ALTER DATABASE [partionTest] SET OFFLINE4 5 --语法6 ALTER DATABASE [partionTest] MODIFY FILEGROUP 文件组名 READONLY7 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,有可能一天都跑不完。这个区别很显著

从徐州到祁门没有查询到可以直达的车次,可通过中转到达的车次如下:

方案1 徐州->马鞍山->祁门(旅行最省钱)

出发车次 徐州发车 到达马鞍山 旅行时间 旅行距离 此区间票价

1708/1705(郑州--杭州) 01:04 08:04 7小时 426 31

中转车次 马鞍山发车 到达祁门 旅行时间 旅行距离 此区间票价

2239(南京西--南昌) 15:23 21:55 6小时32分钟 359 26

方案2 徐州->南京->祁门(旅行时间最短)

出发车次 徐州发车 到达南京 旅行时间 旅行距离 此区间票价

D88/D85(郑州--上海) 10:31 12:55 2小时24分钟 348 107

中转车次 南京西发车 到达祁门 旅行时间 旅行距离 此区间票价

2239(南京西--南昌) 13:18 21:55 8小时37分钟 443 32

方案3 徐州->蚌埠->祁门(旅行距离最短)

出发车次 徐州发车 到达蚌埠 旅行时间 旅行距离 此区间票价

D88/D85(郑州--上海) 10:31 11:34 1小时3分钟 164 50

中转车次 蚌埠发车 到达祁门 旅行时间 旅行距离 此区间票价

2025(蚌埠--厦门) 12:26 22:12 9小时46分钟 584 73

方案4 徐州->南京->祁门

出发车次 徐州发车 到达南京 旅行时间 旅行距离 此区间票价

K58/K55(哈尔滨--上海) 09:22 13:29 4小时7分钟 348 52

中转车次 南京发车 到达祁门 旅行时间 旅行距离 此区间票价

2239(南京西--南昌) 13:41 21:55 8小时14分钟 437 32

方案5 徐州->南京->祁门

出发车次 徐州发车 到达南京 旅行时间 旅行距离 此区间票价

D88/D85(郑州--上海) 10:31 12:55 2小时24分钟 348 107

中转车次 南京发车 到达祁门 旅行时间 旅行距离 此区间票价

2239(南京西--南昌) 13:41 21:55 8小时14分钟 437 32

方案6 徐州->南京->祁门

出发车次 徐州发车 到达南京 旅行时间 旅行距离 此区间票价

K596/K593(乌鲁木齐--南京西) 09:01 13:15 4小时14分钟 348 52

中转车次 南京发车 到达祁门 旅行时间 旅行距离 此区间票价

2239(南京西--南昌) 13:41 21:55 8小时14分钟 437 32

方案7 徐州->南京->祁门

出发车次 徐州发车 到达南京 旅行时间 旅行距离 此区间票价

N466/N467(连云港东--常州) 12:00 16:44 4小时44分钟 348 52

中转车次 南京发车 到达祁门 旅行时间 旅行距离 此区间票价

2182/2183(上海--鹰潭) 17:15 01:35 8小时20分钟 437 32

方案8 徐州->南京->祁门

出发车次 徐州发车 到达南京 旅行时间 旅行距离 此区间票价

N466/N467(连云港东--常州) 12:00 16:44 4小时44分钟 348 52

中转车次 南京南发车 到达祁门 旅行时间 旅行距离 此区间票价

2182/2183(上海--鹰潭) 18:00 01:35 7小时35分钟 404 31

方案9 徐州->蚌埠->祁门

出发车次 徐州发车 到达蚌埠 旅行时间 旅行距离 此区间票价

K258/K255(包头--宁波) 10:12 12:25 2小时13分钟 164 25

中转车次 蚌埠发车 到达祁门 旅行时间 旅行距离 此区间票价

2025(蚌埠--厦门) 12:26 22:12 9小时46分钟 584 73

方案10 徐州->南京->祁门

出发车次 徐州发车 到达南京 旅行时间 旅行距离 此区间票价

D473(徐州--上海) 13:04 15:38 2小时34分钟 348 107

中转车次 南京发车 到达祁门 旅行时间 旅行距离 此区间票价

2182/2183(上海--鹰潭) 17:15 01:35 8小时20分钟 437 32