Sruly Asked: 2009-06-23 04:58:20 +0800 CST2009-06-23 04:58:20 +0800 CST 2009-06-23 04:58:20 +0800 CST 我应该期望带有 REPAIR_ALLOW_DATA_LOSS 的 CheckDB 运行多长时间 772 我在 47mb 的 Shairpoint 搜索数据库上运行带有 REPAIR_ALLOW_DATA_LOSS 的 CheckDB 它已经运行了 > 30 分钟。这正常吗? 需要多长时间? sql-server sharepoint data-recovery checkdb 3 个回答 Voted Best Answer Paul Randal 2009-06-23T06:36:35+08:002009-06-23T06:36:35+08:00 哈 - 我被问到(我写 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 都会减少 CHECKDB 可用的 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 分析该事务日志所需的时间越长。在具有大量并发 DML 和 CHECKDB 的大型多 CPU 机器上,CHECKDB 的这个阶段可能比读取和处理数据库页面花费的时间要长几倍!(我已经在现实生活中多次看到过这种情况。)在 SQL 2005 中,CHECKDB 从数据库快照中获得其一致的数据库视图,该快照存储在与数据库本身相同的磁盘卷上。如果在 CHECKDB 运行时数据库中有大量更改,则将更改的页面推送到快照以保持一致。由于快照文件与数据库文件存储在同一位置,因此每次将页面推送到快照时,磁盘头都必须移动,这会中断#2中描述的高效IO。此外,每当 CHECKDB 去读取一个页面并且它需要从快照文件而不是数据库文件中读取该页面时,这就是另一个磁盘磁头移动和另一个有效的 IO 中断。对数据库的并发更改越多,高效 IO 的中断就越多,CHECKDB 运行的速度就越慢。由于快照文件与数据库文件存储在同一位置,因此每次将页面推送到快照时,磁盘头都必须移动,这会中断#2中描述的高效IO。此外,每当 CHECKDB 去读取一个页面并且它需要从快照文件而不是数据库文件中读取该页面时,这就是另一个磁盘磁头移动和另一个有效的 IO 中断。对数据库的并发更改越多,高效 IO 的中断就越多,CHECKDB 运行的速度就越慢。由于快照文件与数据库文件存储在同一位置,因此每次将页面推送到快照时,磁盘头都必须移动,这会中断#2中描述的高效IO。此外,每当 CHECKDB 去读取一个页面并且它需要从快照文件而不是数据库文件中读取该页面时,这就是另一个磁盘磁头移动和另一个有效的 IO 中断。对数据库的并发更改越多,高效 IO 的中断就越多,CHECKDB 运行的速度就越慢。 IO 子系统的吞吐能力 这个很简单。CHECKDB 将执行大量 IO,甚至最终可能会受到 IO 限制(这意味着 CPU 会定期空闲等待 IO 完成),具体取决于指定的选项和数据库模式。这意味着 IO 子系统的吞吐量将直接影响 CHECKDB 的运行时间。所以,如果你有一个 1TB 的数据库,而 IO 子系统只能管理 100MB/秒,那么读取数据库(1TB / 100MB / 3600 秒)几乎需要 3 个小时,除了升级 IO 子系统。我已经数不清我有多少次了 机箱上的 CPU(处理核心)数量 这也确实包含了正在运行的 SQL Server 版本。在企业版中,CHECKDB 可以在机箱中的所有 CPU 上并行运行(或者在编译 CHECKDB 内部查询时,查询处理器决定并行运行多少)。并行运行可以显着提升 CHECKDB 的性能并缩短运行时间,只要数据库也分布在多个文件中(因此 IO 可以并行化)。使用了一个漂亮的算法,它允许 CHECKDB 并行运行,我将在以后的文章中详细解释。另一方面,CHECKDB 可以在企业版中并行运行这一事实在某些情况下可能会很糟糕,因此一些 DBA 选择强制 CHECKDB 为单线程。SAP 通常建议这样做以帮助提高用户查询的可预测性。 放置 tempdb 的磁盘的速度 针对 VLDB 运行 CHECKDB 会使用大量内存用于内部状态,而对于 VLDB,内存需求通常超过 SQL Server 可用的内存量。在这种情况下,状态被假脱机到 tempdb,因此 tempdb 的性能可能是 CHECKDB 性能的关键因素。有关这方面的更多详细信息,以及如果 tempdb 太小,CHECKDB 如何耗尽磁盘空间,请参阅这篇文章。 数据库模式的复杂性 这会对 CHECKDB 的运行时间产生非常大的影响,因为它会影响 CHECKDB 所需的 CPU 数量。例如,CHECKDB 所做的最昂贵的检查是针对非聚集索引。它需要检查非聚集索引中的每一行是否映射到表的堆或聚集索引中的一行,并且每个堆/聚集索引行在每个非聚集索引中都有一个匹配的行。尽管有一种高效的算法来执行此操作,但它仍然占用 CHECKDB 使用的总 CPU 的 30% 左右!只有在数据库中使用了这些特性时,才会进行许多其他检查——例如计算列评估、行外 LOB 值之间的链接、服务代理、XML 索引、索引视图——所以你可以看到经验因素沿着' 指定了哪些选项 这与 #7 几乎相同,因为通过指定各种选项,您可以限制 CHECKDB 实际执行的检查。例如,使用 WITH NOINDEX 选项将关闭我在 #7 中描述的非聚集索引检查,使用 WITH PHYSICAL_ONLY 选项将关闭所有逻辑检查,大大减少 CHECKDB 的运行时间并使其几乎总是 IO -bound 而不是 CPU-bound(事实上,这是 VLDB 的 DBA 用来使 CHECKDB 的运行时间易于管理的最常见选项)。需要注意的一件事 - 如果您指定任何修复选项,CHECKDB 始终运行单线程,即使在企业版的多进程机器上也是如此。 数据库中存在的损坏的数量和类型 同样,这类似于 #7 和 #8。如果存在任何损坏,可能会触发额外的检查以尝试找出损坏的更多详细信息。例如,对于非聚集索引检查,算法针对不存在损坏的情况进行了非常大的调整(考虑到全球每天运行数百万次 CHECKDB 的绝大多数情况)。当检测到非聚集索引损坏时,必须使用更深入的算法来确定损坏的确切位置,这涉及重新扫描一堆数据,因此需要更多时间。还有一些其他类似的算法。 现在要记住的另一件事是,使用 REPAIR_ALLOW_DATA_LOSS 使检查运行单线程,因此修复得到正确排序 - 这使其运行时间更长。查看 2005 SP2+ 上的错误日志中的 5268 消息 - 正如我上面提到的,它表示深入研究。 总结 所以你可以看到没有简单的答案。希望这可以帮助! PS 忘了说在 SQL 2005 中我向 DBCC CHECKDB 添加了进度报告。您可以查询sys.dm_exec_requestsDMV 并查找该percent_complete列。 Dave Drager 2009-06-23T05:24:11+08:002009-06-23T05:24:11+08:00 这完全取决于数据库的大小(你说 47MB)、损坏的数量、系统的速度等。我会继续让它运行,直到你得到一个超时或其他错误,只是为了确定。要么,要么恢复一个已知良好的备份,如果你有的话。 您还可以启动ProcessExplorer并查看 CPU/磁盘使用情况,看看它是否真的在做任何事情或“挂断”。 Sean Earp 2009-06-23T18:01:26+08:002009-06-23T18:01:26+08:00 这个答案显然与保罗对您的具体问题的出色回答并不相近。 但是,如果您在 SharePoint 中有一个损坏的搜索数据库(47MB),那么在两行之间进行读取可能会比尝试修复搜索数据库中的任何损坏更快地重置搜索索引并重新抓取内容. 这里的步骤(知识库文章是关于不同的问题,但重置搜索索引/数据库的步骤是相同的):http: //support.microsoft.com/kb/948909 找出损坏的根本原因并在内容数据库上设置 CheckDB 运行时的基准仍然没有什么坏处,但搜索数据库本身就是一个半瞬态实体。您唯一的打击将是完全爬网(您可能希望在非高峰时间运行......它非常占用 CPU 和 I/O)。
哈 - 我被问到(我写 DBCC CHECKDB 时)我最喜欢的(非)问题。
干得好:
只有一次您应该尝试计算一个 CHECKDB 需要多长时间 - 当您计划您的定期数据库维护时。如果您面临一个损坏(或疑似损坏)的数据库,并且您才刚刚开始考虑 CHECKDB 需要多长时间 - 您在规划灾难恢复策略时犯了一个错误。您总是需要知道 CHECKDB 需要多长时间(平均)为您的数据库运行,所以:
在我参加的每次会议上,都会有人问我 CHECKDB 在他们的数据库上运行需要多长时间。我有几种方法可以回答这个问题:
现在,许多人会认为第三个答案在某种程度上等同于第一个答案——没有帮助。问题是有许多因素会影响 CHECKDB 运行的时间。让我解释十个最重要的因素,以便您了解为什么这实际上是一个有用的答案。这些没有任何特定的重要性顺序。
现在要记住的另一件事是,使用 REPAIR_ALLOW_DATA_LOSS 使检查运行单线程,因此修复得到正确排序 - 这使其运行时间更长。查看 2005 SP2+ 上的错误日志中的 5268 消息 - 正如我上面提到的,它表示深入研究。
总结 所以你可以看到没有简单的答案。希望这可以帮助!
PS 忘了说在 SQL 2005 中我向 DBCC CHECKDB 添加了进度报告。您可以查询
sys.dm_exec_requests
DMV 并查找该percent_complete
列。这完全取决于数据库的大小(你说 47MB)、损坏的数量、系统的速度等。我会继续让它运行,直到你得到一个超时或其他错误,只是为了确定。要么,要么恢复一个已知良好的备份,如果你有的话。
您还可以启动ProcessExplorer并查看 CPU/磁盘使用情况,看看它是否真的在做任何事情或“挂断”。
这个答案显然与保罗对您的具体问题的出色回答并不相近。
但是,如果您在 SharePoint 中有一个损坏的搜索数据库(47MB),那么在两行之间进行读取可能会比尝试修复搜索数据库中的任何损坏更快地重置搜索索引并重新抓取内容. 这里的步骤(知识库文章是关于不同的问题,但重置搜索索引/数据库的步骤是相同的):http: //support.microsoft.com/kb/948909
找出损坏的根本原因并在内容数据库上设置 CheckDB 运行时的基准仍然没有什么坏处,但搜索数据库本身就是一个半瞬态实体。您唯一的打击将是完全爬网(您可能希望在非高峰时间运行......它非常占用 CPU 和 I/O)。