人人都是 DBA(IV)SQL Server 内存管理

时间:2022-08-24 19:50:43

SQL Server 的内存管理是一个庞大的主题,涉及特别多的概念和技术,例如常见的 Plan Cache、Buffer Pool、Memory Clerks 等。本文仅是管中窥豹,描述常见的内存管理相关概念。

人人都是 DBA(IV)SQL Server 内存管理

在了解内存管理之前,通过 sys.dm_os_memory_clerks 视图可以查询内存的使用职责(Memory Clerks),也就是内存的消耗者。

SELECT [type], SUM(pages_kb) AS total_pages_kb
FROM sys.dm_os_memory_clerks
WHERE pages_kb != 0
GROUP BY [type]
ORDER BY total_pages_kb DESC;

人人都是 DBA(IV)SQL Server 内存管理

SQL Server 中最主要的内存组件就是缓冲池(Buffer Pool, or Bpool)。缓冲池是一个 8KB 页面的集合,任何大于 8KB 的内存块都需要进行单独分配管理,例如 COM Objects、CLR Code、Extended Stored Procedures、Large Cached Plan 等。

缓冲区管理器(Buffer Manager)负责从磁盘上的数据文件中读取数据页(Data Page)和索引页(Index Page),将页数据放入 Buffer Pool 中作为数据缓存(Data Cache)。Buffer 指的是内存中的一个 Page,该 Page 的大小与数据页或索引页相同。

SQL Server 采用预读机制(Read-ahead)从磁盘中读取数据页和索引页至缓冲区中,以提高性能。预读机制完全有系统内部控制,不需要进行任何配置和调整。

数据缓存(Data Cache)

数据缓存(Data Cache)中使用哈希(Hashing)方式存储页数据。比如给定 DatabaseID-FileNumber-PageNumber 标识符,通过哈希函数将标识符存放到哈希表中。这样,通过哈希表(Hash Table)提供的快速检索功能,数据库引擎仅需要较少的内存读取就可以判断目标页是否存在于缓存中,如果不存在再从磁盘中读入缓存。

SQL Server 会将那些一段时间未被引用的页面缓冲位置标记为空闲页,通过空闲页链表进行管理。当需要新的缓冲页时,将从链表头获取要使用的页地址。

每个数据缓存的页中都包含一块表头区域,包含该页最后两次被引用的相关信息和状态信息,例如描述该页是否为脏页(Dirty Page)。脏页(Dirty Page)指的是从磁盘读取后的数据页被修改过。引用信息则用于实现数据缓存页的页面替换策略,它使用 LRU-K 算法。LRU-K 算法将有价值的缓冲区持有页保留在活跃缓冲池中,而如果缓冲区持有页的引用频率不高,则这些缓冲区页将被逐渐地释放回空闲缓冲区列表中。

LazyWriter 线程

SQL Server 为每个 NUMA 节点都创建了一个 LazyWriter 线程,用于扫描与该节点关联的缓冲区。LazyWriter 线程会进行周期性的睡眠和唤醒,当唤醒时将检查空闲缓冲区列表的长度,如果低于某个阈值,将扫描整个缓冲区。在扫描过程中,当发现页的引用率较低时,将检查脏页指示符。如果该页是脏页,则执行磁盘写入操作。然后该页将被释放回空闲缓冲区列表中。

SQL Server 动态使用内存时,必须不断地侦听可用内存的数量,并且追踪和监视内存的更改,以判断何时增加或减少自身的总内存量。每当 SQL Server 中的内存增加或减少 1MB,或达到服务器内存的 5% 时,将会产生事件通知。

检查点(Checkpoint)

检查点(Checkpoint)线程也定期扫描缓冲区,并将脏数据页写入磁盘。检查点与 LazyWriter 的区别在于,检查点不会向空闲缓冲区列表添加空闲缓冲区。检查点的唯一目的就是,确保将某一时刻前的页面都写入磁盘中,以便始终保持内存中的脏页数量最小。

SQL Server 将检查点的运行过程记录到事务日志中,当 SQL Server 出现故障时,由于已写入了某一时刻前的数据,可以减少恢复时间。

触发检查点的情况有:

  • 手动触发 CHECKPOINT 命令在指定数据库上执行检查点。
  • 日志正在变慢,超过容量的 70%。触发检查点可以截断日志并释放日志空间。
  • 预计需要较长的恢复时间。预计恢复时间比设置的 "Recovery Interval" 选项的值要长时。如果 "Recovery Interval" 设置为 1,意味着检查点每分钟一次。默认值为 0,意味着 SQL Server 将选择合适的值,通常也是 1 分钟。
  • 请求正常关闭 SQL Server,并且不使用 NOWAIT 选项。

检查点线程采用非顺序的方式对缓冲区进行扫描。当找到一个脏页时,会检查该脏页在磁盘上相邻的页面是否也是脏页,以便组合进行 gather-write 大块数据写入,提高性能。

计划缓存(Plan Cache)

在 Buffer Pool 的缓冲区的使用组件中,除了数据缓存(Data Cache),另一个使用量最大的就是对过程与查询计划的缓存,也就是通常说的计划缓存(Plan Cache)

SQL Server 为处数据缓存外所有其他的缓存机制提供通用缓存框架,包括储存方式和资源监视器。储存方式包括三种:

  1. Cache Store:计划缓存(Plan Cache)和行集(Rowset Clerk)为常见的 Cache Store。
  2. User Store:元数据缓存(Metadata Clerk)即为一种 User Store。
  3. Object Store/Memory Pool:SNI Pooling Network Buffer 即为一种 Object Store。

Cache Store 和 User Store 采用 LRU 机制来分配和释放空间,使用 Clock 页面置换算法来实现。而 Object Store 则只是大块的内存,不需要 LRU 机制。

Cache Store 使用哈希表来加快查询速度,而 User Store 则未使用哈希表,Object Store 也未使用哈希表。

通过查看 sys.dm_os_memory_cache_clock_hands 视图,尤其是 removed_last_round_count 列,如果该值在急剧增加,那么是出现内存压力的显著征兆。

SELECT cache_address
,[name]
,[type]
,clock_hand
,clock_status
,removed_last_round_count
FROM sys.dm_os_memory_cache_clock_hands;

人人都是 DBA(IV)SQL Server 内存管理

Memory Broker

在 SQL Server 中有大量的组件需要使用内存,为了确保每个组件都在有效的使用内存,SQL Server 使用 Memory Broker 分析与内存消耗相关的行为,并改善动态内存分配。

Memory Broker 可以在 Buffer Pool、Query Executor、Query Optimizer 等各种使用缓存的组件间调度内存分配。通过监视内存的需求与消耗,通过带有反馈和改进机制的动态分配算法,协调各组件间形成最佳的内存分配方式。

SELECT *
FROM sys.dm_os_ring_buffers
WHERE ring_buffer_type = 'RING_BUFFER_MEMORY_BROKER';

人人都是 DBA(IV)SQL Server 内存管理

观察内存

  • sys.dm_os_memory_clerks 该视图描述 SQL Server 实例中正在使用内存的组件职责。
  • sys.dm_os_memory_objects 该视图描述 SQL Server 当前分配的内存对象。
  • sys.dm_os_memory_nodes 该视图描述分配的 NUMA Node 相关信息。
  • sys.dm_os_memory_pools 该视图显示 Object Store 相关信息。
  • sys.dm_os_memory_cache_counters 该视图描述 Cache Store 和 User Store 的运行情况快照。
  • sys.dm_os_memory_cache_hash_tables 该视图描述活跃的缓存信息。
  • sys.dm_os_memory_cache_clock_hands 该视图描述 Clock 页面置换算法的相关信息。

《人人都是 DBA》系列文章索引:

 序号 

 名称 

1

人人都是 DBA(I)SQL Server 体系结构

2

人人都是 DBA(II)SQL Server 元数据

3

人人都是 DBA(III)SQL Server 调度器

4

人人都是 DBA(IV)SQL Server 内存管理

5

人人都是 DBA(V)SQL Server 数据库文件

6

人人都是 DBA(VI)SQL Server 事务日志

7

人人都是 DBA(VII)B 树和 B+ 树

8

人人都是 DBA(VIII)SQL Server 页存储结构

9

人人都是 DBA(IX)服务器信息收集脚本汇编

10

人人都是 DBA(X)资源信息收集脚本汇编

11

人人都是 DBA(XI)I/O 信息收集脚本汇编

12

人人都是 DBA(XII)查询信息收集脚本汇编

13

人人都是 DBA(XIII)索引信息收集脚本汇编

14

人人都是 DBA(XIV)存储过程信息收集脚本汇编

15

人人都是 DBA(XV)锁信息收集脚本汇编

本系列文章《人人都是 DBA》由 Dennis Gao 发表自博客园个人技术博客,未经作者本人同意禁止任何形式的转载,任何自动或人为的爬虫转载或抄袭行为均为耍流氓。

人人都是 DBA(IV)SQL Server 内存管理的更多相关文章

  1. SQL Server 内存管理

    windows memory:  Memory: Cache Bytes 是系统的working set, 也就是系统使用的物理内存数目. 可以观察Windows用了多少物理内存. 1. System ...

  2. SQL Server 内存管理在64位时代的改变

    64位机上  地址空间比以前大了去了.它引起的改变多了去了 1.MemToLeave这个词不存在了.因为SQL Server以不再做这种预留空间的事了,也就是说multiple page 想用多少就用 ...

  3. 人人都是 DBA(VIII)SQL Server 页存储结构

    当在 SQL Server 数据库中创建一张表时,会在多张系统基础表中插入所创建表的信息,用于管理该表.通过目录视图 sys.tables, sys.columns, sys.indexes 可以查看 ...

  4. 人人都是 DBA(VI)SQL Server 事务日志

    SQL Server 的数据库引擎通过事务服务(Transaction Services)提供事务的 ACID 属性支持.ACID 属性包括: 原子性(Atomicity) 一致性(Consisten ...

  5. 人人都是 DBA(V)SQL Server 数据库文件

    SQL Server 数据库安装后会包含 4 个默认系统数据库:master, model, msdb, tempdb. SELECT [name] ,database_id ,suser_sname ...

  6. 人人都是 DBA(III)SQL Server 调度器

    在 SQL Server 中,当数据库启动后,SQL Server 会为每个物理 CPU(包括 Physical CPU 和 Hyperthreaded)创建一个对应的任务调度器(Scheduler) ...

  7. 人人都是 DBA(II)SQL Server 元数据

    SQL Server 中维护了一组表用于存储 SQL Server 中所有的对象.数据类型.约束条件.配置选项.可用资源等信息,这些信息称为元数据信息(Metadata),而这些表称为系统基础表(Sy ...

  8. 人人都是 DBA(I)SQL Server 体系结构

    在了解 SQL Server 数据库时,可以先从数据库的体系结构来观察.SQL Server 的体系结构中包含 4 个主要组成部分: 协议层(Protocols) 关系引擎(Relational En ...

  9. 人人都是 DBA(XII)查询信息收集脚本汇编

    什么?有个 SQL 执行了 8 秒! 哪里出了问题?臣妾不知道啊,得找 DBA 啊. DBA 人呢?离职了!!擦!!! 程序员在无处寻求帮助时,就得想办法自救,努力让自己变成 "伪 DBA& ...

随机推荐

  1. activemq的几种基本通信方式总结

    简介 在前面一篇文章里讨论过几种应用系统集成的方式,发现实际上面向消息队列的集成方案算是一个总体比较合理的选择.这里,我们先针对具体的一个消息队列Activemq的基本通信方式进行探讨.activem ...

  2. HC-05蓝牙模块基本使用

    1.进入AT模式 EN输入高电平+按住按键不放,然后上电,进入AT模式,不过AT指令只能输入一次,下次再输入AT需要重新进入 2.串口波特率设为38400,进行AT模式下的指令操作 3.基本AT指令 ...

  3. TransactionScrope 2

    继上一篇文章TransactionScrope 在做相应的变动时,发现可以重现ORA-14450错误,如: List<Thread> ls = new List<Thread> ...

  4. MyEclipse 2014 破解版下载:我有,需要的给我说一声,给你发过去

    1.破解版的,需要的在下面给我说一声,云盘给你发过去.

  5. java之集合Collection详解之3

    package cn.itcast_03; public class Student { // 成员变量 private String name; private int age; // 构造方法 p ...

  6. 发布版本Debug和Release的区别

    1.Debug是调试版本不会对项目发布的内容进行优化,并且包含调试信息容量会大很多 2.Release不对源代码进行调试,对应用程序的速度进行优化,使得发布的内容容量等都是最优的

  7. 带事件的Bootstrap模态框的使用2

    模态框中显示一些基本的数据以及触发一些基本的JS函数 <%@ page language="java" contentType="text/html; charse ...

  8. 将csv的数据导入mysql

    手头有一份8MB的CSV文件需要分析,对于程序员来说,还有比在数据库里分析更愉快的事情吗? 所以让我们把CSV导入MYSQL吧. 一.首先按照文件列数创建相应的SQL表 例如: DROP TABLE ...

  9. bootsrtap h5 移动版页面 在苹果手机ios滑动上下拉动滚动卡顿问题解决方法

    bootsrtap h5 移动版页面 在苹果手机ios滑动上下拉动滚动卡顿问题解决方法 bootsrtap框架做的h5页面,在android手机下没有卡顿问题,在苹果手机就一直存在这问题,开始毫无头绪 ...

  10. ASP&period;NET AJAX入门系列(11):在多个UpdatePanle中使用Timer控件

    本文将使用Timer控件更新两个UpdatePanel控件,Timer控件将放在UpdatePanel控件的外面,并将它配置为UpdatePanel的触发器,翻译自官方文档. 主要内容 在多个Upda ...