未知,由于内存压力,AppDomain 66 (master.sys[runtime].65) 被标记为卸载

Sto*_*urn 7 sql-server sql-clr error-log sql-server-2016

我偶尔会在 SQL 错误日志中注意到这个错误:

由于内存压力,spid20s,Unknown,AppDomain 79 (master.sys[runtime].78) 被标记为卸载。

我正在使用 SQL Server 2016,SP1 CU5(我正在推动修补,但公司拒绝)。

我读过的所有内容都指向非 CLR 特定的内存压力。有关于更改MemToLeave启动参数中的设置的建议。对于较新版本的 SQL Server,这仍然是这种情况,还是有其他建议?

Sol*_*zky 11

SQL Server 2012 中的内存体系结构发生了变化,因此无需再担心MemToLeave设置,尤其是在使用 64 位 SQL Server 时。而且,从 SQL Server 2016(您正在使用的)开始,SQL Server 仅在 64 位中可用(请参阅“数据库引擎中的新增功能 - SQL Server 2016 ”页面顶部的“注意” )。所以,不,别担心MemToLeave

正确,“内存压力”错误并非特定于 SQLCLR。这些错误并没有告诉你内存压力的原因,而是内存压力会影响什么(我怀疑是否有任何可能的方法来真正了解原因 - 我的意思是,如果有 10 个进程占用内存,哪个组合才是真正的原因?不一定是什么占用了最大的块,因为这可能是完全有效的)。内存压力也会影响其他可能不会出现在错误日志中的区域,例如刷新计划缓存和/或缓冲池(即加载到内存中的数据页)。

有几个使用 SQLCLR 的内置功能,部分列表如下:

  • 数据类型:
    • 层次ID
    • 地理
    • 几何学
  • 职能:
    • FORMAT
    • PARSE
    • TRY_PARSE
    • AT TIME ZONE (从 SQL Server 2016 开始)
    • COMPRESS(但不是UNCOMPRESS; 从 SQL Server 2016 开始)
  • 特征:
    • 变更数据捕获
    • 动态管理框架
    • 复制
    • 基于策略的管理
    • 主数据服务
    • SSISDB(“模糊查找”功能)

其中一个或多个(或者可能是我没有在上面列出的一个)是您系统中受到影响的内容。有两条线索,都在该(master.sys[runtime].78)信息的部分,告诉我们:

  1. 数据库是master(假设您永远不会将自定义程序集加载到master;-))
  2. 程序集的“所有者”(即AUTHORIZATION)是sys(我们不能将程序集的所有权分配给任何一个sysINFORMATION_SCHEMA因为这些主体都没有SID)。如果要查看每个程序集的所有者,请执行以下操作:

    SELECT asm.[name] AS [Assembly],
           USER_NAME(asm.[principal_id]) AS [Owner],
           USER_SID(asm.[principal_id]) AS [OwnerSID]
    FROM   sys.assemblies asm;
    
    Run Code Online (Sandbox Code Playgroud)

你可以做的是:

  1. 您提到此错误“偶尔”出现,但并未准确定义这种情况的实际发生频率。一小时一次不同于一天一次,而一天一次又不同于每周一次。内存压力会发生,所以除非每天超过几次,否则我不会花太多时间担心它。
  2. 添加更多内存(物理上和/或允许 SQL Server 使用更多系统内存,如果您当前将 SQL Server 限制为较少量)
  3. 分析在 SQL Server 之外消耗内存的内容,以查看服务器上是否有不必要的进程可以卸载到其他服务器,或者可能完全关闭(即是否正在使用其他服务,和/或远程桌面会话然后运行使用大量内存的 SSMS 等?)


Ada*_* K. 7

可能会调查这个:https : //docs.microsoft.com/en-us/sql/relational-databases/memory-management-architecture-guide。特别是关于当前分配内容的查询。它会给你一个专注于诊断的地方。

我以前遇到过这个问题,它最终会重复调用 CLR 过程,该过程在完成后永远不会自行关闭。