笔记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