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内存架构及管理的更多相关文章

  1. Linux性能及调优指南1.2之Linux内存架构

    本文为IBM RedBook的Linux Performanceand Tuning Guidelines的1.2节的翻译原文地址:http://www.redbooks.ibm.com/redpap ...

  2. 【公开课】《奥威Power-BI基于微软示例库(MSSQL)快速制作管理驾驶舱》文字记录与反馈

        本期分享的内容: <奥威Power-BI基于微软示例库(MSSQL)快速制作管理驾驶舱> 时间:2016年11月02日 课程主讲人:叶锡文 从事商业智能行业,有丰富的实施经验,擅长 ...

  3. Spark Tungsten揭秘 Day3 内存分配和管理内幕

    Spark Tungsten揭秘 Day3 内存分配和管理内幕 恭喜Spark2.0发布,今天会看一下2.0的源码. 今天会讲下Tungsten内存分配和管理的内幕.Tungsten想要工作,要有数据 ...

  4. 企业架构研究总结(27)——TOGAF架构开发方法(ADM)之架构变更管理阶段

    1.10 架构变更管理(Architecture Change Management) 企业架构开发方法各阶段——架构变更管理 1.10.1 目标 本阶段的目标是: 确保基线架构持续符合当前实际. 评 ...

  5. TOGAF架构开发方法(ADM)之架构变更管理阶段

    TOGAF架构开发方法(ADM)之架构变更管理阶段 1.10 架构变更管理(Architecture Change Management) 企业架构开发方法各阶段——架构变更管理 1.10.1 目标 ...

  6. Java 内存模型和硬件内存架构笔记

    前言 可跟<主存存取和磁盘存取原理笔记>串着看 https://blog.csdn.net/suifeng3051/article/details/52611310 杂技 Java 内存模 ...

  7. C/C++内存分配和管理

    1. 内存分配和管理 1.1 malloc.calloc.realloc.alloca malloc:申请指定字节数的内存.申请到的内存中的初始值不确定. calloc:为指定长度的对象,分配能容纳其 ...

  8. Java并发编程里的volatile。Java内存模型核CPU内存架构的对应关系

    CPU内存架构:https://www.jianshu.com/p/3d1eb589b48e Java内存模型:https://www.jianshu.com/p/27a9003c33f4 多线程下的 ...

  9. SpringCloud分布式架构权限管理

    概述 本文讨论分布式架构权限管理的两种情况,一种是针对统一授权访问的,一种是跨平台接口访问的. 虽然分布式架构会做业务的切割,将整体的业务切割为独立的子业务或者子平台,但是同一平台下往往会有统一的授权 ...

随机推荐

  1. SpringMVC+fastjson项目配置

    首先这个项目得是maven项目,不是maven项目的自己引包,我就不多说了. <!-- https://mvnrepository.com/artifact/org.springframewor ...

  2. docker 日志分析

    日志分两类,一类是 Docker 引擎日志:另一类是 容器日志. Docker 引擎日志 Docker 引擎日志 一般是交给了 Upstart(Ubuntu 14.04) 或者 systemd (Ce ...

  3. Intent 类型

    Intent 分为两种类型: 显式 Intent:按名称(完全限定类名)指定要启动的组件. 通常,您会在自己的应用中使用显式 Intent 来启动组件,这是因为您知道要启动的 Activity 或服务 ...

  4. http与https的区别以及https如何保证数据传输安全

    http是应用层协议,它会将要传输的数据以明文的方式给传输层,这样显然不安全.https则是在应用层与传输层之间又加了一层,该层遵守SSL/TLS协议,用于数据加密. **加密的方式有两种: 对称加密 ...

  5. 对前台传过来的实体是否为空 进行为空校验的N种方法

    首先定义一个注解,如下 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import j ...

  6. MySQL 并发测试中,线程数和数据库连接池的实验

    我一直以来,对性能测试中,连接池的大小要如何配置,不是太清楚: 就我所知道的,就DB自带对连接数的限制,在sqlserver中用select @@connection 可以查到, 在代码中,可以配置D ...

  7. module.exports小程序模块化,require

    小程序模块化 可以将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块.模块只有通过 module.exports 或者 exports 才能对外暴露接口. tips:exports 是 mo ...

  8. 文件编码检测.ZC

    1.今天(20181101) 发现 g文件中的 xml头 和 文件编码不一致,最后发现 貌似是我搞错了,人家的文件 编码方式写的是对的. 我发现的现象是:XML里面写的是"GBK" ...

  9. dockerfile debian 和pip使用国内源

    python官方镜像是基于debian的.国内使用时定制一下,加快下载速度. 1 debian本身使用国内源 dockfile中: #国内debian源 ADD sources.list /etc/a ...

  10. P359 usestock2.cpp

    IDE Qt Creator 4.0.3 stock.h #ifndef STOCK_H #define STOCK_H #include <string> class Stock //类 ...