Hugepage、VLM、SGA、vm.nr_hugepages和Share memory

 

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,而是在不断的消耗系统其它内存。

一、故障现象
系统环境为:

引用
硬件: 4 x IBM x3950 M2 (两台堆叠 8 x Xeon E7420四核(共32个) 64G内存)
操作系统: 红旗 DC Server 5.0 for x86_64 SP2
应用: Oracle RAC 10.2.0.4


当进行应用压力测试时,发现系统可用内存不断减少,这是一个逐步表现的过程,可通过下面的ps命令间隔一段时间,观察Oracle的某进程对内存的占用是否不断增加:

引用
# ps aux|grep -w 3244
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)


系统快失去响应前,内存状态为:

引用
# free -m
             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:

引用
vm.min_free_kbytes=409600


可见,这时的系统可用内存已几乎消耗殆尽(上面设置的400m为核心保留,其它应用不能使用),并且,从vmstat可知,因物理内存不足,正在不断的进行页面交换,使用swap空间。由于正在进行压力测试,对系统的内存消耗压力很大,因此,从top状态,也会看到kswapd进程会一直占用CPU,以进行页面交换:


系统日志报:

引用
May 9 08:02:19 gdracdb1 kernel: Node 0 HighMem per-cpu: empty
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继续使用,系统失去响应的原因有两个:

引用
1、因物理内存不足,系统需由kswapd交换页面以腾出更多的可用物理内存,但swap使用的是磁盘,会给本来压力就大的CPU,增加更多的I/O负载,CPU idle几乎为0,无法响应;
2、因主要问题是供Oracle申请的物理内存不足,即使用swapoff取消swap,仍会因可用内存不足,系统无法响应情况。


二、问题分析
经过多次的测试和分析(可参考附录),最后发现,问题原因与Oracle上设置的SGA大小、系统的vm.nr_hugepages有关。
这里,Oracle的SGA值为30000M:

引用
SQL> show parameter sga;

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

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。

引用
# cat /proc/meminfo |grep Huge
HugePages_Total:  0
HugePages_Free:    
Hugepagesize:     2048 kB


三、解决问题
1、配置合适的vm.nr_hugepages 值

参考H Very Large Memory on Linux提供的一个vm.nr_hugepages 建议值计算脚本。
本地下载:


在已设置好SGA大小及相关参数的情况下,先启动Oracle,然后运行脚本:

引用
# ./hugepages_settings.sh
Recommended setting: vm.nr_hugepages = 15067


※ 注意:
使用该脚本时,必须先设置好SGA,并启动Oracle,待内存申请稳定后才运行。否则,其中用到的ipcs -m所获取的值并不准确。


把该参数加入/etc/sysctl.conf中,然后重启系统:

引用
vm.nr_hugepages=15067


该值必须重启系统才能生效。

2、配置oracle用户的memlock

修改/etc/security/limits.conf文件,加入:

引用
# cat /etc/security/limits.conf|grep lock
#        - 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 stop instance -d postdbs -i postdbs1
# srvctl start instance -d postdbs -i postdbs1


从top观察,可看到oracle运行后,会启动一个oracle进程逐步申请内存,直到SGA的大小:

引用
# top

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:

引用
# cat /proc/meminfo |grep Huge
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小,否则仍会发生上述的故障问题。我曾经参考这个链接:点击,根据其中的公式:

引用
nr_hugepages>=sga(mb)/Hugepagesize(mb)


把vm.nr_hugepages 设置为:30*1024/2 = 15360 ,但是后来启动Oracle后,发现仍存在故障。最后,发现原来是设置SGA时,把SGA设置为了30G(不是30000M):

引用
SQL> alter system set sga_target=30G scope=spfile sid='postdbs1';
SQL> alter system set sga_max_size=30G scope=spfile sid='postdbs1';


SGA的大小(对比前面的值):

引用
SQL> show parameter 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应该设置为:

引用
# ./hugepages_settings.sh
Recommended setting: vm.nr_hugepages = 15428


在上面“解决问题”部分,我们设置的SGA大小是30000M,那么(30000+100)/2 = 15050 < 15067,所以“解决问题”中是成功的。

※ 注意:vm.nr_hugepages 的设置是否正确,可从HugePages的使用量来观察。
下面是分配不足的情况:

引用
# cat /proc/meminfo |grep Huge
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):

引用
# cat /proc/sys/vm/min_free_kbytes
8286


该值不应该太大,太大了,其他应用可用的内存就会减少,提高kswapd交换的频率;也不应该太小,太小了,供核心调度的内存范围将不足,可能会因内存不够,发生OOM。该值与kswapd等存在以下关系:


更详细的信息,请参考:这里

2、/proc/sys/vm/vfs_cache_pressure
该值用于决定虚拟内存directory和i-node缓冲回收的倾向,这个值越大,回收的倾向越严重。默认值是100:

引用
# cat /proc/sys/vm/vfs_cache_pressure
100


提高该值,可以让系统更快的回收缓存,释放更多的物理内存。

3、/proc/sys/vm/swappiness
该值用于决定核心使用swap空间的频率。默认值为60:

引用
# cat /proc/sys/vm/swappiness
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:

# echo 3 > /proc/sys/vm/drop_caches


用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日记 修订版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值