暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Linux中的hugepage简述-技术人生系列第二十四期(补充篇)-我和数据中心的故事

中亦安图 2017-06-27
265

前言:上一期《一次一波三折的节点重启问题分析》中提到hugepage配置错误导致系统内存不足引发的问题,许多读者希望了解hugepage的配置方法,这里笔者以oracle使用的视角对Linux中的hugepage做个简单的介绍;希望对大家有所帮助。

01

基本概念


对于linux系统,内存会被分配成4K大小的页面,之后通过不同类型的页面表(PageTable)来进行管理。对于32位的Linux系统,内存的最大寻址范围是0—4G(2的32次方),意味着页面表大概需要100万个元素来管理这些内存,而对于64位的系统,这个页面表的尺寸会变得更大,这对于管理内存来说会产生更大的开销;


注意

本文的主要目的是从数据库的角度来阐述如何通过hugepage 来获得更好地性能,而不是一篇Linux的技术文档,所以对于内存管理的内容(例如页面表的分层结构等)不会进行讨论。

所以,如果能够把内存页面的尺寸放大,就可以更好的管理系统中的内存资源。从2.4 版本的内核开始,Linux系统开始提供hugepage 的功能,允许内存的页面尺寸可以被设置成为2M—256M之间的值。当然,这要求物理内存页面要连续,也就是说,修改hugepage的设置是需要重新启动OS才能够生效的。由于hugepage 和默认的内存页面大小不同,所以他是不能够被swap到磁盘的,换句话说,后台进程kswapd进程会忽略掉hugepage页面。而应用程序需要支持hugepage 特性才能够使用hugepage 中的内存页面。

配置hugepage 页面,需要设置以下的内核参数(针对2.6 版本的内核):

vm.nr_hugepages = <hugepage 的页面个数>

下面的命令可以查看当前的hugepage使用状况

root@orlx52db01 ~]# cat proc/meminfo |grep Huge

HugePages_Total:   13287 <<<< 系统设置的hugepage 页面总数

HugePages_Free:        2     <<< 可用的hugepage 页面总数

HugePages_Rsvd:        0

HugePages_Surp:        0

Hugepagesize:       2048 kB <<<< hugepage页面的尺寸

02

数据库为什么要使用hugepage

由于Oracle数据库会将运行过的SQL 语句和数据缓存到SGA中,成为一个共享内存段,之后很多的服务器进程(serverprocess)会访问SGA中的数据。随着数据库容量的不断增大,应用程序越来越复杂, SGA的尺寸也在不断变大,很多数据库的SGA都超过了100G。 这意味着SGA这个共享内存段的尺寸会很大,一个服务器进程需要运行SQL语句并访问一些数据的时候,就需要在很大的SGA共享内存段当中查找自己需要的数据,如果使用默认的页面大小就会对性能产生影响。所以,对于大部分的Linux系统,如果上面运行的数据库的SGA尺寸比较大的情况下,都建议配置hugepage, Exadata系统也是如此。

注意

只有SGA的内存是会被分配到hugepage当中,PGA是不会的。而且hugepageoracle AMM(自动内存管理)特性是不能兼容的,也就是说如果决定使用hugepage来保存sga的话,就不能够设置MEMORY_TARGET/ MEMORY_MAX_TARGET 参数

03

关于如何计算需要使用的hugepage页面个数

由于很多数据库服务器上会运行着多个数据库, Oracle在MOS文档401749.1 中给出了一个计算hugepage 页面个数的脚本,下面我们来分析一下这个脚本。

# Check for the kernel version
KERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2);}'`
<<< 查看kernel版本

# Find out the HugePage size
HPG_SZ=`grep Hugepagesize proc/meminfo | awk'{print $2}'` 
<<< 查看hugepage 页面的大小
if [ -z "$HPG_SZ" ];then
    echo "The hugepages may notbe supported in the system where the script is being executed."
    exit 1
fi

for SEG_BYTES in `ipcs -m | cut -c44-300 | awk'{print $1}' | grep "[0-9][0-9]*"` <<< 通过ipcs 命令找到oracle 数据库所使用的共享内存段,并输出它们的大小
do
    MIN_PG=`echo"$SEG_BYTES/($HPG_SZ*1024)" | bc -q`
<<<< 计算每个共享内存段需要的hugepage页面数量的最小值
    if [ $MIN_PG -gt 0 ]; then
       NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q` 
<<< 累加页面数量
    fi
done

RES_BYTES=`echo "$NUM_PG * $HPG_SZ *1024" | bc -q`
<<< 计算所需的hugepage 的大小

 

……
if [ $RES_BYTES -lt 100000000 ]; then 
<<<< 如果所有hugepage页面的总和小于100M的话,报错
    echo"***********"
    echo "** ERROR**"
    echo"***********"
    echo "Sorry! There arenot enough total of shared memory segments allocated for 
HugePages configuration. HugePages can only beused for shared memory segments 
that you can list by command:

    # ipcs -m

of a size that can match an Oracle DatabaseSGA. Please make sure that:
 * Oracle Database instance is up and running 
 * Oracle Database 11g Automatic MemoryManagement (AMM) is not configured
"
    exit 1
fi

 

 

case $KERN in <<<< 基于不同的内核版本给出需要配置的内核参数
    '2.2') echo "Kernelversion $KERN is not supported. Exiting." ;;
    '2.4') HUGETLB_POOL=`echo"$NUM_PG*$HPG_SZ/1024" | bc -q`;
          echo "Recommended setting: vm.hugetlb_pool = $HUGETLB_POOL" ;;
    '2.6') echo"Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
    '3.8') echo"Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
    '3.10') echo"Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
    '4.1') echo"Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
esac

根据上面的分析,这个脚本给出的建议值就是能够包含所有的oracle 数据库的共享内存段(就是SGA)所需要的最少hugepage页面数量的大小。所以,如果服务器上运行的数据库数量和SGA的大小是不变的,那么的确不需要调整hugepage的设置;而如果服务器上的数据库数量或者一些数据库的SGA大小调整之后,是需要重新运行这个脚本来修改hugepage页面数量的。

03

如何让数据库使用hugepage

最后,我们介绍一下如何让数据库实例(ASM实例也同样适用)使用hugepage。

 首先,需要将Oracle 用户的memlock 资源限制调大,由于这个限制只是一个目标值,对于大部分的系统,建议调整到比系统所有的物理内存小一点就可以了。例如:对于一个包含了64G内存的系统,可以设置成以下的值。

$ cat etc/security/limits.conf

  soft  memlock    60397977

  hard   memlock   60397977

之后,设置数据库参数 USE_LARGE_PAGES = TRUE| ONLY 来指定数据库使用hugepage。以下是这个参数的不同取值的含义:

       True:数据库启动时会尝试使用hugepage,但是如果没有配置hugepage或者hugepage的大小不能容纳整个SGA,数据库仍然可以启动。以下是具体的小版本的行为方式:

 对于11.2.0.2 版版本的数据库:如果可用的hugepage的大小不能容纳整个SGA,数据库会转而使用普通的内存页面来保存SGA;

对于11.2.0.3 及以上的版本,如果可用的hugepage的大小不能容纳整个SGA,数据库会尝试首先使用尽量多的hugepage来容纳SGA,其他的部分仍然使用普通的内存页面。

       Only:数据库只能使用hugepage来保存SGA,如果可用的hugepage页面不能容纳SGA,数据库将无法启动。

       False:数据库忽略hugepage,直接使用普通的内存页面来保存SGA。


您的转发是我们持续分享的动力!



往期回顾

关注公众号,回复数字查看精彩往期!

回复“017”第十七期:技术人生系列·我和数据中心的故事(第十七期)-看中国最美女DBA的一次价值连城的系统优化!

回复“018”第十八期:技术人生系列·我和数据中心的故事(第十八期)-记一条500行执行计划的SQL问题分析-从应急处理到根因分析

回复“019”第十九期:技术人生系列·我和数据中心的故事(第十九期)-通过案例教你识别操作系统重启是否为CRS引起

回复“020”第二十期:技术人生系列·我和数据中心的故事(第二十期)-ORA-01555错误启示录

回复“021”第二十一期:技术人生系列·我和数据中心的故事(第二十一期)-一条错误结果SQL带来的警示

回复“022”第二十二期:技术人生系列·我和数据中心的故事(第二十二期)-通过trace定位oracle统计信息收集带来的问题

回复“023”第二十三期:技术人生系列·我和数据中心的故事(第二十三期)-致敬618-电子商城秒杀活动技术支持历险记

回复“024”第二十四期:技术人生系列·我和数据中心的故事(第二十四期)-一次一波三折的节点重启问题分析



文章转载自中亦安图,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论