笔记26-徐 SQLSERVER内存分配和常见内存问题

笔记26-徐 SQLSERVER内存分配和常见内存问题

  1 --SQLSERVER内存分配和常见内存问题
  2 
  3 --SQLOS:SQL 把他对系统资源调度尤其是对内存和CPU的调度的功能组件,称为SQLOS
  4 --SQL是一个非常喜欢用内存的应用,如果内存不够,SQL一定会运行得非常艰难
  5 --而且在内存使用上,容易出的问题也比较多
  6 
  7 
  8 --1、SQL所占用的内存数量从启动以后,就不停地增长
  9 
 10 --2、在Windows2003以上版本运行SQL,内存使用量突然急剧下降
 11 --errorlog:
 12 --spid1 a singnificant part of sqlserver process memory has been paged out
 13 --this may result in a performance degradation 退化降级
 14 --duration:0 seconds working set:1086400  commited:2160928 memory utilization:50%
 15 
 16 --这类问题不是SQL自己导致的,而是Windows感觉到急迫的内存压力,迫使SQL释放内存
 17 
 18 
 19 --3、用户在做操作时,遇到内存申请失败
 20 --错误号:701(SQL2005或以上)     17803(SQL2000)    
 21 --    8645(2000、2005)         17802(SQL2000)           17189(SQL2005或以上)
 22 --SQL内存分成很多部分,不是用户想申请多少就申请多少的
 23 --在内存分配上,SQL2005比SQL2000有了更明显的变化。SQL2000简单一些,SQL2005依然使用
 24 --SQL2000的整体框架结构,但有了更复杂的实现方式。所以SQL2005以后的内存问题比SQL2000
 25 --相比有了一些变化。
 26 
 27 
 28 --4、内存压力导致的性能下降
 29 --如果内存紧张,SQL会马上作出反应,进行自我调节,所以申请内存失败的几率
 30 --不是太高。但是内存对性能的影响会非常显著。同一条语句,在内存充裕和
 31 --紧张的情况下,速度可能会相差几十倍,甚至上百倍。通过性能监视器和
 32 --动态管理视图来解决内存压力
 33 
 34 
 35 --从操作系统层面看SQL内存分配
 36 --各个应用程序包括SQL,都在通过VirtualAlloc之类的API向Windows申请内存。
 37 --SQL申请内存都是通过一些公开的API完成的,Windows不会给SQL任何特殊照顾
 38 
 39 --系统不缺内存不代表SQL就一定不缺内存
 40 
 41 --Windows的一些内存术语
 42 --虚拟地址空间virtual address space
 43 --寻址空间最大是4GB ,在缓存文件paging file  跟物理内存里
 44 
 45 --物理内存physical memory
 46 --频繁访问的数据对象放在物理内存里,达到最优化
 47 
 48 --保留内存reserved memory
 49 --应用程序通过一些特殊API,首先保留一块内存地址空间,以供将来使用
 50 --如果某块地址已经被其他对象保留,你去访问他,就会收到一个访问越界(AV ACCESS VIOLATION)
 51 --错误,像WIN32的VirtualAlloc  和VirtualAllocEx之类的函数,就能提供这些功能
 52 --需要说明的是这里保留的只是虚拟地址空间上的一段地址,而不是真正的物理内存空间
 53 
 54 
 55 
 56 --提交内存commited memory
 57 --将预先保留的内存页面正式提交使用。提交的页面在访问时最终转换到物理内存
 58 --中的有效页面。也就是说,正式在物理内存中申请一段空间,向页面中存入数据
 59 
 60 --分两步来预留和提交内存,通过推迟页面提交来减少物理内存的使用。对于
 61 --潜在、大量、连续的内存缓存区的应用程序是很有用的。地址空间可以被保留
 62 --在需要的时候再提交,而不是为了整个区域提交页面。这种技术在SQL中被
 63 --广泛使用,用以缓存数据页面
 64 
 65 
 66 
 67 --共享内存 share memory
 68 --共享内存定义为对一个以上的进程都是可见的内存,或存在于多个进程的虚拟地址
 69 --空间。例如,如果两个进程使用相同的DLL,只把DLL的代码页装入内存一次,其他
 70 --所有映射这个DLL的进程只要共享这些代码页就可以了
 71 
 72 --private bytes
 73 --某个进程提交的地址空间commited memory中,非共享的部分
 74 
 75 --working set
 76 --某个进程的地址空间中,存放在物理内存的那一部分
 77 
 78 --页面访问错误page fault soft/hard
 79 --访问一个存在于虚拟地址空间但不存在于物理内存working set的页面
 80 --就会发生一次page fault。
 81 --Windows内存管理组件会处理每个页面访问错误,首先判断是不是访问越界
 82 --如果不是,两种情况
 83 --hard fault:目标页面存在于硬盘上,例如page file,这种访问会带来硬盘的读写
 84 --soft fault:页面存在于物理内存中,还没有直接放在这个进程的working set下
 85 --需要Windows重新定向一次,这种访问不会带来硬盘操作
 86 
 87 
 88 --system working set
 89 --Windows的working set的类型:system cache  paged pool  non page pool  system mapped views
 90 --可以通过Windows性能监视器里的memory:cache bytes,发生在系统内存上的page fault 可以通过
 91 --memory :cache fault/sec 看到
 92 
 93 
 94 
 95 --系统高速缓存system cache
 96 --用于映射在系统高速缓存中打开的文件页面,以提供磁盘I/O速度。
 97 --性能监视器:memory:cache resident bytes 监控
 98 
 99 
100 --非换页区non paged pool
101 --包括一定范围的系统虚拟地址的内存交换区,保证在任何时候它都驻留在物理内存中
102 --可以在没有I/O调页的情况下从任何地址空间访问。非页交换区可以在系统初始化时
103 --创建,并且在内核模式组件用来分配系统内存。
104 --性能监视器:memory:pool nonpaged bytes 监控
105 
106 --这一块缓存可以被所有的进程共享,一个最常见的用途是存放所有对象的指针object handles
107 
108 --页交换区paged pool
109 --系统空间中可以调入或调出系统进程工作集working set的虚拟内存区域。页交换区在系统
110 --初始化时候创建,被内存模式组件用来分配系统内存。
111 --性能监视:memory :pool paged bytes  ,pool paged resident bytes 监控
112 
113 --栈stack
114 --每个线程有两个栈,一个给内核模式,一个给用户模式。每一个栈是一块内存空间。
115 --存放线程运行的过程或函数的调用地址,以及所有参数的值
116 
117 
118 --in process
119 --运行在同一个进程的地址空间里,例如一个进程需要加载一个DLL文件,这个DLL文件里
120 --的代码也会去申请内存.如果运行在同一个进程的地址空间里,最大的好处是速度快
121 --不需要做上下文切换context switch。但是明显缺点是DLL在内存使用上管理不善,
122 --出现严重错误会影响整个进程的安全性
123 
124 
125 --out of process
126 --运行在不同的进程地址空间里,以上面的DLL为例,像OLEDB这样的驱动程序可以配置
127 --成运行在DLLHOST.exe的进程空间里
128 
129 --内存泄漏memory leak
130 --一直不断地提交或保留内存资源,哪怕它们不再使用,也不释放给其他用户重用
131 --SQL的内存泄漏有两种:
132 --1、SQL作为一个进程,不断地向Windows申请内存资源,直到整个Windows内存耗尽
133 --2、SQL内部某个SQL组件不断地申请内存,直到把SQL能申请到的所有内存都耗尽
134 --使得其他SQL功能组件不能正常使用内存。
135 
136 --由于SQL完善的内存管理机制,前一种比较少见,而且问题往往不是SQL自身,常见的是
137 --后一种泄漏,而且这种泄漏与客户端的操作有直接关系
138 
139 
140 --32位下Windows地址空间和AWE
141 --32位Windows用户进程会有4G虚拟地址空间,其中2G给内核态,2G给用户态
142 --这两部分严格分开。Windows不会因为其中某一块内存地址空间用尽而将
143 --另外一块空间让出。
144 
145 --由于SQL的绝大部分指令都运行在用户态下,所以SQL的用户态地址空间资源也只有2G
146 

147 --在32位Windows中,2G地址空间使得SQL最多只能使用2G内存,严重阻碍了SQL有效利用硬件资源
148 
149 --方法一:在Windows2003的Boot.ini文件里使用/3GB参数
150 --企业版下使用这个参数,使得Windows将核心态地址空间由2G降到1G,将用户态空间由
151 --2G升到3G,加起来还是4G地址空间
152 --后果是大大缩小system cache里面的一些结构大小,导致核心态内存空间耗尽,而核心态出问题
153 --会影响整个服务器的稳定。
154 
155 
156 
157 --方法二:地址空间扩展address windowsing extensionsAWE。允许32位应用程序
158 --分配64G物理内存,并把视图或窗口映射到2G虚拟地址空间的机制
159 
160 --使用AWE,解决了2G地址空间的限制,使得一个应用程序能够访问最多达64G的物理内存
161 
162 --SQL2000的企业版,SQL2005/2008的企业版和标准版都支持这个技术,也能够享受
163 --这个技术带来的好处。
164 EXEC sys.sp_configure @configname = 'AWE Enabled', -- varchar(35)
165     @configvalue = 1 -- int
166 RECONFIGURE
167 GO
168 
169 --重启SQL服务即可
170 
171 
172 --(1)开启这个功能需要SQL启动帐户在Windows上的lock pages in memory权限。没有这个权限,
173 --AWE就不能成功被开启。启动的SQL这时候只能使用2GB的地址空间。
174 --所以DBA要确认一下SQL的errorlog里有没有相关的信息
175 --成功开启:server  Address Windowing Extensions enabled
176 --消息
177 --Address Windowing Extensions is enabled. This is an informational message only; no user action is required.
178 --开启失败:Cannot use Address Windowing Extensions because lock memory privilege was not granted
179 
180 --(2)这个功能是在应用层面有意识地使用,而不是在Windows层面实施的。也就是说SQL在申请内存时,
181 --通过特殊API调用申请到的,如果SQL不调用这个功能,就还会在普通的2GB虚拟地址空间申请内存。
182 --在SQL中不是所有的内存申请都会调用AWE技术,只有先reserve,再commit的内存调用,SQL才使用AWE
183 --让他们使用到扩展的内存。其他方式申请的内存只能使用普通的2GB地址空间。
184 
185 
186 --正因为这样,AWE不能称为解决SQL地址空间不足的最终解决方法。
187 --使用64位服务器,虚拟地址空间可以达到8TB,大于绝大多数物理内存数,我见过最多的物理内存128GB
188 --在64位下运行的SQL,其性能往往比在32位上有比较明显的提高。
189 
190 --各个版本Windows上支持的最大内存数
191 --配置                                               应用虚拟地址空间大小        最大物理内存数         是否支持AWE/locked pages support
192 --32位SQLSERVER                                              2GB                         64GB                   YES
193 --32位SQLSERVER    + /3GB boot.ini参数                       3GB                         16GB                   YES
194 --32位SQLSERVER   应用在x64位操作系统(WOW)                 4GB                         64GB                   YES
195 --32位SQLSERVER   应用在IA64操作系统(WOW)                  2GB                         2GB                    NO
196 --64位SQLSERVER   应用在x64操作系统                          8TB                         2TB TERABYTES          YES
197 --64位SQLSERVER   应用在IA64操作系统                         7TB                         2TB                    YES

 

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