18.4. 커널 리소스 관리

PostgreSQL은 특히 서버의 복수 사본을 동일한 시스템에서 실행 중인 경우 또는 대규모 설치 중인 경우, 가끔씩 다양한 운영 체제 리소스 제한을 소진시킨다. 이 절에서는 PostgreSQL가 사용하는 커널 리소스 및 커널 리소스 소비와 관련된 문제 해결 단계를 다룬다.

18.4.1. 공유 메모리 및 세마포어

공유 메모리 및 세마포어는 통칭 "System V IPC"라고 한다(PostgreSQL과 무관한 메시지 큐와 함께). Windows 외에, PostgreSQL이 이러한 기능에 대한 자체적인 대체 구현을 제공하는 경우 PostgreSQL을 실행하기 위해 이러한 기능이 요구된다.

이러한 기능의 완전한 부재는 서버 시작 시 잘못된 시스템 호출 에러에 의해 보통 드러난다. 이런 경우 커널을 다시 환경 설정하는 것 외에는 대안이 없다. PostgreSQL은 커널 없이 작동되지 않는다. 이러한 상황은 최신 운영 체제에서는 거의 일어나지 않는다.

PostgreSQL이 다양한 하드 IPC제한 하나를 초과한 경우 서버는 시작을 거부하고 문제와 조치를 설명하는 지시적 에러 메시지를 남긴다(18.3.1절 참조). 관련 커널 파라미터의 이름은 각종 시스템 간에 동일하며, 표 18-1에 개략적인 내용이 나와 있다. 단, 파라미터 설정 방법은 다를 수 있다.일부 플랫폼에 대한 제시는 아래에 나와 있다.

참고: PostgreSQL 9.3 이전에는, 서버 시작에 훨씬 더 많은 System V 공유 메모리가 필요했다. 버전이 오래된 서버를 실행 중인 경우 문서에서 서버 버전을 참고하기 바란다.

표 18-1. System V IPC 파라미터

이름설명적절한 값
SHMMAX공유 메모리 세그먼트의 최대 크기(바이트)최소 1kB(서버 사본이 다수 실행되는 경우 그 이상)
SHMMIN공유 메모리 세그먼트의 최소 크기(바이트)1
SHMALL사용 가능한 공유 메모리의 총 양(바이트 또는 페이지)바이트인 경우 SHMMAX와 동일; 페이지인 경우 ceil(SHMMAX/PAGE_SIZE)
SHMSEG프로세스당 공유 메모리 세그먼트의 최대 수1개 세그먼트만 필요하지만 기본값이 훨씬 큼
SHMMNI시스템 차원(system-wide)의 공유 메모리 세그먼트의 최대 수SHMSEG와 동량 외 다른 애플리케이션의 여유분
SEMMNI세마포어 식별자의 최대 수(예: 세트)최소한 ceil((max_connections + autovacuum_max_workers + max_worker_processes + 5) / 16)
SEMMNS시스템 차원(system-wide)의 세마포어 최대 수ceil((max_connections + autovacuum_max_workers + max_worker_processes + 5) / 16) * 17 그 외 다른 애플리케이션의 여유분
SEMMSL세트별 세마포어 최대 수최소한 17
SEMMAP세마포어 맵에서 항목 수텍스트 참조
SEMVMX세마포어 최대 값최소한 1000 (기본값은 대체로 32767; 필요한 경우 외에는 변경하지 말 것)

PostgreSQL은 서버 사본별로 System V 공유 메모리 수 바이트가 필요하다(64비트 플랫폼의 경우 보통 48바이트). 최신 운영 체제에서 이 정도 양은 손쉽게 할당 가능하다. 그러나, 서버 사본을 다수 실행 중이거나 다른 어플리케이션도 System V 공유 메모리를 사용 중인 경우 바이트 단위의 공유 메모리 최대 크기인 SHMMAX를 늘려야 하거나 시스템 차원(system-wide)의 System V 공유 메모리인 SHMALL를 늘려야 할 수 있다. SHMALL는 여러 시스템에서 바이트 단위가 아니라 페이지 단위로 처리된다는 점에 유의하라.

PostgreSQL의 경우 많아야 약 32바이트에 불과하기 때문에(대개 1) 문제의 원인이 공유 메모리 세그먼트의 최소 크기(SHMMIN)일 가능성은 낮다. 시스템 차원(system-wide)의 세그먼트 최대 수(SHMMNI) 또는 프로세스당 최대 수(SHMMNI) 또는 프로세스당 최대 수(SHMSEG)는 시스템이 영(0)으로 설정되지 않는 한 문제의 원인이 될 가능성은 낮다.

PostgreSQL은 16개 한 세트로, 허용된 연결(max_connections), autovacuum worker 프로세스(autovacuum_max_workers), 그리고 허용된 백그라운드 프로세스 (max_worker_processes) 각각 1개의 세마포어를 사용한다. 각각의 세트마다 다른 어플리케이션에서 사용되는 세마포어 세트와의 충돌을 감지하기 위한 "매직 넘버"가 17번째 세마포어에 포함되어 있다. 시스템에서 세마포어 최대 수는 SEMMNS에 의해 설정되며, 따라서 최소한 max_connections + autovacuum_max_workers + max_worker_processes 각각 허용된 16개 연결에 1 추가 + worker여야 한다(표 18-1 공식 참조). 파라미터 SEMMNI는 시스템에 동시에 존재할 수 있는 세마포어 세트 수에 대한 제한을 결정한다. 그러므로, 이 파라미터는 최소한 ceil((max_connections + autovacuum_max_workers + max_worker_processes + 5) / 16)여야 한다.허용 연결 수를 줄이면 실패를 임시 방편으로 해결할 수 있으며, semget 함수로부터 "No space left on device"라는 애매한 메시지를 받게 된다.

경우에 따라서는 SEMMAP를 적어도 SEMMNS와 유사하게 늘릴 필요가 있을 수 있다. 이 파라미터는 세마포어 리소스 맵의 크기를 정의하며, 이 맵에서는 사용 가능한 세마포어의 연속 블록마다 항목을 필요로 한다. 세마포어 세트가 해제되면, 해제된 블록에 인접한 기존 항목에 추가되거나 새로운 맵 항목 아래에 등록된다. 맵이 꽉 차면 해제된 세마포어는 분실된다(리부팅될 때까지). 세마포어 공간의 조각화는 시간이 흐를수록 원래 있어야 할 것보다 사용 가능한 세마포어 수가 작아진다.

세트에 포함될 수 있는 세마포어 수를 결정하는 SEMMSLPostgreSQL의 경우 최소 17이어야 한다.

SEMMNUSEMUME 같은 "semaphore undo"와 관련된 다양한 기타 설정은 PostgreSQL에 영향을 미치지 않는다.

AIX

모든 메모리가 공유 메모리로 사용되도록 설정되므로, 적어도 버전 5.1은 SHMMAX같은 파라미터에 대해 특수한 설정을 할 필요가 없다. 이것은 DB/2 같은 다른 데이터베이스에서 일반적으로 사용된 설정의 한 종류이다.

그러나, 파일 크기(fsize)와 파일 수(nofiles)에 대한 기본 하드 제한이 너무 낮으므로 전역 ulimit 정보를 /etc/security/limits에서 변경해야 할 수 있다.

FreeBSD

기본 설정은 sysctl 또는 loader 인터페이스를 사용하여 변경할 수 있다. 다음 파라미터는 sysctl을 사용하여 설정할 수 있다.

# sysctl kern.ipc.shmall=32768
# sysctl kern.ipc.shmmax=134217728

리부팅 시에 이 설정을 유지하려면 /etc/sysctl.conf를 수정해야 한다.

이러한 세마포어 관련 설정은 sysctl에 관한 한 읽기 전용이지만 /boot/loader.conf에서 설정 가능하다.

kern.ipc.semmni=256
kern.ipc.semmns=512
kern.ipc.semmnu=256

이 값을 수정한 후에는 새 설정을 적용하려면 리부팅이 필요하다(참고: FreeBSD는 SEMMAP를 사용하지 않는다. 오래된 버전은 kern.ipc.semmap에 대한 설정을 수용하지만 무시하고 새 버전은 완전히 무시한다.).

사용자는 커널을 환경 설정하여 공유 메모리를 RAM에 잠그고 스왑을 위해 페이지 아웃되지 못하게 하기를 원할 수 있다. 이것은 sysctl 설정 kern.ipc.shm_use_phys를 사용하면 가능하다.

sysctlsecurity.jail.sysvipc_allowed를 활성화하여 FreeBSD jail에서 실행 중인 경우 서로 다른 jail에서 실행 중인 postmaster들은 서로 다른 시스템 사용자에 의해 실행되어야 한다. 루트 사용자가 아닌 경우 서로 다른 jail에서 사용자가 공유 메모리 또는 세마포어를 간섭하지 못하게 하고 PostgreSQL IPC 클린업 코드가 올바로 작동되게 하기 때문에 이것은 보안을 개선시킨다 (FreeBSD 6.0 이상에서 IPC 클린업 코드는 서로 다른 jail에서 동일한 포트에 postmaster의 실행을 방지하기 때문에 다른 jail에서 프로세스를 올바로 감지하지 못한다.).

FreeBSD 4.0 이전 버전은 OpenBSD처럼 작동된다(아래 참조).

NetBSD

NetBSD5.0 이상에서, IPC 파라미터는 sysctl을 사용하여 조절 가능하다.예를 들면:

$ sysctl -w kern.ipc.shmmax=16777216

리부팅 시에 이 설정을 유지하려면 /etc/sysctl.conf를 수정해야 한다.

사용자는 커널을 환경 설정하여 공유 메모리를 RAM에 잠그고 스왑을 위해 페이지 아웃되지 못하게 하기를 원할 수 있다.이것은 sysctl 설정 kern.ipc.shm_use_phys를 사용하면 가능하다.

NetBSD 5.0 이전 버전은 키워드 option이 아니라 options로 설정되어야만 하는 파라미터인 경우 외에는 OpenBSD (아래 참조)처럼 작동된다.

OpenBSD

옵션 SYSVSHMSYSVSEM은 커널이 컴파일된 경우에 활성화되어야 한다(기본으로 설정돼 있음).공유 메모리의 최대 크기는 옵션 SHMMAXPGS (페이지 단위)에 의해 결정된다. 다음 예시는 다양한 파라미터 설정 방법을 보여준다.

optionSYSVSHM
optionSHMMAXPGS=4096
optionSHMSEG=256

optionSYSVSEM
optionSEMMNI=256
optionSEMMNS=512
optionSEMMNU=256
optionSEMMAP=256

사용자는 커널을 환경 설정하여 공유 메모리를 RAM에 잠그고 스왑을 위해 페이지 아웃되지 못하게 하기를 원할 수 있다.이것은 sysctl 설정 kern.ipc.shm_use_phys를 사용하면 가능하다.

HP-UX

기본 설정은 보편적으로 정상적인 설치에 충분하다.HP-UX 10에서 SEMMNS의 출고시 기본 설정은 128이며, 이것은 거대 데이터베이스 사이트에는 너무 적을 수 있다.

IPC 파라미터는 Kernel Configuration->Configurable Parameters 아래의 System Administration Manager (SAM)에서 설정할 수 있다. 완료 시 Create A New Kernel을 선택해야 한다.

Linux

최대 세그먼트 크기 기본값은 32 MB이며, 최대 총 크기 기본값은 2097152페이지이다."huge pages"를 이용한 특수한 커널 환경 설정일 때 외에는 페이지는 거의 항상 4096바이트이다(확인하려면 getconf PAGE_SIZE 사용).

공유 메모리 크기 설정은 sysctl 인터페이스를 통해 변경 가능하다.예를 들어, 16 GB를 허용하려면:

$ sysctl -w kernel.shmmax=17179869184
$ sysctl -w kernel.shmall=4194304

또한, /etc/sysctl.conf 파일에서 리부팅 사이에서도 이 설정을 보존할 수 있다.이렇게 하는 것이 매우 바람직하다.

오래된 배포에는 sysctl 프로그램이 없을 수도 있지만 /proc 파일 시스템을 처리하여 동일하게 변경할 수 있다.

$ echo 17179869184 >/proc/sys/kernel/shmmax
$ echo 4194304 >/proc/sys/kernel/shmall

나머지 기본 설정은 아주 넉넉한 크기로, 일반적으로 변경이 불필요하다.

OS X

OS X에서 공유 메모리를 환경 설정하는 권장 방법은 다음과 같은 변수 할당이 포함된 /etc/sysctl.conf 파일을 생성하는 것이다.

kern.sysv.shmmax=4194304
kern.sysv.shmmin=1
kern.sysv.shmmni=32
kern.sysv.shmseg=8
kern.sysv.shmall=1024

일부 OS X 버전에서, 모두 5개의 공유 메모리 파라미터를 /etc/sysctl.conf에 설정해야 하며, 그렇지 않으면 값이 무시된다는 점에 유의해야 한다.

OS X 최근 릴리스는 설정된 SHMMAX가 정확히 4096의 배수가 아니면 이 값을 무시한다.

SHMALL는 이 플랫폼에서 4 kB로 평가된다.

OS X 구 버전에서는 공유 메모리 파라미터에 대한 변경 내용이 적용되려면 리부팅 해야 한다. 10.5는 현재, sysctl을 사용하여 SHMMNI를 제외한 모두를 상황에 따라 변경 가능하다. 그러나 리부팅 사이에 값이 유지될 수 있도록 /etc/sysctl.conf를 통해 원하는 값을 설정하는 것이 최선이다.

/etc/sysctl.conf 파일은 OS X 10.3.9 이상에서만 유효하다. 이전 10.3.x 릴리스를 실행 중인 경우 /etc/rc 파일을 편집하여 다음 명령으로 값을 변경해야 한다.

sysctl -w kern.sysv.shmmax
sysctl -w kern.sysv.shmmin
sysctl -w kern.sysv.shmmni
sysctl -w kern.sysv.shmseg
sysctl -w kern.sysv.shmall

Note that /etc/rc는 일반적으로 OS X 시스템 업데이트 시 덮어쓰기 되므로 업데이트가 있을 때마다 사용자는 이러한 편집을 반복해야 한다.

OS X 10.2 이전 버전에서는 /System/Library/StartupItems/SystemTuning/SystemTuning 파일에서 이 명령을 편집해야 한다.

SCO OpenServer

기본 환경 설정에서 세그먼트당 512 kB의 공유 메모리만 허용된다. 설정을 변경하려면 먼저 /etc/conf/cf.d디렉터리로 이동해야 한다. SHMMAX의 현재 값을 표시하려면 다음을 실행한다.

./configure -y SHMMAX

SHMMAX에 새 값을 설정하려면 다음을 실행한다.

./configure SHMMAX=value

여기서 value는 사용하려는 새 값이다(바이트 단위).SHMMAX를 설정한 후에는 커널을 리빌드한다.

./link_unix

그런 다음 리부팅한다.

Solaris 2.6 to 2.9 (Solaris 6 ~ Solaris 9)

해당 설정은 /etc/system에서 변경 가능하다.예를 들면:

set shmsys:shminfo_shmmax=0x2000000
set shmsys:shminfo_shmmin=1
set shmsys:shminfo_shmmni=256
set shmsys:shminfo_shmseg=256

set semsys:seminfo_semmap=256
set semsys:seminfo_semmni=512
set semsys:seminfo_semmns=512
set semsys:seminfo_semmsl=32

변경한 내용을 적용하려면 사용자의 리부팅이 필요하다.이전 Solaris 버전에서 공유 메모리에 대한 내용은 http://sunsite.uakom.sk/sunworldonline/swol-09-1997/swol-09-insidesolaris.html 을 참조 바란다.

Solaris 2.10 (Solaris 10) 이상
OpenSolaris

Solaris 10 이상 및 OpenSolaris에서 기본 공유 메모리 및 세마포어 설정은 대부분의 PostgreSQL 애플리케이션에서 충분하다.이제 Solaris는 시스템 RAM의 1/4을 SHMMAX 기본값으로 설정한다. 이 설정을 좀 더 조정하려면 postgres 사용자에 대한 프로젝트 설정을 사용해야 한다. 예를 들면, root로 다음을 실행한다.

projadd -c "PostgreSQL DB User" -K "project.max-shm-memory=(privileged,8GB,deny)" -U postgres -G postgres user.postgres

이 명령은 user.postgres 프로젝트를 추가하고 postgres 사용자에 대한 공유 메모리 최대값을 8GB로 설정하고, 다음에 사용자 로그인 시 적용되거나 PostgreSQL 재시작 시 적용된다(리로드 아님).위의 것은 PostgreSQLpostgres 그룹의 postgres 사용자로 실행되는 것으로 간주한다.서버 리부팅은 불필요하다.

연결이 다수 있는 데이터베이스 서버에 대한 다른 권장 커널 설정 변경은 다음과 같다.

project.max-shm-ids=(priv,32768,deny)
project.max-sem-ids=(priv,4096,deny)
project.max-msg-ids=(priv,4096,deny)

또한 zone 내에서 PostgreSQL을 실행 중인 경우 zone 리소스 사용 제한도 올려야 할 필요가 있다.projectsprctl에 대한 자세한 내용은 System Administrator's Guide의 "Chapter2:Projects and Tasks"를 참조 바란다.

UnixWare

UnixWare 7에서 공유 메모리 세그먼트의 최대 크기는 기본 환경 설정에서 512 kB이다.SHMMAX의 현재 값을 표시하려면 다음을 실행한다.

/etc/conf/bin/idtune -g SHMMAX

이것은 현재값, 기본값, 최소값 및 최대값을 표시한다. SHMMAX에 새 값을 설정하려면 다음을 실행한다.

/etc/conf/bin/idtune SHMMAX value

여기서 value는 사용하려는 바이트 단위의 새 값이다.SHMMAX를 설정한 후에는 커널을 리빌드한다.

/etc/conf/bin/idbuild -B

그런 다음 리부팅한다.

18.4.2. 리소스 제한

Unix계열의 운영 체제는 사용자의 PostgreSQL 서버에도 영향을 미칠 수 있는 리소스 제한 형태가 다양하다. 그 중에 사용자별 프로세스 수, 프로세스당 개방 파일 수, 각 프로세스에서 사용 가능한 메모리 양에 대한 제한이 특히 중요하다. 이러한 제한은 각각 "하드""소프트" 제한이 있다. 소프트 제한은 실제로 계산하는 것이지만, 사용자가 하드 제한까지 증가 시킬 수 있다. 하드 제한은 root 사용자만이 변경 가능하다.시스템 호출 setrlimit는 이러한 파라미터의 설정을 담당한다. 쉘의 빌트인 명령어 ulimit(Bourne 쉘) 또는 limit (csh)는 커맨드 라인에서 리소스 제한을 제어하는 데 사용된다. BSD 파생 시스템에서/etc/login.conf 파일은 로그인 동안 다양한 리소스 제한 설정을 제어한다. 자세한 내용은 운영 체제 문서를 참조 바란다. 관련 파라미터는 maxproc, openfilesdatasize들이 있다.예제는 아래와 같다.

default:\
...
:datasize-cur=256M:\
:maxproc-cur=256:\
:openfiles-cur=256:\
...

(-cur는 소프트 제한이다.하드 제한을 설정하려면 -max를 덧붙인다.)

커널은 일부 리소스에 대해 시스템 차원(system-wide)의 제한을 가질 수 있다.

PostgreSQL 서버는 연결당 프로세스 1개를 사용하므로 허용된 연결 수에 해당되는 프로세스는 최소한 제공한 다음에 사용자는 시스템에서 필요로 하는 나머지를 제공해야 한다. 이것은 일반적으로 문제가 되지 않지만 머신 1대에 몇 개의 서버를 실행하는 경우에는 쉽지 않을 수 있다.

개방 파일에 대한 기본 제한은 시스템 리소스를 부적절하게 분할하지 않고도 여러 사용자가 머신에 공존할 수 있는 값인 "사회적으로 용인되는" 값으로 설정된다. 사용자가 필요에 따라 머신 1대에서 여러 개의 서버를 실행하지만, 특정한 전용 서버의 제한만 올리고자 할 수도 있다.

다른 한편으로, 일부 시스템에서는 독립된 프로세스들이 많은 수의 파일들을 열 수 있게 한다.그러면 몇 개의 프로세스만 실행되더라도 시스템 차원(system-wide)의 제한이 손쉽게 초과된다. 이러한 상황이 발생되었지만 시스템 차원(system-wide)의 제한을 변경하고 싶지 않을 경우에는 PostgreSQLmax_files_per_process 환경 설정 파라미터를 설정하여 개방 파일의 소비를 제한할 수 있다.

18.4.3. Linux 메모리 Overcommit

Linux 2.4 이상에서 기본 가상 메모리 동작은 PostgreSQL의 경우 최적화 되어 있지 않다. 커널이 메모리 오버커밋을 이행하는 방식 때문에 PostgreSQL 또는 다른 프로세스의 메모리 수요가 시스템의 가상 메모리가 소진되는 원인이 되는 경우 커널은 PostgreSQL postmaster(마스터 서버 프로세스)를 종료해야 한다.

이런 경우가 발생하면 이와 같은 커널 메시지가 나타난다(해당 메시지를 찾아 보려면 시스템 문서 및 환경 설정 참조).

Out of Memory: Killed process 12345 (postgres).

이것은 postgres 프로세스가 메모리 압박 때문에 종료되었음을 나타낸다.기존 데이터베이스 연결이 정상 작동되더라도 새로운 연결은 수락되지 않는다. 복구하려면 PostgreSQL을 재시작해야 한다.

이 문제를 방지하는 방법 중 하나는 다른 프로세스 때문에 머신의 메모리가 소진되지 않을 것이 확실한 머신에서 PostgreSQL을 실행하는 것이다.실제 메모리와 swap 공간이 소진된 경우에만 메모리 부족(OOM) 킬러가 호출되기 때문에 메모리에 여유가 없는 경우에는 운영 체제의 swap 공간을 늘리면 문제를 방지하는 데 도움이 된다.

PostgreSQL 자체가 메모리 부족의 원인인 경우 환경 설정을 변경하면 문제를 방지할 수 있다.경우에 따라 메모리 관련 환경 설정 파라미터, 특히 shared_bufferswork_mem을 줄이는 것이 도움이 된다.그 외에는 데이터베이스 서버 자체로의 연결을 너무 많이 허용하는 것이 문제의 원인일 수 있다.대체로, max_connections를 줄이는 대신 외부 연결 풀링 소프트웨어를 이용하는 것이 좋다.

Linux 2.6 이상에서 커널의 동작을 수정해서 메모리 "오버커밋"을 방지할 수 있다. 이 설정으로 OOM killer의 호출이 전적으로 방지되는 않지만 가능성은 확연히 줄어들며, 따라서 시스템 동작이 좀 더 견고해진다.sysctl을 통해 엄격한 오버커밋 모드를 선택함으로써 이것이 가능해진다.

sysctl -w vm.overcommit_memory=2

또는 동일한 항목을 /etc/sysctl.conf에 입력해도 된다. 사용자는 이와 관련된 설정인 vm.overcommit_ratio의 수정을 원할 수도 있다. 자세한 내용은 커널 문서 파일 https://www.kernel.org/doc/Documentation/vm/overcommit-accounting 을 참조 바란다.

Another approach, which can be used with or without altering vm.overcommit_memory, is to set the process-specific OOM score adjustment value for the postmaster process to -1000, thereby guaranteeing it will not be targeted by the OOM killer. The simplest way to do this is to execute

echo -1000 > /proc/self/oom_score_adj

in the postmaster's startup script just before invoking the postmaster. Note that this action must be done as root, or it will have no effect; so a root-owned startup script is the easiest place to do it. If you do this, you should also set these environment variables in the startup script before invoking the postmaster:

export PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
export PG_OOM_ADJUST_VALUE=0

These settings will cause postmaster child processes to run with the normal OOM score adjustment of zero, so that the OOM killer can still target them at need. You could use some other value for PG_OOM_ADJUST_VALUE if you want the child processes to run with some other OOM score adjustment. (PG_OOM_ADJUST_VALUE can also be omitted, in which case it defaults to zero.) If you do not set PG_OOM_ADJUST_FILE, the child processes will run with the same OOM score adjustment as the postmaster, which is unwise since the whole point is to ensure that the postmaster has a preferential setting.

Older Linux kernels do not offer /proc/self/oom_score_adj, but may have a previous version of the same functionality called /proc/self/oom_adj. This works the same except the disable value is -17 not -1000.

참고: 일부 공급업체의 Linux 2.4 커널은 2.6 오버커밋 sysctl 파라미터의 초기 버전을 가지고 있는 것으로 알려져 있다.그러나, 관련 코드가 없는 2.4 커널에서 vm.overcommit_memory가 2로 설정되는 것은 상황을 더 나쁘게 만든다. 실제 커널 소스 코드를 확인하여( mm/mmap.c 파일에서 vm_enough_memory 참조) 2.4 설치에서 이것을 시도하기 전에 사용자의 커널에서 무엇이 지원되는지 확인하는 것이 좋다. overcommit-accounting 문서 파일이 존재한다고 해서 기능이 지원된다는 증거로 생각해서는 된다.의심스러울 경우는 커널 전문가 또는 커널 공급업체에게 문의 바란다.

18.4.4. Linux Huge pages

huge pages를 사용하면 PostgreSQL 같이 shared_buffers 값이 크게 지정해 많은 메모리를 사용할 경우, 한번에 큰 메모리 영역을 작업 단위로 지정해, 메모리 읽기 쓰기 작업 비용을 줄일 수 있다. PostgreSQL에서 이 기능을 활성화하려면 커널 환경 설정값이 CONFIG_HUGETLB_PAGE=yCONFIG_HUGETLBFS=y로 되어있어야 한다. 또한 vm.nr_hugepages 값도 적당히 조절되어야 한다. 필요한 huge page 수를 계산하는 방법은, huge page 설정을 끄고, PostgreSQL 서버를 실행한 뒤, /proc 파일 시스템을 이용하며 postmaster 프로세스의 VmPeak 값을 보고, 그 값 정도를 huge page 크기로 산정하면 된다. 이 작업은 다음과 같다:

$ head -1 $PGDATA/postmaster.pid
4170
$ grep ^VmPeak /proc/4170/status
VmPeak:6490428 kB
$ grep ^Hugepagesize /proc/meminfo
Hugepagesize:       2048 kB

6490428 / 2048는 대략 3169.154 huge pages이므로 최소 3170 huge pages가 필요해서, 다음과 같이 지정한다:

$ sysctl -w vm.nr_hugepages=3170

이 설정값은 다른 응용 프로그램에서도 huge page를 사용하다면, 이 보다 더 크게 잡을 필요도 있다. 리부팅 시에 이 설정을 유지하려면 /etc/sysctl.conf에 항목을 추가하는 것을 잊으면 안 된다.

가끔 커널이 원하는 만큼의 huge page 설정을 즉시 하지 못해 윗 명령을 여러번 해야할 경우도 있으며, 리부팅을 해야하는 경우도 있다. (리부팅 다음 즉시, 머신 메모리의 대부분은 huge page로 변환할 수 있기 때문에, 리부팅을 시도한다.) 시스템의 huge page 할당량은 다음 명령으로 확인한다:

$ grep Huge /proc/meminfo

이런 작업은 sysctl 명령으로 알 수 있는 vm.hugetlb_shm_group 설정값에 의한 huge page 설정 변경 권한을 가진 데이터베이스 서버가 운영되고 있는 운영체제 사용자가 필요하며, ulimit -l 명령으로 확인 하는 잠금 메모리 설정을 할 수 있는 사용자여야 한다.

PostgreSQL에서 huge pages의 기본 동작은 가능할 경우 사용하는 것이고 실패할 경우 일반 메모리 관리 방식으로 진행 된다. huge_pageson으로 설정하면 huge pages를 강제로 사용할 수 있다. 이 경우 사용 가능한 huge pages가 부족하면 PostgreSQL 서버가 실행되지 않는다.

Linux huge pages 기능에 대한 자세한 설명은 https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt 페이지를 읽어 보기 바란다.