SQL SERVER 内存学习系列(一)
最近帮客户解决发布订阅的问题时,突然遇到这样一个问题发布订阅中报下面的错误,另外执行alter table 操作时也会报错 :
问题很奇怪发布订阅和CLR有什么关系?memtoleave内存是个啥?回忆学习体系架构的时候,确实看到过memtoleave内存,但是是什么已经完全想不起来了,所以拿起书本回味一下学习的快感...
---------------转载请注明出处------------http://www.cnblogs.com/double-K/p/5049417.html--------------------
抛开问题我们先看一下SQL SERVER的内存结构:
1.从操作系统层面看SQL SERVER内存分配:windows 和SQL SERVER的关系就像君与臣一样,windows的统治下SQLSERVER和其他应用如notepad并无两样,当操作系统级别都内存紧张的时候SQL SERVER的内存一样会紧张。所以了解WINDOWS的内存结构同样重要。
- Virtual Address Space (虚拟地址空间)
- Physical Memory (物理内存)
- Reserved Memory (保留内存)
- committed Memory (提交内存)
- Shared Memory (共享内存)
- 等等好多种有兴趣的可以自己看一下
2.SQL SERVER内存的使用分类:
- 按用途:
- database cache :存放数据页面的缓冲区,SQL SERVER数据库里的数据都是以8KB为一个页面存储的,当有用户需要使用到这个页面的时候SQL SERVER就会把整个也都调入内存。所以8KB是数据访问的最小单元。
- 各类consumer :SQL SERVER各类组件,他们必须申请内存来支持他们完成工作,如:SQL SERVER需要为每一个连接分配一个数据结构,存储关于连接的信息,还会分配输入和输出的缓冲池(客户发送的指令/指令所获取的结果,等待客户端取走),语句的缓存计划等等。
- 线程内存 : SQL 会为进程内的每个线程分配0.5MB的内存,用以存放线程内的结构和相关信息。
- 第三方代码申请的内存 : 如CLR、LINKEDSEVER、COM等,这部分内存一般不会很大,但是假如一个linked server的分布式查询需要从远端取回大量的数据,那么这块内存就会使用的很大。所以这块内存的监视也不能忽视。
- 按申请方式 :
- 预先reserve 一块大内存,然后在使用的时候一小块一小块的commit
- 直接从地址空间申请commit,这种方式成为stolen。(AWE功能无效,扩展出来的内存只能用于database cache,其他还是需要在2GB里解决)
- 按申请大小 :
- 小于等于8KB (buffer pool)
- 大于8KB (multi-page 2008以前叫memtoleave)
- 按用途:
我们以按照大小的分类作为说明:申请小于等于8KB 这些页面都集中管理,这块内存称为 buffer pool,另一部分申请大于8KB的称为multi-page(memtoleave),memtoleave这块区域的内存分配很大一部分不受SQLSERVER本身控制,或者可以说只在SQL SERVER内部分配,但是却是由加载在SQL SERVER内部的其他DLL来分配的,如CLR。
32位的年代启动时需要保留我们配置需要的memtoleave大小(包含worker thread所需)的地址空间,然后把其他的都给buffer pool。
64位时代以后由于地址空间可以理解为无限大,所以SQL SERVER不再控制memtoleave这段空间的大小,甚至已经可以抢夺database cache了。
以一个表格总结一下:
类型 | database cache | consumer | 第三方代码 | threads |
reserved/commit | 是 | 一般不是 | 一般不是 | 不是 |
stolen | 不是 | 是 | 是 | 是 |
buffer pool | 所有 | 绝大部分 | 没有 | 没有 |
memtoleave | 没有 | 一小部分 | 所有 | 所有 |
---------------转载请注明出处------------http://www.cnblogs.com/double-K/p/5049417.html--------------------
简单的说明了一下SQL 的内存,有几点需要注意的也简单提一下:
1.WINDOWS不缺内存SQL 就不会缺内存吧?
答:这个是很错误的(1)如果是32位,由于虚拟地址空间的限制SQL 可能无法继续申请内存。有人会说我可以开AWE,前文也提到过AWE不是万能的,有64位为什么还要选32位呢? 对吧。(2)SQL SERVER很可能设置了max server memory约束了SQL 继续申请内存的能力,这个真遇到过,256G内存的服务器 max server memory 被设置成了2个G。
2.我们设置SQL 的最大内存 为20G,为什么有的时候观察sql进程的内存使用会超过20G?是不是这个没用呢?
答:属性->内存->最大内存 (max server memory)设置的其实buffer pool的最大值,里面没有包含memtoleave这段空间的大小,所以有的时候会看到SQL 使用的内存超过了设置的max server memory
- 3.我这是一台SQL SERVER专用服务器所以不需要设置max server memory,内存都给SQL SERVER。
- 答:这个问题是好多用户遇到的问题,看似没有问题,但是忽略了一点 SQL SERVER是一个很喜欢内存的应用所以很可能吃掉大量内存导致windows系统没有足够内存使用,那么这时候君臣关系就体现的淋漓尽致了,君(windows) 要臣死(释放内存)臣不得不死呀...这个释放在一定程度上可不是单单让windows够用了,很可能导致SQL内存陡降,以致SQL 短时间假死(操作无响应),一般我比较推荐操作系统20% ,SQL SERVER 80%如果服务器还有其他应用还要在SQL 中减掉应用所占的内存。
---------------转载请注明出处------------http://www.cnblogs.com/double-K/p/5049417.html--------------------
说了这么多回到我开篇的问题上,为什么出现这个情况memtoleave内存不足呢?看完文章也许你已经有了答案。
我说一下我排查问题的步骤,当客户发给我报错截图的时候我第一反应必须是了解客户的环境,因为不能远程所以我询问了操作系统版本SQL 版本,补丁及内存设置等等...告诉我64位的WINDOWS SERVER2008 ,SQL SERVER2008R2,遗憾的是当时客户没有select @@version确认SQL 版本,我也理所当然的认为装的肯定是64位SQL SERVER呀!!经过翻阅资料网上寻找答案始终想不明白为什么会出现这个显现...最后再次要求客户确认SQL 版本时才发现64位操作系统竟然误安装32位SQL SERVER 这下问题瞬间明了。
这个32位memtoleave的内存初始是多大呢?256M + 256(个thread) X 0.5MB = 384MB,可以通过修改启动参数 + -g 1024 (分配1024MB)解决这个问题,但是这个问题的根本不是修改启动参数,这仅仅是表名现象,最终的操作必然是重新安装SQL SERVER x64 !!!当然这会对用户的应用造成很大的影响。
---------------转载请注明出处------------http://www.cnblogs.com/double-K/p/5049417.html--------------------
以为这个案例我突然发现自己的体系结构如此之脆弱...遇到问题虽然见过却没有完善的知识体系来支撑,所以准备再次学习一下SQL 内存篇!!同时也会奉上后续学习文章!!
哦了~~~
SQL SERVER 内存学习系列(一)的更多相关文章
- SQL SERVER 内存学习系列(二)-DMV查看内存信息
内存管理在SQL Server中有一个三级结构.底部是内存节点,这是最低级的分配器,用于SQL Server的内存.第二个层次是由内存Clerk组成,这是用来访问内存节点和缓存存储,缓存存储则用于缓存 ...
- SQL SERVER 内存学习系列
http://www.cnblogs.com/double-K/p/5049417.html http://blog.sina.com.cn/s/blog_5deb2f5301014wti.html ...
- SQL Server调优系列基础篇(并行运算总结)
前言 上三篇文章我们介绍了查看查询计划的方式,以及一些常用的连接运算符.联合运算符的优化技巧. 本篇我们分析SQL Server的并行运算,作为多核计算机盛行的今天,SQL Server也会适时调整自 ...
- SQL Server调优系列基础篇(并行运算总结篇二)
前言 上一篇文章我们介绍了查看查询计划的并行运行方式. 本篇我们接着分析SQL Server的并行运算. 闲言少叙,直接进入本篇的正题. 技术准备 同前几篇一样,基于SQL Server2008R2版 ...
- SQL Server调优系列基础篇(索引运算总结)
前言 上几篇文章我们介绍了如何查看查询计划.常用运算符的介绍.并行运算的方式,有兴趣的可以点击查看. 本篇将分析在SQL Server中,如何利用先有索引项进行查询性能优化,通过了解这些索引项的应用方 ...
- SQL Server调优系列基础篇(子查询运算总结)
前言 前面我们的几篇文章介绍了一系列关于运算符的介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符.有兴 ...
- SQL Server调优系列进阶篇(查询语句运行几个指标值监测)
前言 上一篇我们分析了查询优化器的工作方式,其中包括:查询优化器的详细运行步骤.筛选条件分析.索引项优化等信息. 本篇我们分析在我们运行的过程中几个关键指标值的检测. 通过这些指标值来分析语句的运行问 ...
- SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行)
前言 前面几篇我们分析了关于SQL Server关于性能调优的一系列内容,我把它分为两个模块. 第一个模块注重基础内容的掌握,共分7篇文章完成,内容涵盖一系列基础运算算法,详细分析了如何查看执行计划. ...
- SQL Server调优系列玩转篇二(如何利用汇聚联合提示(Hint)引导语句运行)
前言 上一篇我们分析了查询Hint的用法,作为调优系列的最后一个玩转模块的第一篇.有兴趣的可以点击查看:SQL Server调优系列玩转篇(如何利用查询提示(Hint)引导语句运行) 本篇继续玩转模块 ...
随机推荐
- 使用angularJS遇见的一些问题的解决方案
1. angularJS的$http.post请求,SpringMVC后台接收不到参数值的解决方案 问题一般为:400 Required String parameter 'rPassword' is ...
- workflow GetListIdByName 获取表名
1.Assign 获取表的地址 和表名 2.HttpsendWithSuspend==HttpSend 3.ParseDynamicValue 4.GetDynamicValuePropertie ...
- css例子
6.背景图像渐变的制作body{ background:#ccc url(xxx.gif)rpeat-x或y:} 7.给一个区块加上背景#branding{ width:700px: height:2 ...
- 韩服LOL
※◆☆★☆◆※欢迎使用韩服LOL辅助,如有疑问请联系作者QQ:82850696*2*测试版已停用*1*2014-8-27 14:05:59*哈密*E2873D0137C6D04F42E088AA46E ...
- Android手机编程初学遇到的问题及解决方法
对高手来讲不值一提,可是对我这个初学来讲却是因为这些问题费了老长时间,有的不是编程问题,但不注意也会浪费不少宝贵时间!随时遇到随时更新... 引入第三方类库的问题,开始引用后没什么问题,但发现了该类库 ...
- c# json转换实例
用户实体: public class UserModel { public long? UserId { get; set; } public string UserName { get; set; ...
- HTML5 Web Worker的使用
Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面. 一:如何使用Worker Web Wo ...
- .Net Web项目安装包制作 (一)
来源:http://www.cnblogs.com/huxj/archive/2010/09/10/1823637.html
- 复星昆仲杨光:VR行业四大痛点
2016年,可是说是VR产业的爆发之年,从公司层面到资本层面都对VR产业给予了厚望,期望其能够在移动互联网之后带来革命性的突破,掀起新一轮技术主导的商业革命.而创业者们已经跃跃欲试,期望在资本的支持下 ...
- 【九度OJ】题目1061:成绩排序
题目描述: 有N个学生的数据,将学生数据按成绩高低排序,如果成绩相同则按姓名字符的字母序排序,如果姓名的字母序也相同则按照学生的年龄排序,并输出N个学生排序后的信息. 输入: 测试数据有多组,每组输入 ...