排查SQL Server中的内存不足或内存不足问题

0    77    1

Tags:

👉 本文共约8093个字,系统预计阅读时间或需31分钟。

症状

SQL Server使用与复杂且丰富的功能集相对应的复杂内存体系结构。 由于内存需求多种多样,内存消耗和内存压力的来源可能很多,最终导致内存不足的情况。

存在指示SQL Server内存不足的常见错误。 错误示例包括:

  • 701 - 无法分配足够的内存来运行查询
  • 802 - 无法获取内存以在缓冲池中分配页 (数据页或索引页)
  • 1204 - 无法为锁分配内存
  • 6322 - 为 XML 分析程序分配内存失败
  • 6513 - 由于内存压力,无法初始化 CLR
  • 6533 - AppDomain 因内存不足而卸载
  • 8318 - 由于内存不足,无法加载 SQL 性能计数器
  • 8356 或 8359 - ETW 或 SQL 跟踪由于内存不足而无法运行
  • 8556 - 由于内存不足,无法加载 MSDTC
  • 8645 - 由于内存授予 (排序和哈希) (内存,无法执行查询。有关详细信息,请参阅如何排查SQL Server错误 8645 )
  • 8902 - DBCC 执行期间未能分配内存
  • 9695 或 9696 - 无法为 Service Broker 操作分配内存
  • 17131 或 17132 - 由于内存不足,服务器启动失败
  • 17890 - 由于操作系统分页的 SQL 内存,无法分配内存
  • 22986 或 22987 - 由于内存不足而发生更改数据捕获失败
  • 25601 - Xevent 引擎内存不足
  • 26053 - 由于内存不足,SQL 网络接口无法初始化
  • 30085、30086、30094 - SQL 全文操作由于内存不足而失败

原因

许多因素都可能导致内存不足。 这些因素包括操作系统设置、物理内存可用性、在 SQL Server 中使用内存的组件,以及当前工作负荷的内存限制。 在大多数情况下,失败并出现内存不足错误的查询不是导致此错误的原因。 总体而言,原因可分为三类:

原因 1:外部或 OS 内存压力

外部压力是指来自进程外部的组件导致内存不足,导致SQL Server内存不足的内存使用率过高。 必须了解系统上的其他应用程序是否消耗了内存并导致内存可用性低。 SQL Server是为数不多的应用程序之一,旨在通过减少其内存使用量来响应 OS 内存压力。 这意味着,如果应用程序或驱动程序请求内存,OS 会向所有应用程序发送释放内存的信号,SQL Server将通过减少自身的内存使用量来做出响应。 其他应用程序很少会做出响应,因为它们不设计用于侦听该通知。 因此,如果SQL Server开始减少其内存使用量,则其内存池会减少,并且需要内存的组件都可能无法获取内存。 因此,你开始收到 701 或其他与内存相关的错误。 有关 SQL 如何动态分配和释放内存的详细信息,请参阅 SQL Server 内存体系结构。 有关此问题的更详细的诊断和解决方案,请参阅本文中的 外部内存压力

有三大类问题可能会导致 OS 内存压力:

  • 应用程序相关问题:一个或多个应用程序一起耗尽可用的物理内存。 OS 将通过尝试释放一些内存来响应对资源的新应用程序请求。 常见方法是查找哪些应用程序耗尽内存,并采取必要的步骤来平衡其中内存,而不会导致 RAM 耗尽。
  • 设备驱动程序问题:如果驱动程序错误地调用内存分配函数,设备驱动程序可能会导致所有进程的工作集分页。
  • 操作系统产品问题。

有关这些步骤和故障排除步骤的详细说明,请参阅 MSSQLSERVER_17890

原因 2:内部内存压力,不是来自SQL Server

内部内存压力是指由SQL Server进程内部因素导致的内存可用性低。 可在SQL Server进程中运行的某些组件是SQL Server引擎的“外部”。 示例包括 OLE DB 提供程序 (DLL) 链接服务器、SQLCLR 过程或函数、扩展过程 (XP) 以及 OLE 自动化 (sp_OA*) 。 其他程序包括防病毒或其他安全程序,这些程序在进程内注入 DLL 以用于监视目的。 这些组件中的任何一个问题或设计不佳都可能导致大量内存消耗。 例如,假设链接服务器将来自外部源的 2000 万行数据缓存到SQL Server内存中。 就SQL Server而言,没有内存职员会报告内存使用率过高,但SQL Server进程中消耗的内存会很高。 例如,链接服务器 DLL 的这种内存增长将导致SQL Server开始削减其内存使用率, (如上) 所示,并且会为SQL Server内的组件创建内存不足的情况,从而导致内存不足错误。 有关此问题的更详细诊断和解决方案,请参阅内部内存压力,而不是来自SQL Server

备注

SQL Server进程空间中使用的一些 Microsoft DLL (例如 MSOLEDBSQLSQL Native Client) 能够与SQL Server内存基础结构进行交互,以便进行报告和分配。 可以运行 select * from sys.dm_os_memory_clerks where type='MEMORYCLERK_HOST' 来获取它们的列表,并跟踪部分分配的内存消耗。

原因 3:内部内存压力,来自SQL Server组件 ()

来自SQL Server引擎内部组件的内部内存压力也可能导致内存不足错误。 有数百个组件,通过内存管理器跟踪,这些组件在SQL Server中分配内存。 必须确定哪些内存办事员 () 负责最大的内存分配才能解决此问题。 例如,如果发现 OBJECTSTORE_LOCK_MANAGER 内存管理器显示较大的内存分配,则需要了解锁管理器消耗这么多内存的原因。 你可能会发现某些查询会获取许多锁。 可以通过使用索引来优化这些查询,缩短长时间保留锁的任何事务,或者检查是否禁用了锁升级。 每个内存管理器或组件都有一种访问和使用内存的独特方式。 有关详细信息,请参阅 内存文员类型 及其说明。 有关此问题的更详细诊断和解决方案,请参阅按引擎SQL Server的内部内存使用情况

内存压力类型的直观表示形式

下图说明了可能导致SQL Server内存不足情况的压力类型:

排查SQL Server中的内存不足或内存不足问题

用于收集故障排除数据的诊断工具

可以使用以下诊断工具来收集故障排除数据:

性能监视器

使用 性能监视器 配置和收集以下计数器:

  • 内存:可用 MBytes
  • Process:Working Set
  • 进程:专用字节数
  • SQL Server:内存管理器: (所有计数器)
  • SQL Server:缓冲区管理器: (所有计数器)

DMV 或 DBCC MEMORYSTATUS

可以使用 sys.dm_os_memory_clerksDBCC MEMORYSTATUS 来观察SQL Server内的总体内存使用情况。

本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信db_bao,谢谢!
排查SQL Server中的内存不足或内存不足问题后续精彩内容已被小麦苗无情隐藏,请输入验证码解锁本站所有文章!
验证码:
请先关注本站微信公众号,然后回复“验证码”,获取验证码。在微信里搜索“DB宝”或者“www_xmmup_com”或者微信扫描右侧二维码都可以关注本站微信公众号。

标签:

Avatar photo

小麦苗

学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

您可能还喜欢...

发表回复

嘿,我是小麦,需要帮助随时找我哦。
  • 18509239930
  • 个人微信

  • DB宝
  • 个人邮箱
  • 点击加入QQ群
  • 个人微店

  • 回到顶部