Hugepage、VLM、SGA和Share memory:
from:http://space.itpub.net/231499/viewspace-366360
一、相关概念
Hugepage/Big page:
系统进程是通过虚拟地址访问内存,但是CPU必须把它转换程物理内存地址才能真正访问内存。为了提高这个转换效率,CPU会缓存最近的虚拟内存地址和物理内存地址的映射关系,并保存在一个由CPU维护的映射表中。为了尽量提高内存的访问速度,需要在映射表中保存尽量多的映射关系。
而在Redhat Linux中,内存都是以页的形式划分的,默认情况下每页是4K,这就意味着如果物理内存很大,则映射表的条目将会非常多,会影响CPU的检索效率。因为内存大小是固定的,为了减少映射表的条目,可采取的办法只有增加页的尺寸。这种增大的内存页尺寸在Linux 2.1中,称为Big page;在AS 3/4中,称为Hugepage。
如果系统有大量的物理内存(大于8G),则物理32位的操作系统还是64位的,都应该使用Hugepage。
注意:使用Hugepage内存是共享内存,它会一直keep在内存中的,不会被交换出去,也就是说使用hurgepage的内存不能被其他的进程使用,所以,一定要合理设置这个值,避免造成浪费。对于只使用Oracle的服务器来说,把Hugepage_pool设置成SGA大小即可。
VLM(Very Large Memory ):这个是要是针对32位的操作系统,对于64位操作系统,则需要设置VLM。在启用了Hugepage的情况下,32位的ORACLE可以把SGA扩展到62G。需要注意的是,VLM只对SGA中buffer cache有效,对shared pool、large pool、java pool等无效。
VLM的原理是把内存虚拟程一个文件,系统进程通过读取这个内存文件达到使用内存的目的。
如果ORACLE想要使用VLM,则必须设置参数use_indirect_data_buffers=true。如果是10g的数据库,还需要把db_cache_size转换成老版本的db_block_buffers,否则会报错。
当SGA使用VLM时,SGA对应的共享内存会分成两个部分:
. 普通的系统共享内存,也就是可以从ipcs -ma看到的部分,这部分主要对应非buffer cache的SGA(large pool/shared pool/java pool/streams pool)等。
. 基于内存文件的共享内存,这部分可以通过ls -al /dev/shm查看。这部分主要对应SGA中的data buffer部分。
注意:使用VLM时,用于非buffer cache部分的内存会保留512M用于管理VLM。如如果分配了2.5G给非buffer cache使用,实际上,只有2G的实际可用内存。
当使用VLM时,以上两个部分共享内存之和等于SGA。(如果不使用VLM,则SGA大小就等于ipcs -ma显示的大小基本一致)
下面举一个例子说明这四者的关系:
1、SGA相关
SQL> show sga
Total System Global Area 1879048192 bytes
Fixed Size 778452 bytes
Variable Size 802430764 bytes
Database Buffers 1073741824 bytes
Redo Buffers 2097152 bytes
-----非BUFFER CACHE部分
SQL> show parameter shared_pool_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
shared_pool_size big integer 512M
SQL> show parameter java_pool_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
java_pool_size big integer 32M
SQL> show parameter large_pool_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
large_pool_size big integer 128M
SQL> show parameter streams_pool_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
streams_pool_size big integer 80M
SQL> show parameter log_buffer
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
log_buffer integer 2097152
-----BUFFER CACHE部分
SQL> show parameter block_size
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_size integer 8192
SQL> show parameter db_block_buffers
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_buffers integer 131072
2、ipcs显示的大小
$ipcs -a
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0xf258e130 32769 oracle 600 807403520 0
0x00000000 65538 oracle 640 4096 0
------ Semaphore Arrays --------
key semid owner perms nsems
0x610520f4 98304 oracle 640 602
0x610520f5 131073 oracle 640 602
0x610520f6 163842 oracle 640 602
------ Message Queues --------
key msqid owner perms used-bytes messages
3、/dev/shm大小
$ls -al /dev/shm
total 120
drwxrwxrwt 1 root root 0 Feb 15 02:11 .
drwxr-xr-x 22 root root 118784 Feb 15 02:11 ..
-rw-r----- 1 oracle dba 1073741824 Feb 15 02:12 ora_test_65538
(shared_pool_size + java_pool_size + large_pool_size + streams_pool_size + log_buffer) = (512 + 32 + 128 + 80)*1024*1024+2097152=790626304 和ipcs的结果807403520基本一致。
131072*8192=1073741824 和ls -al /dev/shm的结果1073741824相等。
这个结果也验证了以上我们做的结论。
二、配置Hugepage
因为使用hugepage部分的共享内存不能被swap,也不能被其他进程使用,如果把hugepage共享内存设置过大,会导致系统hang住。
既要考虑性能,又要不浪费内存,一定要把使用hugepage部分的共享内存设置一个最佳值。下面的一些参考:
1) 如果是32位操作系统,且没有用VLM,则设置 hugetlb_pool=所有运行在该服务器上的实例SGA总和。如果有ASM,则每一个ASM实例再增加200M左右
2) 如果是32位操作系统,且使用了VLM,则设置 hugetlb_pool=所有运行在该服务器上的实例除data buffer外的SGA总和。如果有ASM,则每一个ASM实例再增加200M左右
3) 如果是64位操作系统,不管是否启用VLM,都设置 hugetlb_pool=所有运行在该服务器上的实例SGA总和。如果有ASM,则每一个ASM实例再增加200M左右
在RHEL 2.1/3/4设置Hugepage的方法各不一样,因为2.1版本太低,这里就不介绍了。
1、在RHEL3中设置hugepage
很简单,只需要在/etc/sysctl.conf添加如下行即可:
#设置1024M hugepage momory
vm.hugetlb_pool=1024
执行sysctl -p使得修改生效。
此时从/proc/meminfo中可以验证设置是否生效:
$more /proc/meminfo |grep -i HugePage
HugePages_Total: 512
HugePages_Free: 512
Hugepagesize: 2048 kB
因为设置的1024M的hugepage_pool,每页2M,所以会有512页。
理想情况下,当oracle实例启动后,HugePages_Free应等于或者接近0。
2、在RHEL4中设置hugepage
类似于RHEL3,在RHEL4配置hugepage也很简单,
1)在/etc/sysctl.conf添加如下行:
#设置1024M hugepage momory
vm.nr_hugepages=512
在RHEL4中,是直接设置hugepage的页数。
执行sysctl -p使得修改生效。
2) 在/etc/security/limits.conf 添加如下行
oracle soft memlock 1048576
oracle hard memlock 1048576
必须设置这个,否则启动数据库可能会报错:
ORA-27103: internal error
Linux Error: 11: Resource temporarily unavailable
此时从/proc/meminfo中可以验证设置是否生效:
$more /proc/meminfo |grep -i HugePage
HugePages_Total: 512
HugePages_Free: 512
Hugepagesize: 2048 kB
理想情况下,当oracle实例启动后,HugePages_Free应等于或者接近0。
如果不想设置hugepage,则设置vm.nr_hugepages=0即可。
有几点需要注意:
1) 无论RHEL3还是RHEL4,只要设置了hugepage_pool或者nr_hugepages,都意味着指定尺寸的内存被pin在内存中了。就算SGA需要的共享内存小于设置的hugepage_pool,这部分内存也无法被其他进程使用,所以,一定要计算好需要的大小,不宜设置过大的hugepage共享内存,避免浪费。
三、配置VLM
在RHEL3和RHEL4中,可以使用两种内存文件方式配置VLM:
. shmfs/tmpfs:这个内存文件方式会发生换页,与hugepage冲突,不适用于使用hugepage的内存管理方式。其中shmfs只适用于RHEL3,tempfs适用于RHEL3和RHEL4。
. ramfs:这种方式不会发生换页,可以与hugepage搭配使用。
要配置VLM,系统内核必须支持以上三种文件系统之一,可以用以下命令判断:
egrep "shm|tmpfs|ramfs" /proc/filesystems
如果结果有对应的条目输出,则表示支持该类型文件系统,如:
nodev tmpfs
nodev ramfs
表示内存支持tmpfs和ramfs两种内存文件系统。
下面以为一个32位的数据库配置8G大小的buffer cache为例说明如何在RHEL3/4中配置VLM(首先要保证内核支持并已经配置Hugepage)
1、挂载内存文件系统
umount /dev/shm
mount -t ramfs ramfs /dev/shm
chown oracle:dba /dev/shm
注意
1)为了重启后也生效,最好把以上几行写在/etc/rc.local里
2)如果oracle用户的主组不是dba,如是oinstall,则chown oracle:oinstall /dev/shm
2、修改oracle参数
use_indirect_data_buffers=true
db_block_size=8192
db_block_buffers=1048576
shared_pool_size=2831155200
3、修改oracle的资源限制
在/etc/security/limits.conf中设置memlock=3145728,也就是在该文件中添加如下两行:
oracle soft memlock 3145728
oracle hard memlock 3145728
用ulimit -l验证
使用VLM时:
1) 无论是什么版本,不能用db_cache_size参数,必须转换成对应的db_block_buffers和db_block_size
2) data buffer部分的共享内存来自VLM,但SGA的其他部分,如shared_pool使用的共享内存来自系统的普通共享内存。
3) kernel.shmmax的设置应大于等于除data buffer以外的其他SGA部件之和
4) 不必像设置hugepage_pool那样考虑要位data buffer设置多大的共享内存,操作系统会自动生成一个与设置的data buffer一样大小的内存文件
5) 即使hugepage足够大,data buffer需要的共享内存也不会从hugepage_pool中分配,而是使用VLM内存文件扩展共享内存段
6) 即使hugepage不足,非data buffer部分的SGA需要的共享内存也不会从VLM中分配,而是使用系统其他的空闲内存扩展共享内存段
最后做一个简单总结:
1、hugepage是为了提高内存的性能;VLM是为了使32位操作系统使用大内存
2、如果服务器上有大量物理内存:
如果是64位的操作系统,只需要设置hugepage即可,且可以使用db_cache_size这一新参数。
如果是32位的操作系统,需要配置hugepage和VLM,并且不能使用db_cache_size这一新参数。其中hugepage_pool设置为非buffer cache的内存总和大小。buffer cache对应的共享内存部分无需设置,OS会自动分配适当大小的内存文件作为共享内存。
/
Oracle的SGA与系统vm.nr_hugepages不匹配导致的故障:
from:http://www.linuxfly.org/post/516/
某项目,使用红旗DC Server 5.0 for x86_64 SP2,运行Oracle RAC 10.2.0.4。而应用服务器上的应用通过Oracle客户端来连接,为常连接的方式。当进行应用的压力测试时,发现数据库服务器在运行一段时间(约3个小时后),系统会失去响应。当做了大量的系统状态及内存使用情况的分析后,发现系统失去响应的原因是,Oracle不断的申请内存,直到内存消耗完所导致的。深究其原因,是由于系统的核心参数vm.nr_hugepages与SGA的大小不匹配,Oracle并没有使用HugePages来分配SGA,而是在不断的消耗系统其它内存。
一、故障现象
系统环境为:
操作系统: 红旗 DC Server 5.0 for x86_64 SP2
应用: Oracle RAC 10.2.0.4
当进行应用压力测试时,发现系统可用内存不断减少,这是一个逐步表现的过程,可通过下面的ps命令间隔一段时间,观察Oracle的某进程对内存的占用是否不断增加:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
oracle 3244 0.2 1.2 30865100 792376 ? Ss May12 0:21 oraclepostdbs1 (LOCAL=NO)
oracle 3244 0.2 1.2 30865100 838360 ? Ss May12 0:23 oraclepostdbs1 (LOCAL=NO)
oracle 3244 0.2 1.3 30865100 902184 ? Ss May12 0:25 oraclepostdbs1 (LOCAL=NO)
系统快失去响应前,内存状态为:
total used free shared buffers cached
Mem: 63839 63415 423 0 1 16387
-/+ buffers/cache: 47026 16812
Swap: 16002 971 15030
#vmstat -k 2
procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
25 0 991516 431400 788 16775636 54 0 59 1269 11004 21412 11 61 28 0
18 0 991444 431976 780 16775648 74 0 85 1551 13373 24064 10 49 42 0
10 0 991388 432848 780 16775200 50 0 117 2374 9521 23511 13 39 48 0
以上面的free显示为例,这里在核心中设置了核心的保留内存为400m:
可见,这时的系统可用内存已几乎消耗殆尽(上面设置的400m为核心保留,其它应用不能使用),并且,从vmstat可知,因物理内存不足,正在不断的进行页面交换,使用swap空间。由于正在进行压力测试,对系统的内存消耗压力很大,因此,从top状态,也会看到kswapd进程会一直占用CPU,以进行页面交换:
系统日志报:
May 9 08:02:19 gdracdb1 kernel:
May 9 08:02:19 gdracdb1 kernel: Free pages: 18728kB (0kB HighMem)
May 9 08:02:19 gdracdb1 kernel: Active:5925372 inactive:2669 dirty:62
writeback:0 unstable:0 free:4682 slab:60603 mapped:5925032
pagetables:6178345
May 9 08:02:19 gdracdb1 kernel: Node 0 DMA free:10472kB min:0kB low:0kB
high:0kB active:0kB inactive:0kB present:16384kB pages_scanned:19479
all_unreclaimable? yes
May 9 08:02:19 gdracdb1 kernel: protections[]: 0 0 0
May 9 08:02:19 gdracdb1 kernel: Node 0 Normal free:8256kB min:8280kB
low:16560kB high:24840kB active:23701520kB inactive:10676kB
present:68665344kB pages_scanned:0 all_unreclaimable? no
May 9 08:02:19 gdracdb1 kernel: protections[]: 0 0 0
May 9 08:02:19 gdracdb1 kernel: Node 0 HighMem free:0kB min:128kB low:256kB
high:384kB active:0kB inactive:0kB present:0kB pages_scanned:0
all_unreclaimable? no
May 9 08:02:19 gdracdb1 kernel: protections[]: 0 0 0
May 9 08:02:19 gdracdb1 kernel: Node 0 DMA: 0*4kB 1*8kB 0*16kB 1*32kB
1*64kB 3*128kB 1*256kB 1*512kB 1*1024kB 0*2048kB 2*4096kB = 10472kB
May 9 08:02:22 gdracdb1 kernel: Node 0 Normal: 20*4kB 4*8kB 5*16kB 2*32kB
27*64kB 1*128kB 0*256kB 0*512kB 0*1024kB 1*2048kB 1*4096kB = 8256kB
May 9 08:02:22 gdracdb1 kernel: Node 0 HighMem: empty
May 9 08:02:22 gdracdb1 kernel: Swap cache: add 87984, delete 87977, find
13381/15259, race 0+0
May 9 08:02:22 gdracdb1 kernel: Free swap: 16143224kB
May 9 08:02:22 gdracdb1 kernel: 17170432 pages of RAM
May 9 08:02:22 gdracdb1 kernel: 827519 reserved pages
May 9 08:02:22 gdracdb1 kernel: 253602825 pages shared
May 9 08:02:23 gdracdb1 kernel: 7 pages swap cached
若应用压力仍不停止,系统将没有内存供Oracle继续使用,系统失去响应的原因有两个:
2、因主要问题是供Oracle申请的物理内存不足,即使用swapoff取消swap,仍会因可用内存不足,系统无法响应情况。
二、问题分析
经过多次的测试和分析(可参考附录),最后发现,问题原因与Oracle上设置的SGA大小、系统的vm.nr_hugepages有关。
这里,Oracle的SGA值为30000M:
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 30000M
sga_target big integer 30000M
从系统top命令发现,oracle的申请的虚拟内存是29.4G(接近30000M),而Oracle启动后,多个oracle进程的常驻内存在不断的增加,故怀疑其使用的并不是SGA申请的内存:
top - 17:47:48 up 1 day, 3:35, 5 users, load average: 0.27, 0.25, 0.16
Tasks: 444 total, 1 running, 443 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.3% us, 0.2% sy, 0.0% ni, 99.3% id, 0.0% wa, 0.0% hi, 0.1% si
Mem: 65371656k total, 5973772k used, 59397884k free, 213504k buffers
Swap: 16386292k total, 0k used, 16386292k free, 4542984k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8424 oracle -2 0 29.4g 326m 311m S 2 0.5 0:59.87 oracle
8428 oracle -2 0 29.4g 329m 314m S 2 0.5 1:00.30 oracle
8432 oracle -2 0 29.4g 328m 313m S 1 0.5 1:00.32 oracle
8436 oracle -2 0 29.4g 326m 311m S 1 0.5 1:00.85 oracle
8440 oracle -2 0 29.4g 323m 308m S 1 0.5 1:00.50 oracle
1419 root 16 0 522m 28m 9748 S 1 0.0 0:48.14 crsd.bin
8416 oracle -2 0 29.4g 321m 306m S 1 0.5 0:59.69 oracle
8420 oracle -2 0 29.4g 329m 314m S 1 0.5 0:59.47 oracle
8444 oracle -2 0 29.4g 320m 305m S 1 0.5 0:59.96 oracle
23551 oracle 16 0 6412 1288 772 R 1 0.0 0:00.08 top
1453 oracle RT 0 238m 224m 23m S 0 0.4 0:47.41 ocssd.bin
8476 oracle 16 0 29.4g 64m 60m S 0 0.1 0:02.12 oracle
8860 oracle 16 0 29.4g 64m 58m S 0 0.1 0:01.47 oracle
1 root 16 0 4752 552 460 S 0 0.0 0:03.19 init
根据这份Oracle 11g的资料:H Very Large Memory on Linux,在如此大内存的环境中(64G),系统核心参数vm.nr_hugepages 的大小与Oracle 上设置的SGA是相关的。
而默认情况下,vm.nr_hugepages 是没有设置的,其大小为0。
HugePages_Total: 0
HugePages_Free:
Hugepagesize: 2048 kB
三、解决问题
1、配置合适的vm.nr_hugepages 值
参考H Very Large Memory on Linux提供的一个vm.nr_hugepages 建议值计算脚本。
本地下载:
在已设置好SGA大小及相关参数的情况下,先启动Oracle,然后运行脚本:
Recommended setting: vm.nr_hugepages = 15067
※ 注意:
使用该脚本时,必须先设置好SGA,并启动Oracle,待内存申请稳定后才运行。否则,其中用到的ipcs -m所获取的值并不准确。
把该参数加入/etc/sysctl.conf中,然后重启系统:
该值必须重启系统才能生效。
2、配置oracle用户的memlock
修改/etc/security/limits.conf文件,加入:
# - memlock - max locked-in-memory address space (KB)
# - locks - max number of file locks the user can hold
oracle soft memlock 30857216
oracle hard memlock 30857216
计算公式为:>=HugePages_Total×1024,这里设置了2倍:15067*1024*2 = 30857216。
重新登录到oracle用户,用ulimit -l 可看到该值。
最后,重新运行Oracle:
# srvctl start instance -d postdbs -i postdbs1
从top观察,可看到oracle运行后,会启动一个oracle进程逐步申请内存,直到SGA的大小:
top - 18:12:50 up 12 min, 1 user, load average: 0.21, 0.47, 0.43
Tasks: 406 total, 1 running, 405 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.2% us, 0.1% sy, 0.0% ni, 99.6% id, 0.0% wa, 0.0% hi, 0.1% si
Mem: 65371656k total, 34944692k used, 30426964k free, 127376k buffers
Swap: 16386292k total, 0k used, 16386292k free, 350956k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
22100 oracle -2 0 29.4g 29g 29g S 2 47.0 0:06.28 oracle
22116 oracle -2 0 29.4g 29g 29g S 1 47.0 0:06.36 oracle
22090 oracle -2 0 29.4g 29g 29g S 1 47.0 0:05.99 oracle
22096 oracle -2 0 29.4g 29g 29g S 1 47.0 0:06.20 oracle
22104 oracle -2 0 29.4g 29g 29g S 1 47.0 0:06.23 oracle
22108 oracle -2 0 29.4g 29g 29g S 1 47.0 0:06.23 oracle
22112 oracle -2 0 29.4g 29g 29g S 1 47.0 0:06.30 oracle
22120 oracle -2 0 29.4g 29g 29g S 1 47.0 0:06.24 oracle
从/proc/meminfo也可观察到已经在使用HugePages:
HugePages_Total: 15067
HugePages_Free: 3
Hugepagesize: 2048 kB
oracle使用的HugePages大小为:(15067-3)*2048 = 30851072 KB 。
再经压力测试,从top、ps aux、free等可看到Oracle的进程使用的内存是固定的(从SGA中申请),在没有额外操作的情况下,系统可用内存处于一个稳定值(这里使用ASM文件系统,故对ASM的磁盘I/O也会由SGA分配,系统cached值不大,free值较大),问题解决。
三、注意事项
1、SGA与vm.nr_hugepages的关系
设置vm.nr_hugepages 时必须注意,该值不能比SGA小,否则仍会发生上述的故障问题。我曾经参考这个链接:点击,根据其中的公式:
把vm.nr_hugepages 设置为:30*1024/2 = 15360 ,但是后来启动Oracle后,发现仍存在故障。最后,发现原来是设置SGA时,把SGA设置为了30G(不是30000M):
SQL> alter system set sga_max_size=30G scope=spfile sid='postdbs1';
SGA的大小(对比前面的值):
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
lock_sga boolean FALSE
pre_page_sga boolean FALSE
sga_max_size big integer 30G
sga_target big integer 30G
可见,这里的vm.nr_hugepages 刚好等于SGA的大小,但是,vm.nr_hugepages还用于如ASM实例等,每个ASM实例约需100M左右的空间。所以,vm.nr_hugepages =15360 是不够的,故障仍会出现。
◎ 在SGA为30G时,vm.nr_hugepages应该设置为:
Recommended setting: vm.nr_hugepages = 15428
在上面“解决问题”部分,我们设置的SGA大小是30000M,那么(30000+100)/2 = 15050 < 15067,所以“解决问题”中是成功的。
※ 注意:vm.nr_hugepages 的设置是否正确,可从HugePages的使用量来观察。
下面是分配不足的情况:
HugePages_Total: 15067
HugePages_Free: 15004
Hugepagesize: 2048 kB
Oracle 启动后,仅因ASM实例的原因,使用了很少一部分的HugePages(由/etc/init.d/init.crs服务占用),对内存的使用不正常。
但是,因为使用HugePages部分的共享内存不能被swap,也不能被其他进程使用,所以,如果该值比Oracle需要的值大了,所多出来的部分就是浪费。因此,HugePages 应该选择一个最佳值,以让HugePages_Free接近或等于0。(可参考上面提供的脚本)
2、vm.nr_hugepages 的调整
调整vm.nr_hugepages 的大小后,必须重启系统才能生效。
3、Oracle RAC启动方式
当用alert调整SGA的大小后,不能单纯的用shutdown immediate关闭数据库实例,而必须用srvctl 重启节点的方式才能生效。
四、附录
开始,因从top上观察到,最后时刻是kswapd在进行页面交换,占用大量的CPU资源。所以,首先想到的是swap的问题,故曾对系统核心参数进行了不少的调整工作,特把一些较重要的参数记录下来:
1、/proc/sys/vm/min_free_kbytes
该值设定的是系统保留给核心自己使用的内存大小,其他应用程序不能使用这部分的内容,包括系统cache也不可以。即free命令首行free部分的保留值。默认情况下,系统在启动时会根据物理内存的大小自动计算出该值。单位是(KB):
8286
该值不应该太大,太大了,其他应用可用的内存就会减少,提高kswapd交换的频率;也不应该太小,太小了,供核心调度的内存范围将不足,可能会因内存不够,发生OOM。该值与kswapd等存在以下关系:
更详细的信息,请参考:这里。
2、/proc/sys/vm/vfs_cache_pressure
该值用于决定虚拟内存directory和i-node缓冲回收的倾向,这个值越大,回收的倾向越严重。默认值是100:
100
提高该值,可以让系统更快的回收缓存,释放更多的物理内存。
3、/proc/sys/vm/swappiness
该值用于决定核心使用swap空间的频率。默认值为60:
60
该值越大,将越早使用kswapd进行页面交换,即使用swap空间;该值越小,越不希望使用swap空间。但该值<10时,除非可用内存(物理内存-核心保留的内存)真的已几乎耗尽,将会尽量不使用swap空间。注意,若该值设定太低(<10)时,一旦在cached较大,而发生突发的大内存申请时,可能会导致kswapd不断的进行页面交换,占用大量的CPU资源,最后导致机器响应不过来(hang住了)。
4、/proc/sys/vm/pagecache
该值决定核心回收内存钱,将会把内存用于pagecahe的最大百分比。默认值为100,即所有的系统内存都可以用于pagecache 。该值在2.4核心的时候曾经提供过,但后来被取消了,直到DC 5.0 SP3或Asianux 3.0 SP1以后更新算法后,可再次设置,这时,只有一个参数,代表百分比。详细请见:这里。
5、 /proc/sys/vm/drop_caches
默认值为0,可以使用下面的命令强制清空cache:
用free可看到效果,而剩余的cached值是有程序正在占用的内存,除非进程退出,否则无法删除该部分的内容。当然,该动作清空缓存后,会影响部分性能。另外,若多次执行该动作后,cached仍在不断的增长,说明有程序在不断的消耗内存,并且没有释放出来,也可作为一个判断内存使用情况的依据。(该参数在DC 5.0 SP3以后才能使用,详细可见:这里)
正常情况下,除非应用对内存的使用有问题,否则是不需要手动执行该动作的。
※ 注意:
虽然以上核心参数都很重要,当初我也受DBA日记 修订版、kswapd0 hangs the system 等文章的影响,修改了这些参数。但是测试结果告诉我们,原因并不在这里,加入这些参数或许可以缓解宕机的时间,但是并不能彻底解决问题。因为故障的根源在于Oracle不断的申请内存,但又没有释放,直到可用内存被消耗完。所以,判断类似问题的办法,仍必须靠top、ps aux、free等监控手段,逐步分析,寻找故障根源。
五、参考资料
H Very Large Memory on Linux
Tuning and Optimizing Red Hat Enterprise Linux for Oracle 9i and 10g Databases
Hugepage、VLM、SGA和Share memory
在CentOS Linux 5中为oracle配置hugepage的方法
DBA日记 修订版