SQL Server 内存管理架构详解
本文详细解析了 SQL Server 的内存管理体系结构,包括 Windows 虚拟内存映射、动态内存获取机制、缓冲区管理器工作流程以及如何通过调整配置来应对内存压力和长 I/O 问题。
Windows 的虚拟内存管理器
地址空间的已提交区域由 Windows 虚拟内存管理器(VMM)映射到可用的物理内存。虚拟内存系统允许物理内存的过度使用,因此虚拟内存与物理内存的比率可以超过 1:1,使得较大的程序可以在各种物理内存配置的计算机上运行。但若使用的虚拟内存远超总平均工作集,则可能导致性能不佳。
SQL Server 内存体系结构
SQL Server 根据需要动态获取和释放内存。管理员通常不必指定应分配的内存量,尽管该选项在特定环境中仍然可用且有用。
所有数据库软件的主要设计目标之一是最小化磁盘 I/O,因为磁盘读写最耗费资源。SQL Server 在内存中构建一个缓冲池以保存从数据库读取的页。它试图在两个目标间取得平衡:
- 防止缓冲池变得太大导致系统内存不足。
- 通过最大化缓冲池大小,最大限度地减少物理 I/O。
解决内存压力下的性能问题
在负载较重的系统中,大型查询可能无法获取请求的最小内存量。若要解决超时错误,可以增加“查询等待选项”。对于并行查询,建议降低“最大并行度”选项。
在内存压力很大的系统中,若查询未获得位图所需的最小内存,可能会删除位图并影响性能。如果排序过程无法容纳在内存中,可能导致 TempDB 增长。解决方案包括添加物理内存或调整查询计划。
传统(虚拟)内存
所有 SQL Server 版本均支持 64 位平台上的传统内存。SQL Server 进程可访问最高至操作系统最大值(如 x64 标准版最多支持 128 GB)的虚拟地址空间。
地址窗口扩展 (AWE) 内存
AWE 允许将大部分 SQL Server 进程内存锁定在物理 RAM 中,这有助于在存在内存压力时保持数据驻留。启用 AWE 需要“锁定内存中的页”(SeLockMemoryPrivilege)权限。
- 风险提醒:强烈建议在使用 AWE 时将“最大服务器内存”设置为特定值,而非默认最大值。
- 若未启用 LPIM,SQL Server 将回退到常规内存模式,并在内存耗尽时可能在错误日志中报告错误 17890。
从 SQL Server 2012 (11.x) 开始的变化
内存管理的变更
自 2012 起,单页分配、多页分配和 CLR 分配合并到“任何大小”页面分配器中,并受最小/最大服务器内存配置限制。这使得内存大小调整更精确。
在此版本中,SQL Server 分配的内存可能会短暂超过“最大服务器内存”设置。若因内存碎片无法满足多页内存请求(>8KB),SQL Server 会执行过度分配以避免拒绝请求。随后,资源监视器后台任务会发出释放信号,使总内存低于规范。
memory_to_reserve 的配置变化
旧版本中预留的用于多页分配器、CLR 等组件的虚拟地址空间,现因“任何大小”分配器的引入而不再包含多页分配。相关的配置选项 memory_to_reserve 默认值为 256 MB,但其含义仅涉及非缓冲池区域的保留,不包括多页分配。
动态内存管理
SQL Server 默认行为是按需获取尽可能多的内存,而不造成系统内存不足。它利用 Windows 内存通知 API 定期查询可用内存量。
- 动态调整:若可用内存减少,SQL Server 向 OS 释放内存;若有更多可用内存,则可分配更多。注意,虚拟地址空间大小不会静态增加。
- 观察现象:若在任务管理器中看到可用内存稳定减少,这是默认行为,并非内存泄漏。
- 控制范围:
max_server_memory控制编译内存、缓存、缓冲池、查询执行内存授予等。CLR 内存在 2012 及更高版本中也受此限制管理。
查看当前内存状态
可以通过以下 T-SQL 查询检查进程当前的内存使用情况:
SELECT
physical_memory_in_use_kb/1024 AS sql_physical_memory_in_use_MB,
large_page_allocations_kb/1024 AS sql_large_page_allocations_MB,
locked_page_allocations_kb/1024 AS sql_locked_page_allocations_MB,
virtual_address_space_reserved_kb/1024 AS sql_VAS_reserved_MB,
virtual_address_space_committed_kb/1024 AS sql_VAS_committed_MB,
virtual_address_space_available_kb/1024 AS sql_VAS_available_MB,
page_fault_count AS sql_page_fault_count,
memory_utilization_percentage AS sql_memory_utilization_percentage,
process_physical_memory_low AS sql_process_physical_memory_low,
process_virtual_memory_low AS sql_process_virtual_memory_low
FROM sys.dm_os_process_memory;
堆栈大小的不受控性
线程堆栈、CLR、扩展存储过程、OLE DB 提供程序等非 SQL Server DLL 分配的内存**不**受 max_server_memory 限制。这些内存占用需额外关注,特别是在高并发场景下。
缓冲区管理
缓冲区管理器负责将数据页从磁盘读入缓冲池,并处理修改后的写回。缓冲池由大小为 8 KB 的页组成。
工作原理
启动时,SQL Server 根据物理内存量和配置计算虚拟地址空间大小(内存目标),但仅提交当前所需的物理内存。随着用户连接增加,实例按需获取更多物理内存,直到达到 max_server_memory 上限或 OS 指示无更多可用内存。
当 min_server_memory 设置被触及且 OS 内存不足时,SQL Server 会释放内存。爬坡阶段(Startup):在启动初期,通过将对齐的单页请求转换为八页范围请求,加速填充缓冲池。
支持的功能
- NUMA 感知:识别非一致性内存访问,优化本地节点访问。
- 热添加内存:支持在不重启的情况下添加物理内存。
- 大页面:支持 64 位平台上的大页面以减少页表开销。
- 诊断工具:通过 DMV 公开 OS 资源指标。
磁盘 I/O 特征
- 所有 I/O 均为异步执行。
- I/O 请求由调用线程发出(关联 I/O 掩码可将特定 CPU 绑定以优化 OLTP 环境性能)。
- 使用分散-收集 I/O 快速填充或刷新缓冲池。
长 I/O 请求的处理
缓冲区管理器会报告任何未完成至少 15 秒的 I/O 请求,记录为错误消息 833(警告性质)。这主要反映底层 I/O 子系统的问题,而非 SQL Server 自身故障。
排查思路:若出现频繁的长 I/O 消息,请检查:
- 错误日志中是否重复出现此类消息。
- 性能计数器中是否有较长的磁盘延迟或队列。
- 是否存在大量顺序 I/O 操作(如索引创建、备份还原),这可能加剧电梯搜索导致的延迟。
了解非一致性内存访问 (NUMA)
SQL Server 原生支持 NUMA 架构,无需特殊应用更改即可利用基于 NUMA 的计算机优势。硬件供应商通过增大 L3 缓存缓解内存延迟问题,而 NUMA 提供了更具扩展性的解决方案。SQL Server 旨在自动优化数据在线程所在 NUMA 节点本地内存中的分布,以减少跨节点内存访问带来的性能损耗。
以上就是 SQL Server 内存管理架构的详细内容,更多关于数据库内存优化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













