哈 – 我(不)最喜欢的问题,我问(如我写的DBCC CHECKDB)。
干得好:
只有一次你应该试着弄清楚CHECKDB要花多长时间 – 当你计划你的日常数据库维护时。 如果你面对一个腐败的(或被怀疑是腐败的)数据库,而你刚刚开始考虑CHECKDB要花多长时间 – 在规划灾难恢复策略时,你犯了一个错误。 您总是需要知道CHECKDB需要多长时间(平均)为您的数据库运行:
- 你可以告诉CHECKDB的一个特定的运行是否比平常花费更长的时间 – 这是一个迹象表明它发现了一些腐败
- 您知道要在灾难恢复情况下获得结果需要多长时间
在每次会议上,有人问我CHECKDB将在数据库上运行多久。 有几种方法可以回答这个问题:
- 无益的答案 – 我不知道。
- 几乎有用的答案 – 上次跑步需要多长时间,条件完全相同?
- 我通常给的答案 – 这取决于。
现在,许多人会看到第三个答案,与第一个答案相当 – 无益。 问题是有很多因素会影响CHECKDB运行的时间。 让我来解释十个最重要的因素,让你明白为什么这实际上是一个有用的答案。 这些并不是特别重要的顺序。
- 数据库的大小非常明显… CHECKDB必须读取数据库中每个分配的页面,所以它越大,读取所有页面所需的时间就越长。
- 服务器上的并发IO负载在最简单的级别,CHECKDB要做什么? 它读取数据库中的每个分配的页面。 这是很多的IO。 CHECKDB非常努力的去做最有效率的IO,并以大量的预读来读取数据库页面,使磁盘在磁盘上平滑移动(而不是随机跳转,引起磁头寻道延迟)。 如果服务器上没有并发的IO负载,那么IO将像CHECKDB一样有效。 但是,从SQL Server引入额外的IO意味着磁盘头将会跳转 – 减慢CHECKDB IO。 如果IO子系统已经满足CHECKDB的IO需求,那么任何额外的IO都将减lessCHECKDB可用的IO带宽,从而减慢它的速度。
- 服务器上的并发CPU活动在下一级简单性中,CHECKDB将以某种方式处理它读取的每一页。 根据您指定的各种选项和数据库模式(下面的详细信息),这将使用大量的CPU – 当CHECKDB运行时,服务器可能与100%的CPU挂钩。 如果服务器上有额外的工作负载,那么CHECKDB将会占用CPU周期,并且会减慢速度。 基本上,#2和#3所指的是CHECKDB是非常耗费资源的! 这可能是SQL Server要做的最耗费资源的事情之一,所以在高峰期工作负载时不要运行它通常是一个好主意,因为您不仅会导致CHECKDB花费更长时间运行,还会减慢并发工作量,可能是不可接受的。
- 数据库上的并发更新活动这与SQL 2000和SQL 2005相关,但是由于不同的原因。 在SQL 2000中,CHECKDB从并发DML事务的事务日志分析中获取数据库的一致视图(请参阅这里了解详细信息)。 在CHECKDB正在运行时,并发DML越多,事务日志的生成就越多,因此CHECKDB分析事务日志的时间越长。 在一个大型的多CPU机器上,有一大堆并发的DML和CHECKDB限于一个CPU,CHECKDB的这个阶段可能比读取和处理数据库页面要长好几倍! (我已经多次在实际中看到过)。在SQL 2005中,CHECKDB从数据库快照中获取数据库的一致视图,数据库快照与数据库本身存储在相同的磁盘卷上。 如果CHECKDB正在运行时数据库中有很多更改,则更改后的页面会被推送到快照,以保持一致。 由于快照文件与数据库文件存储在同一位置,因此每次将页面压入快照时,磁头必须移动,这会中断#2中描述的高效IO。 另外,每当CHECKDB读取一个页面,它需要从快照文件而不是数据库文件读取页面,这是另一个磁盘头移动,以及另一个有效的IO中断。 对数据库的并发更改越多,高效IO的中断就越多,CHECKDB运行得越慢。
- IO子系统的吞吐能力这个很简单。 CHECKDB将会执行IO的装载,甚至可能最终成为IO绑定(意味着CPU空闲周期性地等待IO完成),这取决于指定的选项和数据库模式。 这意味着IO子系统的吞吐量将直接影响CHECKDB的运行时间。 所以,如果你有一个1TB的数据库,IO子系统只能pipe理100MB /秒,那么读取数据库需要花费将近3个小时(1TB / 100MB / 3600秒),除此之外,升级IO子系统。 我听说客户抱怨说CHECKDB(或索引重build或其他IO繁忙操作)正在运行,只是发现磁盘队列长度巨大,IO子系统完全无法匹配服务器和工作量。
- 盒子上的CPU数量(处理核心数量)这也确实包含了正在运行的SQL Server版本。 在企业版中,CHECKDB可以在框中的所有CPU上并行运行(或者在查询处理器在编译CHECKDB内部查询时决定并行运行)。 只要数据库也分布在多个文件中(因此IO可以并行化),并行运行可以显着提高CHECKDB的性能并降低运行时间。 有一个漂亮的algorithm可以让CHECKDB并行运行,我将在后面的文章中详细解释。 另一方面,CHECKDB可以在Enterprise Edition中并行运行的事实对于某些场景可能是不利的,所以一些DBAselect强制CHECKDB为单线程。 SAP通常build议这样做,以帮助用户查询可预测性。 这样做的方法是打开logging的跟踪标志2528。
- 放置tempdb的磁盘的速度对VLDB运行CHECKDB对内部状态使用大量内存,对于VLDB,内存要求通常会超过SQL Server可用的内存量。 在这种情况下,状态被转移到tempdb,所以tempdb的性能可能是CHECKDB性能的一个关键因素。 看到这篇文章的更多细节,以及如果tempdb太小,CHECKDB如何可以用尽磁盘空间。
- 数据库模式的复杂性这会对CHECKDB的运行时间产生非常大的影响,因为它会影响CHECKDB所需的CPU数量。 例如,CHECKDB所做的最昂贵的检查是针对非聚簇索引的。 它需要检查非聚簇索引中的每一行是否映射到表的堆或聚簇索引中的一行,并且每个非聚簇索引中的每个堆/聚簇索引行都只有一个匹配行。 尽pipe这样做有一个高效率的algorithm,但CHECKDB仍然占用CPU总数的30%左右! 还有一些其他的检查,只有在数据库中已经使用了这些function的情况下才会执行 – 例如,计算列评估,非行LOB值,Service Broker,XML索引,索引视图之间的链接 – 所以您可以看到,经验因素还不足以确定运行时间。
- 指定了哪些选项这与#7几乎相同,通过指定各种选项来限制CHECKDB实际执行的操作。 例如,使用WITH NOINDEX选项将closures我在#7中描述的非聚集索引检查,并使用WITH PHYSICAL_ONLY选项将closures所有逻辑检查,从而极大地减less了CHECKDB的运行时间,并使其几乎总是IO而不是CPU绑定(事实上,这是VLDB的DBA使用CHECKDB的运行时间可pipe理的最常见的选项)。 有一点需要注意 – 如果指定了任何修复选项,CHECKDB将始终运行单线程,即使在Enterprise Edition的多处理器上也是如此。
- 数据库中存在的腐败的数量和types同样,这与#7和#8类似。 如果存在腐败现象,可能会引发额外的检查,试图弄清腐败的更多细节。 例如,对于非聚集索引检查,对于没有损坏存在的情况(考虑到CHECKDB每天在世界各地运行数百万次的绝大多数情况),该algorithm被非常严重地调整。 当检测到非聚集索引损坏时,必须使用更深入的algorithm来确定损坏的确切位置,这涉及重新扫描一堆数据,从而花费更多时间。 还有其他一些这样的algorithm。
现在还有一件事要记住,使用REPAIR_ALLOW_DATA_LOSS使得检查运行单线程,所以修复得到正确的sorting – 这使得运行时间更长。 在2005 SP2 +的错误日志中查看消息5268 – 如上所述,这表示深入了解。
总结所以你可以看到没有简单的答案。 希望这可以帮助!
PS忘了说,在SQL 2005中,我向DBCC CHECKDB添加了进度报告。 您可以查询sys.dm_exec_requests
DMV并查找percent_complete
列。
这完全取决于数据库的大小(你说47MB),腐败的数量,系统的速度等。我会继续让它运行,直到你得到一个超时或其他错误,只是可以肯定的。 要么,要么恢复已知的好备份,如果有的话。
您也可以启动ProcessExplorer并查看CPU /磁盘使用情况,看看它是否正在做任何事情或“挂断”。
这个答案显然不接近保罗对你的具体问题的真棒回答。
但是,如果您在SharePoint中有一个损坏的search数据库,则在47MB之间进行读取,重置search索引并重新抓取内容可能会比尝试修复search数据库中的任何损坏要快得多。 这里的步骤(KB文章是关于一个不同的问题,但重置search索引/数据库步骤是相同的): http : //support.microsoft.com/kb/948909
确定损坏的根本原因仍然没有什么坏处,并且在您的内容数据库上对CheckDB运行时进行基线,但是search数据库是一个半瞬变实体。 你唯一的打击就是完全爬网(你可能想在非高峰时间运行…这是相当CPU和I / O密集型)。