针对 SQL Server 文件报告 OS 错误 665 和 1450

本文可帮助你解决在执行、创建数据库快照或文件增长时 DBCC CHECKDB针对数据库文件报告 OS 错误 1450 和 665 的问题。

原始产品版本:SQL Server
原始 KB 数: 2002606

现象

假设你在运行 SQL Server 的计算机上执行以下操作之一:

  • 在大型数据库上创建数据库快照。 然后,在源数据库中执行大量数据修改或维护操作。
  • 在镜像数据库上创建数据库快照。
  • DBCC CHECKDB执行命令系列来检查大型数据库的一致性,并且还会在该数据库中执行大量数据更改。

注意

SQL Server 对这些操作使用 稀疏文件 :数据库快照和 DBCC CHECKDB

  • 备份或还原数据库。
  • 使用并行 BCP 执行和写入到同一卷,通过 BCP 执行批量复制到多个文件。

由于这些操作,你可能会注意到 SQL Server 错误日志中报告的一个或多个这些错误,具体取决于运行 SQL Server 的环境。

The operating system returned error 665(The requested operation could not be completed due to a file system limitation) to SQL Server during a write at offset 0x00002a3ef96000 in file 'Sam.mdf:MSSQL_DBCC18'
The operating system returned error 1450 (Insufficient system resources exist to complete the requested service.) to SQL Server during a write at offset 0x00002a3ef96000 in file with handle 0x0000000000000D5C. This is usually a temporary condition and the SQL Server will keep retrying the operation. If the condition persists, then immediate action must be taken to correct it.`

除了这些错误,还可以注意到以下闩锁超时错误:

Timeout occurred while waiting for latch: class *'DBCC_MULTIOBJECT_SCANNER'*, id 000000002C61DF40, type 4, Task 0x00000000038089B8 : 16, waittime 600, flags 0x1a, owning task 0x0000000006A09828. Continuing to wait.  
Timeout occurred while waiting for latch: class *'ACCESS_METHODS_HOBT_COUNT'*, id 000000002C61DF40, type 4, Task 0x00000000038089B8 : 16, waittime 600, flags 0x1a, owning task 0x0000000006A09828. Continuing to wait.  

此外,在查看各种动态管理视图(DMV)时,你可能还会注意到阻止,例如 sys.dm_exec_requestssys.dm_os_waiting_tasks

在极少数情况下,你可能会发现 SQL Server 错误日志中报告的非生成计划程序问题,并且 SQL Server 会生成内存转储。

原因

如果需要大量 ATTRIBUTE_LIST_ENTRY 实例来维护 NTFS 中的大量碎片文件,则会出现此问题。 如果空间位于文件系统已跟踪的群集旁边,则会将属性压缩为单个条目。 但是,如果空间已碎片,则必须使用多个属性对其进行跟踪。 因此,大量文件碎片可能会导致属性耗尽和生成的 665 错误。 以下知识库文章介绍了此行为: NTFS 卷中的大量碎片文件可能无法超过特定大小

当这些快照文件的生存期发生大量数据修改时,SQL Server 或其他应用程序创建的常规文件和稀疏文件都可以碎片化到这些级别。

如果在位于同一卷上的一组条带文件之间执行数据库备份,或者要将数据批量复制(BCP-ing)到同一卷上的多个文件,则写入操作最终可能位于相邻的位置,但属于不同文件。 例如,一个流写入到 201 到 400 之间的偏移量,另一个流从 401 写入到 600,第三个流可以从 601 写入到 800。 此过程也适用于其他流。 这将导致同一物理介质上的文件碎片。 每个备份文件或 BCP 输出流都可以耗尽属性存储,因为其中任何一个都无法获得相邻的存储。

有关 SQL Server 引擎如何使用 NTFS 稀疏文件和备用数据流的完整背景,请参阅 详细信息

解决方法

请考虑使用以下一个或多个选项来解决此问题:

  1. 将数据库文件放置在弹性文件系统(ReFS)卷上,该卷没有 NTFS 存在的相同ATTRIBUTE_LIST_ENTRY限制。 如果要使用当前的 NTFS 卷,则必须在将数据库文件暂时移到其他位置后重新格式化使用 ReFS。 使用 ReFS 是处理此问题的最佳长期解决方案。

    注意

    SQL Server 2012 和早期版本使用命名 文件流 而不是稀疏文件来创建 CHECKDB 快照。 ReFS 不支持文件流。 DBCC CHECKDB在 ReFS 中的 SQL Server 2012 文件上运行可能会导致错误。 有关详细信息,请参阅 DBCC CHECKDB 如何从 SQL Server 2014 开始创建内部快照数据库的说明

  2. 取消碎片数据库文件所在的卷。 请确保碎片整理实用工具是事务性的。 有关对 SQL Server 文件所在的驱动器进行碎片整理的详细信息,请参阅 对 SQL Server 数据库驱动器和建议进行碎片整理时的预防措施。 必须关闭 SQL Server 才能对文件执行此操作。 建议先创建完整数据库备份,然后再将文件碎片整理为安全措施。 碎片整理在固态硬盘(SSD)媒体上的工作方式不同,通常无法解决问题。 复制文件并允许 SSD 固件重新打包物理存储通常是更好的解决方案。 有关详细信息,请参阅操作系统错误(665 - 文件系统限制)不再只是发生在 DBCC 上

  3. 文件复制 - 执行文件副本可能会提供更好的空间获取,因为该字节可能在进程中紧密打包在一起。 复制文件(或将其移动到其他卷)可能会减少属性使用情况,并可能阻止 OS 错误 665。 将一个或多个数据库文件复制到另一个驱动器。 然后,可以将文件保留在新卷上,或将其复制回原始卷。

  4. 使用 /L 选项获取大型 FRS 设置 NTFS 卷的格式。 此选项可能会缓解此问题,因为它使 ATTRIBUTE_LIST_ENTRY 问题更大。 使用 DBCC CHECKDB 此选项可能没有帮助,因为后者为数据库快照创建稀疏文件。

    注意

    对于运行 Windows Server 2008 R2 和 Vista 的系统,首先需要从知识库文章967351应用修补程序,然后再将/Lformat选项与命令一起使用。

  5. 将大型数据库拆分为较小的文件。 例如,如果有一个 8 TB 数据文件,则可以将其分解为 8 个 1 TB 数据文件。 此选项可能会有所帮助,因为较小的文件修改会减少,因此不太可能引入属性耗尽。 此外,在移动数据的过程中,文件将组织得紧凑,碎片化会减少。 以下是概述该过程的高级步骤:

    1. 将七个新的 1 TB 文件添加到同一文件组。
    2. 重新生成现有表的聚集索引,该索引将自动将每个表的数据分散到八个文件之间。 如果表没有聚集索引,请创建一个并删除它以完成相同的操作。
    3. 收缩原始的 8 TB 文件,该文件现在已满约 12%。
  6. 数据库自动增长设置:调整自动 增长增量 数据库设置,以获取有利于生产性能和打包 NTFS 属性的大小。 自动增长次数和增长增量大小越少,文件碎片的可能性就越小。

  7. 使用性能增强功能减少命令的 DBCC CHECK 生存期,从而避免 665 错误: 使用 PHYSICAL_ONLY 选项时,DBCC CHECKDB 命令的改进可能会导致性能更快。 请记住,使用PHYSICAL_ONLY开关运行时DBCC CHECKDB不提供可避免此错误的保证,但在许多情况下会降低可能性。

  8. 如果要跨多个文件(条带集)执行数据库备份,请仔细规划文件数, MAXTRANSFERSIZEBLOCKSIZE (请参阅 BACKUP)。 目标是减少文件系统上的片段,通常通过将较大的字节区块一起写入文件来实现。 可以考虑跨多个卷对文件进行条带化,以提高性能和减少碎片。

  9. 如果使用 BCP 同时写入多个文件,请调整实用工具写入大小,例如增加 BCP 批大小。 此外,请考虑将多个流写入不同的卷以避免碎片,或减少并行写入数。

  10. 若要执行 DBCC CHECKDB,可以考虑设置可用性组或日志传送/备用服务器。 或使用第二台服务器,可在其中运行 DBCC CHECKDB 命令来卸载工作,并避免遇到稀疏文件碎片导致的问题。

  11. 执行 DBCC CHECKDB时,如果在数据库服务器上几乎没有活动时运行该命令,则会轻填充稀疏文件。 对文件的写入次数越少,就越有可能耗尽 NTFS 上的属性。 更少的活动是尽可能在另一台只读服务器上运行 DBCC CHECKDB 的另一个原因。

  12. 如果运行的是 SQL Server 2014,请升级到最新的 Service Pack。 有关详细信息,请参阅 FIX:对 SQL Server 2014 中包含列存储索引的数据库执行 DBCC CHECKDB 命令时 OS 错误 665。

详细信息