笔记30-徐 SQLSERVER内存管理模式与接口

笔记30-徐 SQLSERVER内存管理模式与接口

  1 --SQLSERVER内存管理模式与接口
  2 
  3 
  4 --SQLSERVER是个很喜欢内存资源的程序,他的理想状态就是把所有可能会用到的数据和结构
  5 --都缓存在物理内存里,以达到最优的性能。
  6 
  7 --SQLSERVER会约束自己的内存使用量,但是最好作出合理的分配
  8 
  9 --SQL会缓存大量的数据页面,他还会缓存很多其他信息,包括存储过程的执行计划
 10 --特定用户的安全上下文等
 11 --如果这些信息没有在数据库中缓存,SQL都要重新计算一遍,花额外的时间
 12 
 13 --SQLSERVER开发出来的内存调节接口却很少,只有下面几个:
 14 
 15 --1、min server memory (MB)(sp_configure接口)
 16 --定义SQL的最小内存值 需要澄清亮点
 17 --(1)min server memory 是一个逻辑概念,控制SQLSERVER Total Server Memory的大小
 18 --至于数据是放在物理内存还是缓存文件里,由Windows决定。所以这个值不能保证SQL使用
 19 --的最小物理内存数
 20 
 21 --(2)min server memory 的意思是,在SQL的地址空间增长到这个值以后,就不会再小于这个
 22 --值。当SQL刚启动的时候,仅仅申请启动所需要的内存。所以这个时候内存使用量小于min server memory
 23 --也是正常现象
 24 
 25 
 26 
 27 --2、max server memory (MB)(sp_configure接口)
 28 --定义SQL的最大内存值 需要澄清亮点
 29 --(1)max server memory 也是一个逻辑概念,控制SQLSERVER Total Server Memory的大小
 30 --至于数据是放在物理内存还是缓存文件里,由Windows决定
 31 
 32 --(2)max server memory 只能控制SQL的一部分内存使用量,SQL的virtual bytes或working set大于
 33 --你设置的max server memory 也是一个正常现象。并不是SQL有内存泄漏问题
 34 
 35 
 36 --3、Set Working Set Size(sp_configure接口)
 37 --在SQL的执行代码中调用一个Windows参数,试图将SQL在物理内存中使用的内存数固定下来。
 38 --但是现在的Windows版本已经不再尊重这个请求。所以设置这个参数已经没有任何意义
 39 --有时候还会带来副作用,请不要使用
 40 
 41 --4、AWE Enabled(sp_configure接口)
 42 --让SQL开启用AWE方法申请的内存,以突破32位Windows2GB用户寻址空间。所以这个
 43 --设置对32位SQL意义重大。但是不是所有的SQL内存都会用AWE。AWE扩展出去的的地址
 44 --空间不是什么数据都能存放。这个也是为什麽32位AWE效果没有64位好的一个重要
 45 --原因。
 46 
 47 
 48 
 49 --5、lock pages in memory(企业版会自动开启)
 50 --这个开关是能在一定程度上确保SQL的物理内存数,但是不十分可靠。
 51 
 52 
 53 --调节SQL内存的使用参数比较有限。SQL有一套比较完善的内存自我管理调度机制,这是其他应用
 54 --软件难以企及的。绝大多数情况下,SQL能够很好做自我调节,满足用户需求,维护SQL性能优化
 55 
 56 
 57 
 58 
 59 ------------------内存使用分类--------------------------------------------------------
 60 --按用途分:
 61 
 62 --(1)database cache
 63 --1存放8KB数据页面的缓存区,8KB是数据访问的最小单元
 64 
 65 --2用户写数据到数据页面,等到checkpoint或lazy write才把数据页面写回硬盘
 66 
 67 --3用户使用完页面之后,SQL如果没有内存压力,不会马上删除页面,等以后用户
 68 --再访问这个页面,不用到磁盘读取。所有数据页面都缓存在内存里,等到checkpoint
 69 --的时候把修改过的页面写入硬盘
 70 
 71 
 72 
 73 --(2)SQL的很多功能组件都需要申请内存来完成他们的任务,功能组件简称:consumer
 74 
 75 --connection(连接池):SQL为每一个连接分配一个数据结构,存储关于这个连接的信息。另外还会分配一个
 76 --输入缓冲池,缓冲客户端发来的指令;一个输出缓冲池,存放SQL返回的结果集,等待客户端取走
 77 
 78 --general:一组大杂烩,包括:语句的编译、范式化、每个锁数据结构、事务上下文、表格、索引的元数据
 79 
 80 --query plan:语句和存储过程的执行计划。和database cache类似,如果SQL没有内存压力,他会保留每一个
 81 --生成的执行计划,供以后用户使用,减少编译消耗。所以执行计划也是一块比较大的内存使用区域
 82 
 83 --optimizer:SQL在生成执行计划的过程中需要消耗的内存
 84 
 85 --utilities:像BCP、log manager、paraller queries并行查询、backup等比较特殊操作需要的内存
 86 
 87 
 88 --(3)线程内存
 89 --SQL会为进程内的每个线程分配0.5MB的内存,以存放线程的数据结构和相关信息
 90 
 91 
 92 --(4)第三方代码申请的内存(COM,XP...)
 93 --在SQL进程里,会运行一些非SQL自身的代码。例如:用户定义CLR或扩展存储过程EXEC sys.xp_cmdshell
 94 --代码,链接服务器linked server需要加载的数据连接驱动,调用SQL Mail功能需要加载的MAPI动态库等。
 95 --这些代码运行也会申请内存,会算在SQL进程的虚拟地址空间里。但是由于他们不是SQL自身的代码,
 96 --所以他们申请了多少内存SQL自己都不知道(但是作为一个进程,Windows能够知道SQL申请的所有内存)
 97 --所以也能计算这一部分的内存使用
 98 
 99 
100 
101 
102 --按申请方式分类
103 --第一种:SQL内存申请预先reserve一块大内存,然后在使用时一小块一小块地commit
104 --第二种:内存申请直接从地址空间里commit ,这种称为stolen
105 
106 --database cache:预先reserve一块大内存,然后在使用时一小块一小块地commit
107 --其他:内存申请直接从地址空间里commit ,这种称为stolen,不是内存泄漏,也是正常使用
108 
109 --AWE扩展出去的内存只能用来存放database cache,其他内存还是要在2GB内存里想办法
110 
111 
112 --按申请大小分类
113 --SQL有两种内存申请单位
114 --1所有可以分成小于或等于8KB一个单位的内存申请,SQL会分配一个页面8KB。所有这些页面都集中管理,这块
115 --内存被称为BUFFER POOL,一次一个页面的分配称为single page allocation
116 
117 --2大于8KB单位的内存申请,SQL把他们集中在另外一个区域,成为multi-page/memtoleave,
118 --称为multi page allocation
119 
120 --对于SQL,大部分内存需求都可以以8KB为单位,放在buffer pool里
121 
122 --按用途分类:
123 --database cache:由于都是数据页面,所以都是以8KB为单位,存储在buffer pool里面
124 
125 --其他consumer:
126 --connection(连接池):和net work package size(客户端和SQL通信的每个数据包大小)有关系
127 --如果是默认4KB设置,输入输出缓存会放在buffer pool里,如果改成8KB或更大,输入输出缓存
128 --会放在 multi-page里
129 --net work package size的大小可以使用sp_configure来更改,但是任何一个客户端都可以指定
130 --他建立的连接自己的net work package size
131 
132 
133 --general:绝大部分内存,例如每个锁数据结构、事务上下文、表格、索引元数据等,都会以
134 --8KB为单位申请。但是如果偶尔一个语句特别长,他的编译和范式化需要使用大于8KB为单位
135 --的内存,会使用multi-page里的
136 
137 
138 --query plan、optimizer、utilities:和general类似,绝大部分内存使用会在buffer pool,
139 --一些特别长语句,会使用一部分的multi-page
140 
141 --第三方的代码:由于这些代码申请的内存大小SQL自己不知道,所以SQL把他们的内存申请放在
142 --multi-page
143 
144 --线程内存;每个以512KB为单位,自然放在multi-page里
145 
146 
147 
148 -- 各种内存分类方法之间的关系
149 --                              database cache      consumer           3rd party code         threads     CLR code
150 --reserved/commit                 是                一般不是             一般不是              不是         是
151 --stolen                          不是              是                     是                    是         不是
152 --buffer pool(single page)        所有               绝大部分             没有                   没有       没有
153 --memtoleave(multi page)          没有               一小部分             所有                  所有        所有
154 
155 
156 --各部分内存的分布和大小限制
157 
158 --在32位SQL里面,虚拟地址空间为2GB(除掉核心态的2GB)。这个2GB被SQL分成两部分:
159 
160 --8KB为单位的buffer pool也称BPool
161 
162 --不以8KB为单位分配的部分,memtoleave multi-page(之所以叫memtoleave,是因为SQL启动的时候会把这部分虚拟
163 --地址预留出来,地址空间是有上限的,SQL2005以上,memtoleave的默认大小是256MB加上sp_configure配置的最大
164 --线程数(服务器属性-》处理器-》最大工作线程数)乘以512KB,就是256MB+256(个threads)*0.5MB=384MB),
165 --剩下就是2GB-384MB=1664MB,就是buffer pool的最大值
166 
167 --线程内存:SQL进程为每个线程分配0.5MB的内存,以存放线程的数据结构和相关信息
168 
169 --SQL启动时buffer pool很少,随着缓存数据越来越多,SQL会不断commit内存给buffer pool,buffer pool
170 --大小达到max server memory或1664MB,SQL无法申请内存了
171 
172 --memtoleave也一样,但是他的上限是SQL启动时算出来的,跟max server memory无关
173 
174 
175 
176 --X64位系统 32位SQL:因为X64支持WOW,由于64位核心态已经不占用32位应用程序的进程的虚拟地址空间,所以
177 --WOW的32位应用程序进程用户态可以到4GB。memtoleave-MULTI-PAGE算法不变,还是默认的384MB。
178 --buffer pool可以达到3.6GB。如果开启了AWE,这3.6GB就可以基本都给buffer pool里的stolen memory使用了
179 
180 
181 --如果用户频繁使用linked server或扩展存储过程EXEC sys.xp_cmdshell等会使用multipage的功能
182 --multi-page会变得非常繁忙,SQL会先使用默认的那一块256MB。如果这里使用完了,SQL会看看预留给
183 --线程那一块内存是不是用完。一般SQL不会把256个线程都创建出来,所以这里还是有地方
184 --SQL会在这里存放multi-page的申请,直到把这一块内存用完
185 
186 --SQL会记录这些缓存被引用的次数,每个缓存页面和执行计划都有一个权值。每隔一段时间,权值减一
187 --当系统内存有压力时,SQL根据权值是0的那个缓存(即在一段时间没有被引用过)从内存里清理出去
188 --这个清理出去的动作由lazy writer完成,如果lazy writer经常被触发表明系统有内存压力
189 
190 --memtoleave multi-page里的执行计划也归这个机制管理,当buffer pool有压力时,memtoleave里的
191 --一部分缓存也会被清理出去
192 
193 
194 
195 --64位操作系统,SQL虚拟地址空间扩展了很多,不会再为multi-page预留一块地址空间。就没有了
196 --memtoleave这个概念。不管single page 还是multi page,都可以无约束地申请虚拟地址空间里的
197 --地址资源。所以在64位操作系统上会遇到一些32位不会遇到的问题
198 
199 
200 
201 
202 
203 -----------------------database cache的上限一般由max server memory来控制-------------------------------------------
204 
205 
206 --64位SQL,stolen内存没有限制,只要物理内存足够,buffer pool还没有达到max server memory的限制
207 --就可以不断地缓存执行计划,尤其是小型数据库内存量比较大的服务器,stolen内存数量一般会超过
208 --database cache的数量。这种变化DBA要注意

 

posted @ 2013-07-27 15:56  桦仔  阅读(627)  评论(0编辑  收藏  举报