分类: Oracle
最近一台装有Rhel5.3的40G内存的机器上有一个oracle数据库,数据库的SGA设置为20G,当运行业务时,一个业务高峰期时,发现swap频繁交换,CPU 100%,Load很高,基本体现为内存不足。此时的连接数在600个左右。按内存的计算:每个连接占用内存基本在5M,这样600个连接只占用3G内存,SGA内存20G,操作系统占用内存1G,这样总占用的内存为24G,而总共内存有40G,怎么会内存不足呢?当时是百思不得其解,于是做了大量的压力测试,首先是写了一个java程序,启动多个线程,每个线程与数据库建一个连接,然后循环运行一个简单的SQL,这个SQL按一个随机函数生成的ID去查询一个很大的表(有索引)。当启动1000个连接后,使用free -m查看内存: #free -m total used free shared buffers cached Mem: 40210 25842 14368 0 9 177-/+ buffers/cache: 25655 14554Swap: 20481 479 20001 发现free的内存值很小,used的内存值为断增长,运行大约20分钟后,当free减少到40M左右的时候, 系统的CPU一下子到100%,Load从15升到600。 从这个结果看到,还是内存不足,当时还写了一个脚本,查看所有oracle进程的内存情况,也没有发现oracle进程占用内存太多。所以一直没有找到原因。 最后试着用cat /proc/meminfo查看内存时,终于找到了原因,没有加压力时,cat /proc/meminfo看到的结果为: root@xxxx:/proc/sys/vm>cat /proc/meminfoMemTotal: 41175744 kBMemFree: 27603324 kBBuffers: 36572 kBCached: 13006240 kBSwapCached: 232980 kBActive: 304448 kBInactive: 12990616 kBHighTotal: 0 kBHighFree: 0 kBLowTotal: 41175744 kBLowFree: 27603324 kBSwapTotal: 20972816 kBSwapFree: 20070348 kBDirty: 1232 kBWriteback: 0 kBAnonPages: 240500 kBMapped: 354120 kBSlab: 136980 kBPageTables: 34004 kBNFS_Unstable: 0 kBBounce: 0 kBCommitLimit: 41560688 kBCommitted_AS: 17163928 kBVmallocTotal: 34359738367 kBVmallocUsed: 273756 kBVmallocChunk: 34359464051 kBHugePages_Total: 0HugePages_Free: 0HugePages_Rsvd: 0Hugepagesize: 2048 kB 当压力上来时: root@bopspri:/proc/sys/vm>cat /proc/meminfoMemTotal: 41175744 kBMemFree: 375212 kBBuffers: 36444 kBCached: 13005200 kBSwapCached: 232984 kBActive: 16919192 kBInactive: 509908 kBHighTotal: 0 kBHighFree: 0 kBLowTotal: 41175744 kBLowFree: 375212 kBSwapTotal: 20972816 kBSwapFree: 20070340 kBDirty: 184 kBWriteback: 0 kBAnonPages: 4375088 kBMapped: 12889760 kBSlab: 168916 kBPageTables: 23005464 kBNFS_Unstable: 0 kBBounce: 0 kBCommitLimit: 41560688 kBCommitted_AS: 40413008 kBVmallocTotal: 34359738367 kBVmallocUsed: 273756 kBVmallocChunk: 34359464051 kBHugePages_Total: 0HugePages_Free: 0HugePages_Rsvd: 0Hugepagesize: 2048 kB 可以看到压力上来后, PageTables 占用的内存居然高达23G。PageTables是Linux下虚拟内存到物理内存中做映射时映射表占用的空间,这个映射表居然占用了这么大的内存,真让人不可思议。 为了解决这个问题,想到了Linux的大页管理,正常的页大小为4k,而大页管理的页大小为2M,通过大页管理后,映射表占用的空间将会大大减少。 于是把数据库停了,启动大页管理,给大页管理分配20G内存: echo 10240 > /proc/sys/vm/nr_hugepages 增加 root soft memlock -1 root hard memlock -1 oracle soft memlock -1 oracle hard memlock -1 把数据库的lock_sga改成true后,再做压力测试,系统终于能稳定运行了,free -m查看到的空闲内存一直空闲13G: root@xxxx:/etc/security>free -m total used free shared buffers cachedMem: 40210 26234 13976 0 20 184-/+ buffers/cache: 26029 14181Swap: 20481 479 20001
转载于:https://www.cnblogs.com/woxing/p/3854178.html