当使用 LOB 数据类型的链接服务器查询遇到异常时,SQL Server 将生成断言转储文件

本文可帮助你解决导致MICROSOFT SQL Server 生成资产转储文件和 SQL Server 服务变得无响应的问题。

现象

假设出现了下面这种情景:

  • SQL Server 生成断言转储文件。 这会导致 SQL Server 服务无响应。

  • 在 SQL Server 错误日志中,可以看到以下断言表达式: pilb->m_cRef == 0 有关断言以及如何对其进行故障排除的详细信息,请参阅 MSSQLSERVER_3624 - SQL Server

    2023-03-14 06:12:44.83 spid54 * 位置:memilb.cpp:1836 2023-03-14 06:12:44.83 spid54 * 表达式: pilb-m_cRef> == 0

  • 在转储文件过程中,SQL Server 变得无响应。

原因

下面是在生成 SQL Server 转储文件时可能影响的一些条件:

  • 使用 EXEC AT 命令运行远程查询。 例如:

    DECLARE @test NVARCHAR(MAX) = N'ABC'
    EXEC ('SELECT * FROM Customers.dbo.CustomerInformation WHERE CustomerId = ?', @test) AT [YourRemoteServer];
    
  • 将大型对象 (LOB) 参数传递给查询。 有关 LOB 数据类型的详细信息,请参阅 数据类型 (Transact-SQL) - SQL Server

在前面的示例中,变量 NVARCHAR(MAX) 作为查询参数传递。 提交到链接服务器的基础请求之一失败。

还可以通过运行以下查询来重现问题:

DECLARE @test NVARCHAR(MAX) = N'msdb' 
EXEC ('---SELECT * FROM sys.databases where name = ?', @test) AT [<server>\<instance>]

若要避免此问题,请在数据库设计或代码中使用 nonblob (BLOB) 数据类型:

DECLARE @test NVARCHAR(5) = N'msdb' 
EXEC ('---SELECT * FROM sys.databases where name = ?', @test) AT  [<server>\<instance>]

警告

如果在环境中运行此代码,则可能会遇到会导致中断的转储文件。 以自己的风险运行。

Status

Microsoft仍在调查此问题,以确定长期修复。 在修补程序可用之前,可以尝试下一部分提供的解决方法。

解决方法

若要解决此问题,请将所有 LOB (大型对象)数据类型更改为固定输入数据长度支持的长度数据类型。 例如,转换为 NVARCHAR(MAX) NVARCHAR(200)).