MSSQL内存架构及管理
1. MSSQL内存架构
相比较Oracle,MSSQL的内存区域并没那么清晰,但和Oracle类似,MSSQL内存区域大体也可以分为三个部分:buffer pool,query/workspace memory,其他cache/memory。下面,我们分别对这三个内存区域做简要介绍:
1) Bufferpool:
Buffer pool 作为MSSQL内存主要组件之一,其包括和管理MSSQL的数据缓冲。其中,buffer pool 中的每个buffer为8k大小的内存页(当然,MSSQL 64位系统上也支持large page,这里不做讨论,感兴趣的同学可以参考其他文档),与数据或索引页大小相同,这样,整个buffer pool就由这种8k大小的buffer组成。可以通过以下SQL语句来查询各数据库的buffer pool信息:
select database_id
,case database_id
when 32767 then 'resourcedb'
else db_name(database_id)
end as 'database'
,count(*)*8/1024 as 'cached size (MB)'
from sys.dm_os_buffer_descriptors
group by db_name(database_id),database_id
order by 'cached size (MB)' desc;
2) Query/workspacememory:
类似Oracle的PGA,MSSQL中,query memoy(也称为workspace memory)用于存储查询执行时哈希和排序期间的临时结果。虽然大家都知道Oracle的PGA,但MSSQL的query memory也许并没有太多文档可读,因此,也并没有太多人清楚和知道,包括MSSQL的background process,memory components等内部的一些细节和内容,都是这种现状,这也许和多方面因素相关,这里不做太多的探讨。但是,当你仔细的查看MSSQL中SQL语句的查询计划时,你会清楚的看到hash和sort等操作相关的query memory内容。
Query memory的分配出自buffer pool,因为,MSSQL内存管理器非常清楚其内存的整个分配和使用情况,这点也许和Oracle的PGA有点不同,因为,Oracle为进程模型,在其buffer pool和PGA之间转换和分配可能会比MSSQL更加复杂些,这也是MSSQL线程模型的特点和优势,关于这点,大家自己思考吧,这里不做过多的阐述。
Query memory空间可以占到buffer pool大小的25%和75%之间,但是,当buffer pool不存在内存压力时,query memory也可以进一步增长。对于所有代价低于3和query memory需求低于5M的小查询,其query memory可以为之保留整个query memory5%的空间。单个查询最多能占到整个query memory的20%以保证其他查询的正常执行,这点来说,与Oracle的PGA非常类似。可以通过以下SQL语句来获取查询语句的query memory及相关授权情况:
select session_id,sql_handle,grant_time,requested_memory_kb
,granted_memory_kb,used_memory_kb
from sys.dm_exec_query_memory_grants
order bygranted_memory_kb desc;
select sum(isnull(requested_memory_kb,0))requested_memory_kb
,sum(isnull(granted_memory_kb,0))granted_memory_kb
,sum(isnull(used_memory_kb,0))used_memory_kb
from sys.dm_exec_query_memory_grants
orderby granted_memory_kb desc;
3) 其他cache/memory:
MSSQL内存区域,除了上面讲述的buffer pool和query/workspace memory外,剩下的那就是其他cache/memory部分,该部分内存用于MSSQL中所有不能放于前述两个内存区域的内存组件。这部分虽然不像Oracle中定义的那么清晰,但基本相当于Oracle中的SGA中除去buffer pool外的其他组件,这其中,主要是shared pool。该部分区域,虽然占据的内存不多,但包含众多的内存组件,也很重要。我们可以通过以下SQL语句来查询其相关信息:
select [name],[type],pages_kb,entries_count
from sys.dm_os_memory_cache_counters
order by pages_kb desc;
此外,log cache/buffer也是大家比较关心的一个内存组件,相较于Oracle来说,MSSQL对这个内存区域的持比较保守的态度,不管是官网还是其他资料,对这块区域都未曾提及。Oracle中,我们既可以很容易的查看该区域的大小,也可以很容易的对该区域大小进行配置和更改;然而,MSSQL中该区域则是截然相反,我们对该区域既不能查看,也不能修改,真相估计也只有微软内部清楚。纵观所有可以查阅的资料,我们只是知道,MSSQL实例中的每个数据都有一个log cache/buffer,其为一段连续的内存区域,其大小并不固定,最大大小不过60k,用户不能干预该区域的管理和设置,该区域由MSSQL实例自动动态管理,仅此而已,也希望有清楚和知道这部分机制和管理配置方法的同学随时联系和讨论,先谢谢了。
2. 动态内存管理
MSSQL默认的内存管理行为动态内存管理,即在不造成系统层面内存短缺的前提下,尽可能多的获取其所需的内存,MSSQL通过windows的内存通知APIs来实现这点。这点来讲,和Oracle11g的AMM非常相似,只不过,MSSQL几乎一直是这种内存管理方式,而Oracle则是在11g之后的版本才实现,这其中涉及进程模型及内存共享实现方面的内容和细节,这里不再深入探讨。
当MSSQL启动时,将会基于各种因素(像:系统上的物理内存,服务器线程数,以及各种启动参数等)计算MSSQL进程地址空间的大小,MSSQL将会保留这个计算出大小的内存空间,但它仅仅获取当前负载需要的物理内存空间。
接下来,当更多用户连接和运行查询时,为了支撑更多的负载,MSSQL会按需获取另外的物理内存。MSSQL实例会继续获取物理内存,直到达到它的max server memory目标,或者windows通知不再有额外的自有内存可用,此时,如果实例获取的内存大于min server memory且windows通知自由内存短缺时,则MSSQL会释放内存。
Min server memory和max server memory配置选项建立了MSSQL实例所用内存的上下限。MSSQL并不会立即获取min server memory确定大小的内存,开始仅仅获取实例初始化所需大小的内存,此后,随着MSSQL实例上负载的增加,其不断获取内存以支撑这些工作负载,期间,MSSQL实例内存达到min server memory前不会释放任何已获取的内存,一旦达到min server memory值后,MSSQL实例会利用其内部内存相关算法按需获取和释放内存,和之前不同的是,MSSQL实例不再会释放内存至min server memory确定值之下,也不会获取内存至max server memory确定值之上。
实际上,MSSQL2012之前的版本中,min/max server memory并非指MSSQL实例所占用和管理的所有内存,而仅仅是指MSSQL实例中的buffer pool大小,而MSSQL实例的其他内存组件则在此之外,而MSSQL2012之后的版本中,这一切发生了变化,min/max server memory几乎包括了MSSQL实例所占用和管理的所有内存,MSSQL实例完全根据其上负载按需动态的获取和释放内存。
当运行MSSQL实例的同一计算机上其他应用启动时,它们会消耗内存且自由物理内存降到MSSQL内存目标值以下时,MSSQL实例开始调整自己的内存消耗。当其他应用停止且更多内存变得可用时,MSSQL实例开始增加它的内存分配。MSSQL实例每秒钟能释放和获取数MB的内存,以便迅速的调整内存分配。至于MSSQL实例内存使用方面的信息,可以通过以下SQL来查询:
select name,value,value_in_use,[description]
from sys.configurations
where namelike'%server memory%'
order by name;
select physical_memory_in_use_kb,locked_page_allocations_kb,
page_fault_count,memory_utilization_percentage,
available_commit_limit_kb,process_physical_memory_low,
process_virtual_memory_low
from sys.dm_os_process_memory;
MSSQL内存架构及管理的更多相关文章
- Linux性能及调优指南1.2之Linux内存架构
本文为IBM RedBook的Linux Performanceand Tuning Guidelines的1.2节的翻译原文地址:http://www.redbooks.ibm.com/redpap ...
- 【公开课】《奥威Power-BI基于微软示例库(MSSQL)快速制作管理驾驶舱》文字记录与反馈
本期分享的内容: <奥威Power-BI基于微软示例库(MSSQL)快速制作管理驾驶舱> 时间:2016年11月02日 课程主讲人:叶锡文 从事商业智能行业,有丰富的实施经验,擅长 ...
- Spark Tungsten揭秘 Day3 内存分配和管理内幕
Spark Tungsten揭秘 Day3 内存分配和管理内幕 恭喜Spark2.0发布,今天会看一下2.0的源码. 今天会讲下Tungsten内存分配和管理的内幕.Tungsten想要工作,要有数据 ...
- 企业架构研究总结(27)——TOGAF架构开发方法(ADM)之架构变更管理阶段
1.10 架构变更管理(Architecture Change Management) 企业架构开发方法各阶段——架构变更管理 1.10.1 目标 本阶段的目标是: 确保基线架构持续符合当前实际. 评 ...
- TOGAF架构开发方法(ADM)之架构变更管理阶段
TOGAF架构开发方法(ADM)之架构变更管理阶段 1.10 架构变更管理(Architecture Change Management) 企业架构开发方法各阶段——架构变更管理 1.10.1 目标 ...
- Java 内存模型和硬件内存架构笔记
前言 可跟<主存存取和磁盘存取原理笔记>串着看 https://blog.csdn.net/suifeng3051/article/details/52611310 杂技 Java 内存模 ...
- C/C++内存分配和管理
1. 内存分配和管理 1.1 malloc.calloc.realloc.alloca malloc:申请指定字节数的内存.申请到的内存中的初始值不确定. calloc:为指定长度的对象,分配能容纳其 ...
- Java并发编程里的volatile。Java内存模型核CPU内存架构的对应关系
CPU内存架构:https://www.jianshu.com/p/3d1eb589b48e Java内存模型:https://www.jianshu.com/p/27a9003c33f4 多线程下的 ...
- SpringCloud分布式架构权限管理
概述 本文讨论分布式架构权限管理的两种情况,一种是针对统一授权访问的,一种是跨平台接口访问的. 虽然分布式架构会做业务的切割,将整体的业务切割为独立的子业务或者子平台,但是同一平台下往往会有统一的授权 ...
随机推荐
- http协议的状态码解释
一些常见的状态码为: 200 – 服务器成功返回网页 404 – 请求的网页不存在 503 – 服务器超时 下面提供 HTTP 状态码的完整列表.点击链接可了解详情.您也可以访问 HTTP 状态码上的 ...
- IOS学习笔记一1
//创建.h文件 界面的类文件(创建一个类) @interface MyClass:NSObject{ //类变量声明 int a; int b; } //类属性声明 (int) p2 //类方法声明 ...
- 理解 Redis(7) - Set 值
unordered collection of unique strings.set值是唯一的字符串的无序集合, 把握住两个特点: 唯一, 无序. 清空所有的数据, 并清理显示界面: 127.0.0. ...
- Codeforces 242 E. XOR on Segment
题目链接:http://codeforces.com/problemset/problem/242/E 线段树要求支持区间求和,区间内每一个数字异或上一个值. 既然是异或,考虑每一个节点维护一个长度为 ...
- python 加密
https://github.com/duanhongyi/gmssl
- leecode第七十题(爬楼梯)
class Solution { public: int climbStairs(int n) { vector<unsigned long long> num;//斐波那契数列 num. ...
- 学习笔记28—Python 不同数据类型取值方法
1.array数据类型 1)-------> y[i,] 或者 y[i] 2.遍历目录下所有文件夹: def eachFile(filepath): pathDir = os.list ...
- java线程执行的优先级
1.1 线程的优先级 java 中的线程优先级的范围是1-10,默认的优先级是5.10极最高. 有时间片轮循机制.“高优先级线程”被分配CPU的概率高于“低优先级线程”.根据时间片轮循调度, ...
- Python 常见时间处理
Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能. Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间. 时间间隔是以秒为单位的浮点小数. ...
- 第 6 章 存储 - 042 - 用 volume container 共享数据
volume container volume container 是专门为其他容器提供 volume 的容器.它提供的卷可以是 bind mount,也可以是 docker managed volu ...