排查 DBCC CHECKDB 报告的数据库一致性错误

本文介绍如何排查命令报告 DBCC CHECKDB 的错误。

原始产品版本:SQL Server
原始 KB 编号: 2015748

症状

执行 DBCC CHECKDB (或类似命令(如 DBCC CHECKTABLE) )时,会将类似于以下的消息写入错误日志SQL Server:

DBCC CHECKDB (mydb) executed by MYDOMAIN\theuser found 15 errors and repaired 3 errors.
Elapsed time: 0 hours 0 minutes 0 seconds.
Internal database snapshot has split point LSN = 00000026:0000089d:0001 and first LSN = 00000026:0000089c:0001.
This is an informational message only. No user action is required.

如果使用修复选项,则此消息显示发现的数据库一致性错误数以及修复了多少错误。 此消息还会作为 EventID=8957 的信息级别消息写入 Windows 应用程序事件日志。 即使报告了错误,此消息也是信息级消息。

消息中的信息以“内部数据库快照...”开头。仅当DBCC CHECKDB联机运行(其中数据库不处于 模式)时显示SINGLE_USER。 这是因为对于联机 DBCC CHECKDB,使用内部数据库快照向检查呈现一组一致的数据。

本文不讨论如何排查报告的每个特定错误, DBCC CHECKDB 而是讨论报告错误时采用的一般方法。 除非另有说明,否则本文中对 CHECKDB 的任何引用也适用于 DBCC CHECKTABLEDBCC CHECKFILEGROUP

原因

命令 DBCC CHECKDB 检查数据库页、行、分配页、索引关系、系统表引用完整性和其他结构检查的物理和逻辑一致性。 如果这些检查中的任何一个失败 (取决于你) 选择的选项,则会报告错误。

这些问题的原因包括文件系统损坏、基础硬件系统问题、驱动程序问题、内存或存储缓存中的页面损坏或SQL Server问题。 有关如何确定报告错误的根本原因的信息,请参阅 调查根本原因

解决方案

  1. 在继续还原备份或以其他方式修复数据库之前,请先解决系统上与硬件相关的任何基础问题。 应用与 I/O 路径相关的任何设备驱动程序、固件、BIOS 和操作系统更新。 请与完整 I/O 路径 (本地计算机、设备驱动程序、存储 NIC、SAN、后端存储和缓存) 管理员协作,以隔离并解决任何问题。 示例包括更新设备驱动程序和检查整个 I/O 路径的配置。 有关检查根本原因的详细信息,请参阅 调查根本原因

  2. 如果 DBCC CHECKDB 报告永久一致性错误,则最佳解决方案是从已知良好的备份还原数据。 有关详细信息,请参阅 还原和恢复

  3. 应用最新的SQL Server累积更新或 Service Pack,以确保不会遇到任何已知问题。 查看 累积更新或 Service Pack 文档 ,了解与数据库损坏 (一致性错误) 修复的任何已知问题,并应用任何相关的修补程序。 如果详细修补程序列出了 2022、2019、2017 SQL Server,则可以在一个中心位置搜索特定版本的所有修补程序。

  4. DBCC CHECKDB如果错误是间歇性的,也就是说,如果错误出现在一次运行中,然后在下一次运行时消失,则可能会遇到磁盘缓存问题 (设备驱动程序或其他 I/O 路径问题) 。 请与 I/O 路径的维护人员协作,以隔离并解决任何问题。 示例包括更新设备驱动程序、检查整个 I/O 路径的配置,以及更新 I/O 路径设备和系统上的固件和 BIOS。

  5. 如果无法从备份还原, CHECKDB 则具有修复可以使用的错误的功能。 修复有两个级别:

    • REPAIR_REBUILD - 执行不可能发生数据丢失的修复。
    • REPAIR_ALLOW_DATA_LOSS - 执行可能丢失数据的修复。

    有关详细信息,请参阅 DBCC CHECKDB 文档

    在选择修复允许数据丢失时必须谨慎,因为它可能会使数据库处于逻辑不一致状态。 输出 DBCC CHECKDB 会针对要使用的最低修复级别提出建议。 常见的做法是多次运行CHECKDBREPAIR_ALLOW_DATA_LOSS,直到不再报告错误。 这是因为修复修复了一组错误时,可能会发现其他断开的链接。 但是,如果根本原因尚未解决,则可能会显示新的错误。 因此,如果硬件或文件系统等系统级问题导致数据损坏,则必须在还原备份或修复之前先解决这些问题。 如果修复未修复一致性错误或数据库备份损坏,Microsoft 支持工程师无法协助物理恢复损坏的数据。

    运行 DBCC CHECKDB时,会提供一个建议来指示修复所有错误所需的最低修复选项。 这些消息类似于以下输出:

    CHECKDB 在数据库“mydb”中发现了 0 个分配错误和 15 个一致性错误。
    REPAIR_ALLOW_DATA_LOSS 是 (mydb) 找到 DBCC CHECKDB 的错误的最低修复级别。

    修复建议是尝试解决来自 CHECKDB的所有错误的最低修复级别。 最低修复级别并不意味着此修复选项可修复所有错误。 某些错误根本无法修复。 此外,可能需要多次运行修复过程。 并非所有报告的错误都需要使用此修复级别才能解决。 这意味着并非所有修复都CHECKDBREPAIR_ALLOW_DATA_LOSS会导致数据丢失。 必须运行修复来确定错误解决方法是否会导致数据丢失。 帮助缩小每个表的修复级别的方法之一是用于 DBCC CHECKTABLE 报告错误的任何表。 这显示了给定表的最低修复级别。

    警告

    修复或数据导出或导入完成后,必须执行手动数据验证 CHECKDB 。 有关详细信息,请参阅 DBCC CHECKDB 参数。 修复后,数据在逻辑上可能不一致。 例如,修复 (特别是 REPAIR_ALLOW_DATA_LOSS 选项) 可能会删除包含不一致数据的整个数据页。 在这种情况下,与另一个表具有外键关系的表最终可能会出现父表中没有相应主键行的行。

  6. 尝试 编写数据库架构脚本。 使用脚本创建新数据库,然后使用 BCPSSIS 导出/导入向导 等工具将尽可能多的数据从损坏的数据库导出到新数据库。 从损坏的表导出数据可能会失败。 在这种情况下,请跳过此表,转到下一个表,然后保存可以执行的操作。

  7. 查看以下文章,了解由 DBCC CHECKDB 生成的特定错误,并按照 (提供的步骤(如果有任何) )。 下面是一些示例:

调查数据库一致性错误的根本原因

若要确定数据库一致性错误的根本原因,请考虑以下方法:

  • 检查 Windows 系统事件日志中是否存在任何系统级别、驱动程序或磁盘相关的错误,并与硬件制造商合作解决这些错误。
  • 运行硬件制造商为计算机和/或磁盘系统提供的任何诊断。
  • 请与硬件供应商或设备制造商合作,确保:
  • 请考虑在报告一致性错误的数据库所在的驱动器上使用 SQLIOSim 等实用工具。 SQLIOSim 是独立于 SQL Server 引擎的工具,用于测试磁盘系统的 I/O 完整性。 SQLIOSim 附带SQL Server,不需要单独下载。 可以在 \MSSQL\Binn 文件夹中找到它。
  • 查看 累积更新或 Service Pack 文档 ,了解与数据库损坏 (一致性错误) 修复的任何已知问题,并应用任何相关的修补程序。 如果详细修补程序列出了 2022、2019、2017 SQL Server,则可以在一个中心位置搜索特定版本的所有修补程序。
  • 检查SQL Server报告的任何其他错误,例如访问冲突或断言。 针对损坏的数据库的活动经常导致访问冲突异常或断言错误。
  • 请确保数据库使用 PAGE_VERIFY CHECKSUM 选项。 如果报告校验和错误,则表明在SQL Server将页写入磁盘后发生了一致性错误。 因此,应彻底检查 I/O 子系统。 有关校验和错误的详细信息,请参阅如何排查 SQL Server 中的 Msg 824 问题。
  • 在 ERRORLOG 中查找消息 832 错误。 这些错误可能表明,在写入磁盘之前,页在缓存中时可能已损坏。 有关详细信息,请参阅如何对 SQL Server 中的 Msg 832 进行故障排除
  • 在另一个系统上,尝试还原已知“干净”的数据库备份, () CHECKDB 后跟跨越错误生成时间的事务日志备份。 如果可以通过还原“干净”数据库备份和事务日志备份来“重新创建”此问题,请联系 Microsoft 技术支持获取帮助。
  • 应用程序将无效数据插入或更新到SQL Server表中时,数据纯度错误可能是一个问题。 有关排查数据纯度错误的详细信息,请参阅排查 SQL Server 2005 中的 DBCC 错误 2570。
  • 使用 chkdsk 命令检查文件系统的完整性。

更多信息

有关 语法 DBCC CHECKDB 的详细信息以及有关如何运行命令的信息或选项,请参阅 DBCC CHECKDB (Transact-SQL)

如果使用 找到 CHECKDB任何错误,则会在 ERRORLOG 中报告类似于以下消息的其他消息,以便报告错误:

**Dump thread - spid = 0, EC = 0x00000000855F5EB0
***Stack Dump being sent toFilePath\FileName
* ******************************************************************************
*
* BEGIN STACK DUMP:
*  Date/Timespid 53
*
* DBCC database corruption
*
* Input Buffer 84 bytes -
*             dbcc checkdb(mydb)
*
* *******************************************************************************
*   -------------------------------------------------------------------------------
* Short Stack Dump
Stack Signature for the dump is 0x00000000000001E8
External dump process return code 0x20002001.

错误信息已提交到 Watson 错误报告。

用于报告错误的文件包括 SQLDump<nnn>.txt 文件。 此文件可用于历史用途,因为它包含 XML CHECKDB 格式中发现的错误列表。

若要了解上次DBCC CHECKDB运行时没有检测到数据库 (最后一个已知清理 CHECKDB) 的错误,检查用户或系统数据库中的以下消息SQL Server ERRORLOG, (此消息在 Windows 应用程序事件日志中将其写入为信息级别消息(EventID = 17573)以及) :

数据库“master”的日期/时间 spid7s CHECKDB 已完成,但日期/时间 22:11:11.417 (本地时间) 。 这只是一条信息性消息;无需用户操作