PostgreSQL 문서중 커널 리소스 관리에 대한 부분이 있어서 참고자료로서 확인해봅니다. 


Shared Memory 와 Semaphores 에 대한 내용입니다.


PostgreSQL 은 운영체제에서 프로세스간 통신(IPC) 기능, 그 중 공유메모리(Shared Memory) 와 세마포어(Semaphores) 를 제공해야 합니다. 

Unix 관련 System 에서는 일반적으로 System V IPC 와 Posix IPC 두가지를 전부 제공합니다. Windows 에서는 이러한 기능을 자체적으로 구현을 하고 있기에 이번내용에서는 windows 에 대해서는 언급하지 않겠습니다. 


PostgreSQL 을 실행할때에 적은량의 System V Shared Memory 가 필요합니다. 그리고 그보다 큰 POSIX Shared Memory(mmap) 가 필요합니다. 

Posix shared memory 를 Linux 및 FreeBSD 에서 사용되며 System V shared memory 는 다른 플랫폼에서 사용합니다. 


System V IPC 에서 사용되는 Parameter 값 입니다.


NameDescriptionValues needed to run one PostgreSQL instance
SHMMAXMaximum size of shared memory segment (bytes)at least 1kB, but the default is usually much higher
SHMMINMinimum size of shared memory segment (bytes)1
SHMALLTotal amount of shared memory available (bytes or pages)same as SHMMAX if bytes, or ceil(SHMMAX/PAGE_SIZE) if pages, plus room for other applications
SHMSEGMaximum number of shared memory segments per processonly 1 segment is needed, but the default is much higher
SHMMNIMaximum number of shared memory segments system-widelike SHMSEG plus room for other applications
SEMMNIMaximum number of semaphore identifiers (i.e., sets)at least ceil((max_connections + autovacuum_max_workers + max_worker_processes + 5) / 16) plus room for other applications
SEMMNSMaximum number of semaphores system-wideceil((max_connections + autovacuum_max_workers + max_worker_processes + 5) / 16) * 17 plus room for other applications
SEMMSLMaximum number of semaphores per setat least 17
SEMMAPNumber of entries in semaphore mapsee text
SEMVMXMaximum value of semaphoreat least 1000 (The default is often 32767; do not change unless necessary)


위의 내용에 대한 여러가지 어려운 이야기들이 많은데 그 이야기는 "https://postgresql.kr/docs/9.6/kernel-resources.html" 를 통해서 확인하시기 바랍니다. 


각 플랫폼 별로 수정권장 사항에 대해서 언급하도록 하겠습니다. 


[AIX]

 AIX 는 모든 메모리가 공유 메모리로 사용되도록 설정이 됩니다. 버전 5.1은 SHMMAX 와 같은 파라미터에 대한 특수한 설정을 할 이유가 없습니다. 

DB/2 와 같은 일반적인 Database 의 기본설정입니다. 파일크기(fsize) 와 파일갯수(nofiles) 대간 기본 제한이 낮기에 ulimit 정보 수정은 필요 합니다. /etc/security/limits


[FreeBSD]

sysctl 혹은 loader 인터페이스를 사용해서 변경이 가능합니다. 

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

리부팅을 해서도 유지를 하려면 /etc/sysctl.conf 파일을 수정해야 합니다. 

/boot/loader.conf 에서도 가능합니다. 

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

수정후에는 리부팅이 필요합니다. 


[NetBSD]

$ sysctl -w kern.ipc.shmmax=16777216
sysctl 을 통해서 수정이 가능합니다. Reboot 이후에도 유지하려면 /etc/sysctl.conf 를 수정해야 합니다. 


[OpenBSD]

sysvshm 및 sysvsem 은 커널이 컴파일 된 경우에 활성화 되어야 합니다.(Default 설정) 공유메모리의 최대 크기는 옵션 (shmmaxpgs) 에 의해 결정이 됩니다. 

option        SYSVSHM
option        SHMMAXPGS=4096
option        SHMSEG=256

option        SYSVSEM
option        SEMMNI=256
option        SEMMNS=512
option        SEMMNU=256
option        SEMMAP=256


[HP-UX]

Default 값으로 정상설치에 충분 합니다. 대신 HP-UX 10 에서 semmnx Default 값이 128 로 해당값은 Huge Database 에는 작을수 있습니다. 

IPC 값 수정은 SAM 에서 수정 가능합니다. 


[Linux]

Default Max Segment size 는 32MB / Default Max total size 는 2097152 Pages 입니다. 

"Huge Pages" 를 이용한 특수한 커널 환경이 아닌경우 Page 는 대부분 4096 Bytes 입니다. 

Shared Memory size 는 sysctl 를 통해 변경이 가능합니다. 


16GB 의 예시 입니다.

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

reboot 이후에도 적용을 하려면  /etc/sysctl.conf 에 입력하면 됩니다. 


sysctl 이 안되는경우 /proc 에 직접 입력하는 방법도 있습니다. 


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

 - Linux Resource Limits


Unix 계열의 운영체제는 PostgreSQL 을 운영할때에 서버에 영향을 줄수있는 리소스 제한 이 다양하게 존제 합니다. 

그 중 사용자별 프로세스 수 / 프로세스당 open file 수 / 각 프로세스에서 사용가능한 메모리 에 대한 제한이 중요합니다. 

각각 하드 리밋 과 소프트 리밋이 존제 합니다. 소프트 리밋은 실제의값을 계산하는 것이며, 하드 리밋값 까지 증가가 가능합니다. 

관련 파라미터는 "maxproc, openfiles, datasize" 등이 있습니다. 

Linux 에서는 /proc/sys/fs/file-max 에서 파일의 최대 수를 결정합니다. 자세한 내용은 /usr/src/linux/Documentation/proc.txt 를 참조 하시면 됩니다. 



 - Linux Memory Overcommit

Linux 2.4 버전 이후부터는 가상 메모리의 기본설정이 PostgreSQL 을 운영하기에 적합한 환경은 아니다. 

Memory Overcommit 을 하는  방식으로 인해서 PostgreSQL 및 다른 Process 의 메모리 점유가 시스템의 가상 메모리의 소진 원인이 되는경우 커널은 PostgreSQL 의 postmaster 를 종료해야 한다. 


이런경우 아래와 같은 메시지가 발생한다. 

Out of Memory: Killed process 12345 (postgres).

PostgreSQL 프로세스가 메모리의 부족으로 인해 종료되었음을 나타낸다. 

기존의 데이터베이스 연결이 정상 작동하더라도 새로운 연결은 수행되지 않는다. 

복구를 위해서는 PostgreSQL 을 재시작 해야한다. 

메모리가 부족한경우 Swap 을 확보하여서 OOM 을 예방할수도 있다. 


PostgreSQL 자체가 메모리 부족의 원인이 되는경우에는 환경설정을 변경함으로 문제를 방지할수 있다. 

Memory 관련 Parameter 특히 shared_buffers 및 work_mem 을 줄이는것이 도움이 된다.  그 외에는 데이터베이스 서버로의 연결이 너무 많이 허용되어 있는것이 원인이 될수 있다. max_connection 을 줄이는 대신 외부연결 풀링 소프트웨어를 이용하는것을 권장한다. 


Linux 2.6 이상에서는 커널의동작을 수정해서 Memory Overcommit 을 방지할수 있다. OOM Killer 의 호출이 완전방지가 되는것은 아니나. 가능성이 확연이 줄어들며, 좀더 견고한 시스템을 운영할수 있게된다. 

sysctl -w vm.overcommit_memory=2
동일한 항목을 /etc/sysctl.conf 에 입력하여도 된다. 혹은 이와같은 설정인 vm.overcommit_ratio 을 수정할수도 있다. 

다른 방식은 PostgreSQL 프로세스가 OOM Killer 의 대상이 되지 않도록 설정값을 -1000 으로 수정하는 내용입니다. 

echo -1000 > /proc/self/oom_score_adj


 - Linux Huge Pages

Huge Page 를 사용하는경우 PostgreSQL은 shared buffers 값이 크게 지정하여 많은 메모리를 사용할 경우 한번에 큰 메모리 영역을 작업 단위로 지정하여서 메모리 읽기 쓰기 부하를 줄일수 있다. 

PostgreSQL 에서 이 기능을 활성화 하려면 커널 설정값이 CONFIG_HUGETLB_PAGE=y 및 CONFIG_HUGETLBS=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
해당 내용을 /etc/sysctl.conf 에 기록하여서 reboot 시에도 변경되지 않도록 한다. 
시스템의 huge page 값은 아래와 같이 확인합니다. 
$ grep Huge /proc/meminfo



'Database > PostgreSQL' 카테고리의 다른 글

8. PostgreSQL Upgrading  (0) 2017.11.13
7. PostgreSQL Server Shutdown  (0) 2017.11.06
5. PostgreSQL 데몬구동 설정 및 운영  (0) 2017.10.31
4. PostgreSQL 설치 시 요구사항  (0) 2017.10.31
3. PostgreSQL 설치하기  (0) 2017.10.27

+ Recent posts