排查 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 CHECKTABLE DBCC 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 文档,了解与数据库损坏(一致性错误)相关的任何已知问题,并应用任何相关的修补程序。 如果 SQL Server 2022、2019、2017 的详细修补程序列表,则可以在其中搜索特定版本的所有修补程序。

  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 是 ( DBCC CHECKDB mydb) 找到的错误的最低修复级别。

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

    警告

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

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

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

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

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

  • 检查 Windows 系统事件日志中是否有任何与系统级别、驱动程序或磁盘相关的错误,并与硬件制造商合作解决这些问题。
  • 为计算机和/或磁盘系统运行硬件制造商提供的任何诊断。
  • 请与硬件供应商或设备制造商合作,确保:
    • 硬件设备和配置确认Microsoft SQL Server 数据库引擎输入/输出要求
    • I/O 路径中所有设备的设备驱动程序和其他支持软件组件都是最新的。
  • 请考虑在报告一致性错误的数据库所在的驱动器上使用 SQLIOSim实用工具。 SQLIOSim 是独立于 SQL Server 引擎的工具,用于测试磁盘系统 I/O 的完整性。 SQLIOSim 附带 SQL Server,不需要单独下载。 可以在 \MSSQL\Binn 文件夹中找到它。
  • 检查累积更新或 Service Pack 文档,了解与数据库损坏(一致性错误)相关的任何已知问题,并应用任何相关的修补程序。 如果 SQL Server 2022、2019、2017 的详细修补程序列表,则可以在其中搜索特定版本的所有修补程序。
  • 检查 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 命令检查文件系统的完整性。 在 SQL Server 运行时不要 运行 chkdsk 。 如果 SQL Server 正在写入正在检查的文件,则可能报告暂时性文件错误。 此外,如果 SQL Server 也在写入或读取这些文件,例如 /r/f 可以将文件字节移动到磁盘上的其他位置,这种移动可能会导致损坏。 因此,在运行 chkdsk 命令之前,请务必停止 SQL Server。 此外,请谨慎使用像和/f这样的/r修复选项。 请确保在运行修复之前备份数据库,因为这些选项可能会损坏文件(如果找到 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 编写为信息级别消息:

Date/Time spid7s CHECKDB for database “master”在 Date/Time22:11:11.417(本地时间)上未出错。 这只是一条信息性消息;无需用户操作