PostgreSQL은 특히 서버의 복수 사본을 동일한 시스템에서 실행 중인 경우 또는 대규모 설치 중인 경우, 가끔씩 다양한 운영 체제 리소스 제한을 소진시킨다. 이 절에서는 PostgreSQL가 사용하는 커널 리소스 및 커널 리소스 소비와 관련된 문제 해결 단계를 다룬다.
PostgreSQL 서버는 내부-프로세스 통신(inter-process communication, IPC) - 구체적으로 공유 메모리와, 세마포어를 여러 프로세스가 함께 사용하는 것 - 을 제공하는 OS에서 실행된다. 유닉스 계열에서는 일반적으로 “System V” IPC, “POSIX” IPC 중 하나나, 둘 모두를 제공한다. Windows에서는 자체적인 방법으로 이 기능을 제공하며, 여기서는 언급하지 않는다.
이러한 기능을 제공하지 않는 OS에서 서버를 실행하면, “Illegal system call” 오류를 내면서 실행되지 않는다. 커널이 이런 기능을 제공하지 않는다면, 커널을 다시 만들거나, OS 환경 설정을 다시 하거나 해야한다. 이러한 상황은 최신 운영 체제에서는 거의 일어나지 않는다.
PostgreSQL 서버는 아주 적은 System V 공유 메모리와,
서버에서 사용할 공용 메모리로 POSIX (mmap
함수 이용)
공유 메모리를 사용한다.
또한 OS 세마포어도 필요한데, 이 수량도 서버가 실행될 때 확보한다.
현재 리눅스나 FreeBSD 인 경우는 POSIX 세마포어를 사용하고,
나머지 OS에서는 System V 세마포어를 사용한다.
PostgreSQL 9.3 이전에는, 서버 시작에 훨씬 더 많은 System V 공유 메모리가 필요했다. 버전이 오래된 서버를 실행 중인 경우 문서에서 서버 버전을 참고하기 바란다.
System V IPC를 사용하는 경우, 이들 자원(공유 메모리와 세마포어)은 OS 전역에서 공용으로 사용된다. PostgreSQL 서버를 실행 할 때, 필요한 만큼의 자원을 확보할 수 없다면, 서버 오류 메시지를 보이며 서버는 중지된다. ( 18.3.1절 참조). 이 OS 설정은 표 18.1 에서 대략적으로 설명한다. 하지만, 이들 설정은 OS 마다 서로 다르기 때문에, 사용하는 OS 설명서를 참조해야 한다. 몇몇 OS에 대해서는 아래에서 설명하고 있다.
표 18.1. System V IPC 파라미터
이름 | 설명 | 하나의 PostgreSQL 서버 인스턴스가 실행 될 때 필요한 값 |
---|---|---|
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 공유 메모리를 사용 중인 경우
시스템 차원(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
와 유사하게 늘릴 필요가 있을 수 있다.
이 파라미터는 세마포어 리소스 맵의 크기를 정의하며, 이 맵에서는 사용 가능한 세마포어의 연속 블록마다 항목을 필요로 한다.
세마포어 세트가 해제되면, 해제된 블록에 인접한 기존 항목에 추가되거나 새로운 맵 항목 아래에 등록된다.
맵이 꽉 차면 해제된 세마포어는 분실된다(리부팅될 때까지).
세마포어 공간의 조각화는 시간이 흐를수록 원래 있어야 할 것보다 사용 가능한 세마포어 수가 작아진다.
SEMMNU
및 SEMUME
같은 “semaphore undo”와 관련된 다양한 기타 설정은
PostgreSQL에 영향을 미치지 않는다.
POSIX 세마포어를 쓰는 경우는 System V 경우와 같다. that is one semaphore per allowed connection (max_connections), allowed autovacuum worker process (autovacuum_max_workers) and allowed background process (max_worker_processes). On the platforms where this option is preferred, there is no specific kernel limit on the number of POSIX semaphores.
모든 메모리가 공유 메모리로 사용되도록 설정되므로, 적어도 버전 5.1은
SHMMAX
같은 파라미터에 대해 특수한 설정을 할 필요가 없다.
이것은 DB/2 같은 다른 데이터베이스에서 일반적으로 사용된 설정의 한 종류이다.
그러나, 파일 크기(fsize
)와 파일 수(nofiles
)에 대한 기본 하드 제한이 너무 낮으므로 전역
ulimit
정보를 /etc/security/limits
에서 변경해야 할 수 있다.
기본 설정은 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
를 사용하면 가능하다.
sysctl의 security.jail.sysvipc_allowed
를 활성화하여 FreeBSD jail에서 실행 중인 경우 서로 다른 jail에서 실행 중인 postmaster들은 서로 다른 시스템 사용자에 의해 실행되어야 한다.
루트 사용자가 아닌 경우 서로 다른 jail에서 사용자가 공유 메모리 또는 세마포어를 간섭하지 못하게 하고 PostgreSQL IPC 클린업 코드가 올바로 작동되게 하기 때문에 이것은 보안을 개선시킨다
(FreeBSD 6.0 이상에서 IPC 클린업 코드는 서로 다른 jail에서 동일한 포트에 postmaster의 실행을 방지하기 때문에 다른 jail에서 프로세스를 올바로 감지하지 못한다.).
FreeBSD 4.0 이전 버전은 OpenBSD처럼 작동된다(아래 참조).
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 (아래 참조)처럼 작동된다.
옵션 SYSVSHM
및 SYSVSEM
은 커널이 컴파일된 경우에 활성화되어야 한다(기본으로 설정돼 있음).공유 메모리의 최대 크기는 옵션 SHMMAXPGS
(페이지 단위)에 의해 결정된다.
다음 예시는 다양한 파라미터 설정 방법을 보여준다.
optionSYSVSHM optionSHMMAXPGS=4096 optionSHMSEG=256 optionSYSVSEM optionSEMMNI=256 optionSEMMNS=512 optionSEMMNU=256
기본 설정은 보편적으로 정상적인 설치에 충분하다.HP-UX 10에서
SEMMNS
의 출고시 기본 설정은 128이며, 이것은 거대 데이터베이스 사이트에는 너무 적을 수 있다.
IPC 파라미터는 System Administration Manager (SAM)에서 설정할 수 있다. 완료 시 을 선택해야 한다.
→ 아래의최대 세그먼트 크기 기본값은 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
나머지 기본 설정은 아주 넉넉한 크기로, 일반적으로 변경이 불필요하다.
macOS에서 공유 메모리를 환경 설정하는 권장 방법은 다음과 같은 변수 할당이 포함된 /etc/sysctl.conf
파일을 생성하는 것이다.
kern.sysv.shmmax=4194304 kern.sysv.shmmin=1 kern.sysv.shmmni=32 kern.sysv.shmseg=8 kern.sysv.shmall=1024
일부 macOS 버전에서,
모두 5개의 공유 메모리 파라미터를
/etc/sysctl.conf
에 설정해야 하며, 그렇지 않으면 값이 무시된다는 점에 유의해야 한다.
macOS 최근 릴리스는 설정된 SHMMAX
가 정확히 4096의 배수가 아니면 이 값을 무시한다.
SHMALL
는 이 플랫폼에서 4 kB로 평가된다.
macOS 구 버전에서는 공유 메모리 파라미터에 대한 변경 내용이 적용되려면 리부팅 해야 한다.
10.5는 현재, sysctl을 사용하여 SHMMNI
를 제외한 모두를 상황에 따라 변경 가능하다.
그러나 리부팅 사이에 값이 유지될 수 있도록 /etc/sysctl.conf
를 통해 원하는 값을 설정하는 것이 최선이다.
/etc/sysctl.conf
파일은 macOS 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
는 일반적으로 macOS 시스템 업데이트 시 덮어쓰기 되므로 업데이트가 있을 때마다 사용자는 이러한 편집을 반복해야 한다.
macOS 10.2 이전 버전에서는 /System/Library/StartupItems/SystemTuning/SystemTuning
파일에서 이 명령을 편집해야 한다.
해당 설정은
/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 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 재시작 시 적용된다(리로드 아님).위의 것은 PostgreSQL이 postgres
그룹의 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 리소스 사용 제한도 올려야 할 필요가 있다.projects
및 prctl
에 대한 자세한 내용은 System Administrator's Guide의 "Chapter2:Projects and Tasks"를 참조 바란다.
If systemd is in use, some care must be taken
that IPC resources (shared memory and semaphores) are not prematurely
removed by the operating system. This is especially of concern when
installing PostgreSQL from source. Users of distribution packages of
PostgreSQL are less likely to be affected, as
the postgres
user is then normally created as a system
user.
The setting RemoveIPC
in logind.conf
controls whether IPC objects are
removed when a user fully logs out. System users are exempt. This
setting defaults to on in stock systemd, but
some operating system distributions default it to off.
A typical observed effect when this setting is on is that the semaphore objects used by a PostgreSQL server are removed at apparently random times, leading to the server crashing with log messages like
LOG: semctl(1234567890, 0, IPC_RMID, ...) failed: Invalid argument
Different types of IPC objects (shared memory vs. semaphores, System V vs. POSIX) are treated slightly differently by systemd, so one might observe that some IPC resources are not removed in the same way as others. But it is not advisable to rely on these subtle differences.
A “user logging out” might happen as part of a maintenance
job or manually when an administrator logs in as
the postgres
user or something similar, so it is hard
to prevent in general.
What is a “system user” is determined
at systemd compile time from
the SYS_UID_MAX
setting
in /etc/login.defs
.
Packaging and deployment scripts should be careful to create
the postgres
user as a system user by
using useradd -r
, adduser --system
,
or equivalent.
Alternatively, if the user account was created incorrectly or cannot be changed, it is recommended to set
RemoveIPC=no
in /etc/systemd/logind.conf
or another appropriate
configuration file.
At least one of these two things has to be ensured, or the PostgreSQL server will be very unreliable.
Unix계열의 운영 체제는 사용자의 PostgreSQL 서버에도 영향을 미칠 수 있는 리소스 제한 형태가 다양하다.
그 중에 사용자별 프로세스 수, 프로세스당 개방 파일 수, 각 프로세스에서 사용 가능한 메모리 양에 대한 제한이 특히 중요하다.
이러한 제한은 각각 “하드” 및 “소프트” 제한이 있다. 소프트 제한은 실제로 계산하는 것이지만, 사용자가 하드 제한까지 증가 시킬 수 있다.
하드 제한은 root 사용자만이 변경 가능하다.시스템 호출 setrlimit
는 이러한 파라미터의 설정을 담당한다.
쉘의 빌트인 명령어 ulimit
(Bourne 쉘) 또는 limit
(csh)는 커맨드 라인에서 리소스 제한을 제어하는 데 사용된다.
BSD 파생 시스템에서/etc/login.conf
파일은 로그인 동안 다양한 리소스 제한 설정을 제어한다.
자세한 내용은 운영 체제 문서를 참조 바란다.
관련 파라미터는 maxproc
, openfiles
및 datasize
들이 있다.예제는 아래와 같다.
default:\ ... :datasize-cur=256M:\ :maxproc-cur=256:\ :openfiles-cur=256:\ ...
(-cur
는 소프트 제한이다.하드 제한을 설정하려면
-max
를 덧붙인다.)
커널은 일부 리소스에 대해 시스템 차원(system-wide)의 제한을 가질 수 있다.
Linux에서
/proc/sys/fs/file-max
는 커널이 지원하는 개방 파일의 최대 수를 결정한다.
파일 내에 다른 수를 적거나 /etc/sysctl.conf
에 할당을 추가하면 변경이 가능하다.
프로세스당 파일의 최대 제한은 커널이 컴파일되는 시점에 수정된다.자세한 내용은
/usr/src/linux/Documentation/proc.txt
를 참조 바란다.
PostgreSQL 서버는 연결당 프로세스 1개를 사용하므로 허용된 연결 수에 해당되는 프로세스는 최소한 제공한 다음에 사용자는 시스템에서 필요로 하는 나머지를 제공해야 한다. 이것은 일반적으로 문제가 되지 않지만 머신 1대에 몇 개의 서버를 실행하는 경우에는 쉽지 않을 수 있다.
개방 파일에 대한 기본 제한은 시스템 리소스를 부적절하게 분할하지 않고도 여러 사용자가 머신에 공존할 수 있는 값인 “사회적으로 용인되는” 값으로 설정된다. 사용자가 필요에 따라 머신 1대에서 여러 개의 서버를 실행하지만, 특정한 전용 서버의 제한만 올리고자 할 수도 있다.
다른 한편으로, 일부 시스템에서는 독립된 프로세스들이 많은 수의 파일들을 열 수 있게 한다.그러면 몇 개의 프로세스만 실행되더라도 시스템 차원(system-wide)의 제한이 손쉽게 초과된다. 이러한 상황이 발생되었지만 시스템 차원(system-wide)의 제한을 변경하고 싶지 않을 경우에는 PostgreSQL의 max_files_per_process 환경 설정 파라미터를 설정하여 개방 파일의 소비를 제한할 수 있다.
Linux 2.4 이상에서 기본 가상 메모리 동작은 PostgreSQL의 경우 최적화 되어 있지 않다. 커널이 메모리 오버커밋을 이행하는 방식 때문에 PostgreSQL 또는 다른 프로세스의 메모리 수요가 시스템의 가상 메모리가 소진되는 원인이 되는 경우 커널은 PostgreSQL postmaster(마스터 서버 프로세스)를 종료해야 한다.
이런 경우가 발생하면 이와 같은 커널 메시지가 나타난다(해당 메시지를 찾아 보려면 시스템 문서 및 환경 설정 참조).
Out of Memory: Killed process 12345 (postgres).
이것은 postgres
프로세스가 메모리 압박 때문에 종료되었음을 나타낸다.기존 데이터베이스 연결이 정상 작동되더라도 새로운 연결은 수락되지 않는다.
복구하려면 PostgreSQL을 재시작해야 한다.
이 문제를 방지하는 방법 중 하나는 다른 프로세스 때문에 머신의 메모리가 소진되지 않을 것이 확실한 머신에서 PostgreSQL을 실행하는 것이다.실제 메모리와 swap 공간이 소진된 경우에만 메모리 부족(OOM) 킬러가 호출되기 때문에 메모리에 여유가 없는 경우에는 운영 체제의 swap 공간을 늘리면 문제를 방지하는 데 도움이 된다.
PostgreSQL 자체가 메모리 부족의 원인인 경우 환경 설정을 변경하면 문제를 방지할 수 있다.경우에 따라 메모리 관련 환경 설정 파라미터, 특히
shared_buffers
및 work_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
문서 파일이 존재한다고 해서 기능이 지원된다는 증거로 생각해서는 안 된다.의심스러울 경우는 커널 전문가 또는 커널 공급업체에게 문의 바란다.
huge pages를 사용하면 PostgreSQL 같이
shared_buffers 값이 크게 지정해 많은 메모리를
사용할 경우, 한번에 큰 메모리 영역을 작업 단위로 지정해,
메모리 읽기 쓰기 작업 비용을 줄일 수 있다.
PostgreSQL에서 이 기능을
활성화하려면
커널 환경 설정값이 CONFIG_HUGETLB_PAGE=y
및
CONFIG_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_pages
를
on
으로 설정하면 huge pages를 강제로 사용할 수
있다. 이 경우 사용 가능한 huge pages가
부족하면 PostgreSQL 서버가 실행되지 않는다.
Linux huge pages 기능에 대한 자세한 설명은 https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt 페이지를 읽어 보기 바란다.