ITPub博客

首页 > 数据库 > Oracle > Oracle服务器开启HugePages以支持大内存SGA

Oracle服务器开启HugePages以支持大内存SGA

原创 Oracle 作者:xz43 时间:2020-09-23 15:33:59 0 删除 编辑

Linux内核支持

linux虽然没有aix,hp unix那么强悍,但linux也是非常优秀的os。为了提升linux的性能,它采用了很多 io、memory的调度机制,linux使用内存的方式是采用vm的方式,即linux把物理内存和swap共同虚拟成可用内存来对外提供使用,有时用户看似使用内存,实则使用磁盘。

linux管理内存的单位是页(pages),一般情况下默认的 page size 为4k。显然,对于SGA比较大(SGA_MAX_SIZE > 8G )的数据库系统,管理这么大的内存会给系统造成很大的负担,再加上频繁的pagein/pageout,最终会成为系统的瓶颈。

Hugepages引入

hugepage是在linux2.6内核被引入的,其目的就是使用更大的 memory page size 以适应越来越大的系统内存管理。

Page Table是用来存放虚拟内存页和物理内存页映射关系的内存数据结构。当进程访问虚拟内存地址时,首先访问Page Table,然后再根据Page Table的映射关系mapping来访问真实物理内存地址(RAM+SWAP)。

(借用网络上的图示)

因为Linux默认的page size为4k,所以相应的 Page Table 内存结构会比较大。而Hugepages的常见page size为2M,是默认值4k的500倍,可以大大降低 Page Table 内存结构的大小。

接下来,引用两个例子,比较启用hugepages与否两者之间的区别。

例1:没有配置Hugepage的系统

$stat -f / | grep "Block size"

Block size: 4096       Fundamental block size: 4096

首先,先查看系统的block size大小。

$ cat /proc/meminfo

MemTotal: 132086880 kB

...

PageTables: 4059612 kB

可以看出,系统内存为128G,pagetable大小约为4G。

例2:配置了Hugepage的系统

$ cat /proc/meminfo

MemTotal: 98999880 kB

PageTables: 79916 kB

可以看出:系统内存为96G, PageTable大小仅为78M。


为了提升访问性能,在CPU cache中有一个固定大小的TLB(Transaction Lookaside Buffer),用来保存部分Page Table以提高虚拟地址的转换速度,遵循让数据尽可能的靠近CPU的原则。提高了TBL命中率,也就是提高了地址转换的速度。因为Page size变大了,所以同样大小的TLB,所覆盖的内存大小也变大了。

使用Hugepages的内存页是不会被交换出去的,永远常驻在内存中,所以也减少了内存页替换的额外开销

HugePages注意事项

下面再说说在数据库服务器上使用Hugepages要注意的几点

1. Hugepages是在分配后就会预留出来的,其大小一定要比服务器上所有实例的SGA总和要大,差一点都不行。

比如说Hugepages设置为90G,oracle SGA为91G,那么oracle在启动的时候就不会使用到这90G的Hugepages。这90G就浪费了。所以在设置Hugepages时要计算SGA的大小,后面会给出一个脚本来计算。

2. 其他进程无法使用Hugepages的内存,所以不要设置太大,稍稍比SGA大一点保证SGA可以使用到hugepages就好了。

3. PGA不会使用Hugepages的内存。所以11g的AMM (Automatic Memory Management,memory_target参数)是不被支持的。而ASMM(Automatic Shared Memory Management, SGA_target参数)是被支持的,这两个不要搞混淆了。

4. 在meminfo中和Hugepage相关的有四项

  • HugePages_Total     所分配的hugepages页面数目,和Hugepagesize相乘后得到所分配的内存大小;

  • HugePages_Free     从来没有被使用过的Hugepages数目。即使oracle sga已经分配了这部分内存,但是如果没有实际写入,那么看到的还是Free的;

  • HugePages_Rsvd     已经被分配预留但是还没有使用的page数目。在Oracle刚刚启动时,大部分内存应该都是Reserved并且Free的,随着oracle  SGA的使用,Reserved和Free都会不断的降低;

  • Hugepagesize         默认的hugepages页大小,不可以修改;

HugePages_Free – HugePages_Rsvd 这部分是没有被使用到的内存,如果没有其他的Oracle  instance,这部分内存也许永远都不会被使用到,也就是被浪费了。

开启HugePages并使数据库生效

开启大页HugePage步骤如下:

1、关闭Oracle Database 11g中的AMM(Automatic Memory Management),即把两个参数MEMORY_TARGET / MEMORY_MAX_TARGET设为0

另外:默认情况下ASM instance 也是使用AMM的,但因为ASM 实例不需要大SGA,所以对ASM 实例使用HugePages意义不大。

2、计算hugepages的参数值

Oracle默认提供hugepages计算脚本(/app/oracle/product/11.2.0/rdbms/admin/hugepages_settings.sh),执行之前对hugepages_settings.sh 这个脚本授可执行的权限

[oracle@mydb admin]$ chmod +x hugepages_settings.sh

然后,执行hugepages_settings.sh

[oracle@mydb admin]$ ./hugepages_settings.sh

... 

...

Press Enter to proceed...

 

Recommended setting: vm.nr_hugepages = 1028

计算得到 hugepages 的推荐值为1028 页(注:一页为2M,这个值不可改,1028*2M=2056M),实际上hugepages与参数sga_max_size有关,比sga_max_size的值稍微大一点点(比SGA_MAX_SIZE最少要多加一页,2M的页不要分配超过sga_max_size太多,会造成内存的浪费)

3、设置hugepages,在内核参数中添加一行

[root@mydb ~]# vi /etc/sysctl.conf

vm.nr_hugepages = 1028


4、修改内核参数立即生效

[root@mydb ~]# sysctl -p

5、设定/etc/security/limits.conf文件,以K为单位,必须大于sga_max_size,这里设定为2056000

[root@mydb ~]# vi /etc/security/limits.conf

oracle          soft    memlock 2056000

oracle          hard    memlock 2056000


6、检查limits是否正确

[root@mydb ~]# su - oracle

[oracle@mydb ~]$ ulimit -l

2056000


7、重启数据库

注意:需要在原来的orale用户窗口退到root用户后,重新su - oracle切换到oracle用户,使配置生效。

[oracle@mydb ~]$ sqlplus / as sysdba

SQL> shutdown immediate;

SQL> startup


8、查看大页的使用情况

[oracle@mydb ~]$ watch -n1 'cat /proc/meminfo |grep -i HugePage'


Every 1.0s: cat /proc/meminfo |grep -i HugePage                                                   Thu Dec  5 11:09:06 2013

 

HugePages_Total:  1028

HugePages_Free:    869

HugePages_Rsvd:    842


注:

HugePages_Total:  1028    ---总共1028页

HugePages_Free:    869    ---空闲548页,即当前大页被使用了1028-869=159页,即被用了159*2M=118M,小于sga_target。

HugePages_Rsvd:    842    ---操作系统承诺给Oracle预留842页,即842*2M=1684M(1684+118==SGA_MAX_SIZE)

Hugepagesize:     2048 kB --每页是2M,不可修改


使用了hugepage之后,SGA就默认pin在内存里了,那么就不用lock sga了。


9、尝试启用 pre_page_sga 并查看效果

注意:参数 pre_page_sga 默认是false

SQL> alter system set pre_page_sga=true scope=spfile;

 

System altered.

 

sys@OCM> show parameter sga

 

NAME                                 TYPE        VALUE

------------------------------------ ----------- ------------------------------

lock_sga                             boolean     FALSE

pre_page_sga                         boolean     TRUE

sga_max_size                         big integer 2G

sga_target                           big integer 1G


HugePages_Total:  1028    ---总共1028页

HugePages_Free:    548    ---空闲548页,即当前大页被使用了1028-548=480页,即被用了480*2M=960M,约等于sga_target,参数pre_page_sga起作用了。

HugePages_Rsvd:    521    ---操作系统承诺给Oracle预留521页,即521*2M=1042M(理解为sga_max_size-sga_target)

Hugepagesize:     2048 kB --每页是2M,不可修改


附录:

系统缺省会启用 Transparent HugePages,用来提高内存管理的性能透明大页(Transparent HugePages ), THP 与Hugepages 类似,主要的区别是:Transparent HugePages 可以实时配置,不需要重启才能生效配置。

$cat /proc/meminfo | egrep 'Huge|MemTotal|PageTables'

MemTotal:       790965276 kB

PageTables:      1053188 kB

AnonHugePages:  208969728 kB

HugePages_Total:       0

HugePages_Free:        0

HugePages_Rsvd:        0

HugePages_Surp:        0

Hugepagesize:       2048 kB

只要这里 AnonHugePages 的值大于0,即表示启用了THP。

在linux 6.2 之后可以通过如下命令来监控THP。

$egrep 'trans|thp' /proc/vmstat

nr_anon_transparent_hugepages 102079

thp_fault_alloc 458782670

thp_fault_fallback 25986

thp_collapse_alloc 188918

thp_collapse_alloc_failed 0

thp_split 43215

thp_zero_page_alloc 1

thp_zero_page_alloc_failed 0

查看哪些进程在使用THP:

$grep -e AnonHugePages  /proc/*/smaps | awk  '{ if($2>4) print $0} ' |  awk -F "/"  '{print $0; system("ps -fp " $3)} '


因为 THP 会导致节点重启,所以Oracle 强烈建议关闭THP。


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9399028/viewspace-2723514/,如需转载,请注明出处,否则将追究法律责任。

下一篇: JDK13新特性详解
请登录后发表评论 登录
全部评论
鱼儿的学习空间

注册时间:2010-11-16

  • 博文量
    424
  • 访问量
    1757541