开发者社区> 嗯哼9925> 正文

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

简介:
+关注继续查看

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

在了解内存管理之前,通过 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;

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;
复制代码

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';

观察内存

  • 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)锁信息收集脚本汇编









本文转自匠心十年博客园博客,原文链接:http://www.cnblogs.com/gaochundong/p/everyone_is_a_dba_sqlserver_memory_management.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【计算机网络】计算机网络总览(超多图)
计算机网络是学习计算机的人必须要学习的基础,是非常非常的重要。在以后的面试当中这也是一定会被问到的重点。所以我们要重视起来。
5 0
文件找不到!
谈文件异常前,先要给各位复习一下磁盘 IO 的知识,说到 IO,就不得不提一下计算机的存储系统体系,主要分为 CPU、内存、磁盘,而磁盘又分为机械磁盘和固态硬盘。一般来说,离 CPU 越近,价格越贵,速度越快,容量越小;反之,离 CPU 越远,价格越便宜,速度越慢,容量越大,见下图。
4 0
Maven 仓库介绍 和 nexus 私服搭建
Maven 仓库 在 Maven 的术语中,仓库是一个位置(place)。 Maven 仓库是项目中依赖的第三方库,这个库所在的位置叫做仓库。 在 Maven 中,任何一个依赖、插件或者项目构建的输出,都可以称之为构件。 Maven 仓库能帮助我们管理构件(主要是 JAR ),它就是放置所有 JAR 文件(WAR,ZIP,POM 等)的地方。
6 0
Android Studio快捷键以及使用技巧
Android Studio快捷键以及使用技巧
4 0
Struts,你为何死不悔改!
上篇文章《诡异的字符串问题。。。》的问题已经解决了,我一直相信「团队力量的重要性」,虽然我不能保证加入群的每一个人都是乐于分享的同学,但我始终群里的各位同学总会慢慢被我们这种乐于分享的群氛围所影响。就以上篇文章为例,群里的 Univechige 同学专门给 IntelliJ IDEA 官方发邮件寻求原因,这便是一个好的开端,我相信有各位同学的共同维护,后面群氛围会越来越好。下面给出 IDEA 官方的答复,见下图。
5 0
解决bug:Android 更换新logo图标后,运行项目图标没有变化
解决bug:Android 更换新logo图标后,运行项目图标没有变化
3 0
JDK 11 是发布了,但收费吗?
自 9 月 26 日,Oracle JDK 11 正式版本发布以来,一直被大家所看好,因为它是继 6、7、8之后,第一个长期支持的版本「见下图」,而 9 、10 估计多半会夭折了。。。
4 0
如何使用滚动列表插件?
嗨!大家好,我是小蚂蚁。今天来分享一下小游戏制作工具中的滚动列表插件的使用方法。滚动列表在小游戏或者小程序中经常的会被用到,例如关卡选择列表,背包列表,信息展示列表等。滚动列表主要的作用是可以在一个有限的指定的范围内,展示大量的信息。
3 0
小白ECS使用体验
初次使用ECS,从使用原因,使用攻略,使用总结三方面进行阐述ECS服务器
5 0
+关注
4716
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载