이 블로그 검색

[ORACLE] Huge Page 설명 및 Linux 환경에서의 Huge Page 적용

1. Huge page개요


1.1. Huge page 사용 목적

Huge page는 Linux Kernel 2.6부터 통합된 기능으로,

vm.nr_hugepages 커널 파라미터를 통해 Shared memory에 대하여 더 큰 단위의 Memory page를 사용할 수 있게 해주는 기능이다.

Physical Memory의 용량이 큰 서버에서 기존과 같이 4KB 단위로 OS가 메모리 관리를 할 경우 CPU 부하가 높아 지게 되며,

더 큰 단위(2MB ~ 256MB)로 메모리 관리를 하여 CPU에 대한 부하를 줄여주는 역할을 한다.

본 문서에서는 Linux Kernel 2.6 이후 Huge page의 설정 및 운영 중 변경 Case에 따른 가이드를 제공한다.

Linux kernel 2.4 에서는 vm.nr_hugepages 커널 파라미터 대신에 vm.hugetlb_pool을 사용하였으며, 본 문서는 상기된 대로 Linux Kernel 2.6 이후 버전에 맞춰 vm.nr_hugepages 커널 파라미터로 설명한다.


1.2. Huge page 운영 매뉴얼 프롬프트 안내

본 문서의 각 프롬프트의 의미는 아래와 같다.

Prompt

설명

(root) #

OS root 유저 권한으로 shell command 수행

(oracle) $

OS oracle 설치 유저 권한으로 shell command 수행

SQL>

SQL*PLUS DB에 접속하여 수행


                                                               


2. Huge page 설정


2.1. 사전 준비 사항

아래 A~E 항목에 대한 확인을 통해 사전 준비사항을 확인한다.

A. DB가 기동(OS의 Shared Memory를 점유)중이어야 한다.
아래 쿼리 수행이 정상적으로 수행되는지 확인한다.

SQL> select status from v$instance ;

STATUS

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

OPEN

B. /etc/security/limits.* 파일에 ORACLE OS 유저의 memlock이 전체 Physical Memory 값과 같거나 약간 작게(90%) 설정되어 있어야 한다.

(root) # ls /etc/security/limits.*

limits.conf

 

/etc/security/limits.d:

limits.d/98-oracle.conf  limits.d/99-oracle.conf

 

(root) # vi /etc/securiry/limit.d/99-oracle.conf

*   soft   memlock    8388608

*   hard   memlock    8388608

 

(oracle) $ ulimit -a | grep "max locked memory"

max locked memory       (kbytes, -l) 8388608

memlock의 값은 KB 단위이며, 첫 컬럼은 OS 유저를 의미하고, "*"은 모든 OS 유저를 의미한다.

/etc/security/limits.* 의 값을 변경하는 경우, 변경 이후 시점에 기동 되는 프로세스들에만 적용 된다.

limits.d 디렉토리 아래에 파일이 존재하는 경우 가장 큰 sort 값을 가지는(오름차순 정렬 시 가장 마지막)파일에 입력 후 적용한다.

위와 같이 limits.conf, 98-oracle.conf, 99-oracle.conf 세 파일이 존재하는 경우 모든 파일의 파라미터가 커널에 적용 되지만, 각 파일에 중복된 커널 파라미터가 있는 경우, 정렬 순서상 마지막인 "99-oracle.conf" 파일에 설정된 값으로 최종 적용 된다.

가장 큰 sort 값을 가지는 파일 생성하여 입력하는 것도 가능하다.


C. AMM을 사용하지 않아야 한다.

ORACLE memory_target 파라미터가 0으로 설정되면 AMM을 사용하지 않는 상태이다.

SQL> select name, value from v$system_parameter where name = 'memory_target' ; 

NAME                 VALUE
-------------------- --------------------
memory_target        0


D. ORACLE의 use_large_pages 파라미터는 TRUE 상태를 권장.

ONLY 사용 시, NOMOUNT 단계에서 ORA-27106: system pages not available to allocate memory 발생 가능.

SQL> select name, value from v$system_parameter where name = 'use_large_pages' ;

NAME                 VALUE
-------------------- --------------------
use_large_pages      TRUE


E. 현재 Huge page를 사용하고 있는지 확인

(root) # cat /proc/meminfo | grep ^Huge

HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

HugePages_Total

  • Huge page의 개수이며, 단위는 Hugepagesize 이다. 즉, HugePages_Total * Hugepagesize 의 값이 Hugepage로 설정된 총 메모리의 양이다.

HugePages_Free

  • 사용되지 않고 남아있는 Huge page의 개수이다.

HugePages_Rsvd

  • Huge page로 할당 예약되어 있는 공간으로, 할당된 메모리에 문제가 있는경우 대체된다.

HugePages_Surp

  • sysctl의 nr_overcommit_hugage에 의해 조정되는 값으로, Huge page의 여분을 두도록 하였을 때 해당 값이 사용 된다.

Hugepagesize

  • Huge page의 page당 크기이다.


                                                               

2.2. Huge page 적정 값 수동 산출

지나치게 높은 값의 Huge page를 설정하면 OS 부팅 오류를 발생 시킬 수 있으며,

너무 작은 값을 사용 할 경우, 모든 Shared memory에 대해 Huge page를 제대로 활용 하지 못하거나 use_large_pages 파라미터가 ONLY로 설정 된 경우, DB Instance 기동에 실패 할 수 있다.

따라서 아래의 공식을 사용 하여, Huge page 설정을 위한 OS 커널 파라미터 vm.nr_hugepages를 산출하도록 한다.


2.2.1. vm.nr_hugepages 파라미터 값 산출

산출 공식

(shared memory KB) / (Hugepagesize KB) = vm.nr_hugepages
shared memory KB
  • 현재 OS에서 사용중인 Shared memory의 KB 단위.

Hugepagesize

  • Huge page의 page당 크기이다. Default(2048 KB)

vm.nr_hugepages

  • Huge page의 page 개수를 설정하는 OS kernel parameter 이다.

vm.nr_hugepages의 적용은 본 문서의 "2.4.1. /etc/sysctl.* 파일 수정"을 참조.

현재 Shared memory의 사용량은 # ipcs -m 명령어로 확인 가능하다.

  


2.2.2. huge page 제한 개수

Physical memory >= memlock > vm.nr_hugepages*2048KB > Shared memory

Physical memory
  • 실제 서버에 장착된 물리 메모리의 크기이다.

memlock

  • limit.* 파일에 기재하는 memlock은 일반적으로 Physical memory 같거나 90%만을 지정하며, 지정된 유저가 사용 할 수 있는 최대 Shared memory의 크기를 제한하는 역할을 한다. 상세 내용은 "2.1. 사전 준비 사항" 참고.

vm.nr_hugepages*2048KB

  • Huge page의 총 메모리 사용량으로, Physical memory에서 cache 상태로 변경시킨다.OS나 기타 User process에서 사용할 memory 공간이 존재해야 하므로 memlock 값보다 반드시 작아야 한다.

Shared memory

  • ORACLE DB 파라미터 use_large_page가 ONLY로 설정된 경우, SGA(Shared memory)는 Hugepage 보다 작아야 하며, use_large_page가 TRUE 설정이더라도 온전한 Hugepage 사용을 위해 SGA는 Hugepage 총량보다 작아야 한다.



                                                               


2.3. Huge page 적정 값 자동 산출

적정 값 산출에 있어 어려움이 있는 경우, 오라클에서 제공하는 아래의 스크립트를 사용 할 수 있다.

아래의 스크립트 파일 생성 후 실행 시, 현재 사용하고 있는 shared memory를 파악하여 적정 huge page 값을 도출 할 수 있다.


2.3.1. set_huge_pages.sh 스크립트 생성

원본 스크립트는 Document 401749.1 (oracle.com) 참고.

(oracle) $ vi set_huge_pages.sh

#!/bin/bash
#
# hugepages_settings.sh
#
# Linux bash script to compute values for the
# recommended HugePages/HugeTLB configuration
# on Oracle Linux
#
# Note: This script does calculation for all shared memory
# segments available when the script is run, no matter it
# is an Oracle RDBMS shared memory segment or not.
#
# This script is provided by Doc ID 401749.1 from My Oracle Support
# http://support.oracle.com
 
# Welcome text
echo "
This script is provided by Doc ID 401749.1 from My Oracle Support
( http://support.oracle.com) where it is intended to compute values for
the recommended HugePages/HugeTLB configuration for the current shared
memory segments on Oracle Linux. Before proceeding with the execution please note following:
 * For ASM instance, it needs to configure ASMM instead of AMM.
 * The 'pga_aggregate_target' is outside the SGA and
   you should accommodate this while calculating the overall size.
 * In case you changes the DB SGA size,
   as the new SGA will not fit in the previous HugePages configuration,
   it had better disable the whole HugePages,
   start the DB with new SGA size and run the script again.
And make sure that:
 * Oracle Database instance(s) are up and running
 * Oracle Database 11g Automatic Memory Management (AMM) is not setup
   (See Doc ID 749851.1)
 * The shared memory segments can be listed by command:
     # ipcs -m
 
 
Press Enter to proceed..."
 
read
 
# Check for the kernel version
KERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'`
 
# Find out the HugePage size
HPG_SZ=`grep Hugepagesize /proc/meminfo | awk '{print $2}'`
if [ -z "$HPG_SZ" ];then
    echo "The hugepages may not be supported in the system where the script is being executed."
    exit 1
fi
 
# Initialize the counter
NUM_PG=0
 
# Cumulative number of pages required to handle the running shared memory segments
for SEG_BYTES in `ipcs -m | cut -c44-300 | awk '{print $1}' | grep "[0-9][0-9]*"`
do
    MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q`
    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`
 
# An SGA less than 100MB does not make sense
# Bail out if that is the case
if [ $RES_BYTES -lt 100000000 ]; then
    echo "***********"
    echo "** ERROR **"
    echo "***********"
    echo "Sorry! There are not enough total of shared memory segments allocated for
HugePages configuration. HugePages can only be used for shared memory segments
that you can list by command:
 
    # ipcs -m
 
of a size that can match an Oracle Database SGA. Please make sure that:
 * Oracle Database instance is up and running
 * Oracle Database 11g Automatic Memory Management (AMM) is not configured"
    exit 1
fi
 
# Finish with results
case $KERN in
    '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" ;;
    '4.14') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
    '4.18') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
    '5.4') echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
    *) echo "Kernel version $KERN is not supported by this script (yet). Exiting." ;;
esac
 
# End

 

2.3.2. set_huge_pages.sh 스크립트 수행

(oracle) $ sh set_huge_pages.sh
This script is provided by Doc ID 401749.1 from My Oracle Support
( http://support.oracle.com) where it is intended to compute values for
the recommended HugePages/HugeTLB configuration for the current shared
memory segments on Oracle Linux. Before proceeding with the execution please note following:
 * For ASM instance, it needs to configure ASMM instead of AMM.
 * The 'pga_aggregate_target' is outside the SGA and
   you should accommodate this while calculating the overall size.
 * In case you changes the DB SGA size,
   as the new SGA will not fit in the previous HugePages configuration,
   it had better disable the whole HugePages,
   start the DB with new SGA size and run the script again.
And make sure that:
 * Oracle Database instance(s) are up and running
 * Oracle Database 11g Automatic Memory Management (AMM) is not setup
   (See Doc ID 749851.1)
 * The shared memory segments can be listed by command:
     # ipcs -m
 
 
Press Enter to proceed...
 
Recommended setting: vm.nr_hugepages = 573

 

                                                               


2.4. Huge page 적용

OS의 런타임 중 커널 파라미터 설정을 위해 sysctl.* 파일을 아래와 같이 수정 및 적용한다.


2.4.1. /etc/sysctl.* 파일 수정

수동으로 산정한 값 또는 set_huge_pages.sh 스크립트 수행 후 출력된 vm.nr_hugepages = nnn 값을 sysctl.conf에 입력 후 저장한다.

sysctl.d 디렉토리 아래에 파일이 존재하는 경우 가장 큰 sort 값을 가지는(오름차순 정렬 시 가장 마지막)파일에 vm.nr_hugepages 파라미터 값을 입력 후 적용한다.

(root) # ls /etc/sysctl.*
/etc/sysctl.conf
 
/etc/sysctl.d:
sysctl.d/98-oracle.conf  sysctl.d/99-oracle.conf
 
(root) # vi /etc/sysctl.d/99-oracle.conf
vm.nr_hugepages = 573



2.4.2. /etc/sysctl.* 커널 파라미터 적용

(root) # sysctl -p
vm.nr_hugepages = 573


2.4.3. /etc/sysctl.* 커널 파라미터 확인

(root) # sysctl -a | grep vm\.nr_hugepages
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.enp0s3.stable_secret"
sysctl: reading key "net.ipv6.conf.enp0s8.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret"
vm.nr_hugepages = 573
vm.nr_hugepages_mempolicy = 573


2.4.4. Huge page 적용 확인

(root) # grep ^Huge /proc/meminfo
HugePages_Total:     573
HugePages_Free:      573
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB


2.4.5. DB 기동 후 Huge page 확인

(root) # grep ^Huge /proc/meminfo
HugePages_Total:     573
HugePages_Free:       63
HugePages_Rsvd:       59
HugePages_Surp:        0
Hugepagesize:       2048 kB


추천 게시글

[ORACLE] Data Pump가 느리거나 멈춘경우.

목록