Linux

[Linux] OOM(Out of Memory)란?

SungWookKang 2023. 8. 30. 14:49
반응형

[Linux] OOM(Out of Memory)?

 

l  Linux

 

몇일전부터 개발 환경에서 겪던 문제로 멀쩡하던 MySQL 서비스가 갑자기 연결이 되지 않는다. 처음엔 단순히 현상인줄 알고, MySQL 서비스를 재시작 하였다. 그런데 동일한 상황이 하루에도 여러 발생하고 있어서 원인을 살펴보기로 했다. 원인을 살펴보니, 아래와 같은 로그가 있었다.

Aug 30 01:35:08 xxxxx kernel: [7189052.423131] [18540]   111 18540  1930392  1535479 12935168        0             0 mysqld
Aug 30 01:35:08 xxxxx kernel: [7189052.423132] Out of memory: Kill process 18540 (mysqld) score 512 or sacrifice child
Aug 30 01:35:08 xxxxx kernel: [7189052.424065] Killed process 18540 (mysqld) total-vm:7721568kB, anon-rss:6141916kB, file-rss:0kB, shmem-rss:0kB
Aug 30 01:35:08 xxxxx kernel: [7189052.749286] oom_reaper: reaped process 18540 (mysqld), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

 

OOM으로 인한 OOM Killer(강제 서비스 종료)였다. OOM 무엇이고 발생하는 것일까? 그리고 로그는 어떻게 확인할 있을까?

 

OOM (Out of Memory)

Linux swap 메모리와 물리 메모리를 모두 사용 , 프로세스에서는 필요에 의해 추가적인 물리 메모리 할당을 요청하였는데, 이상 할당할 물리 메모리 공간이 없어 할당이 불가능한 상태를 의미한다. 메모리 Over Commit 상태일 발생하는 현상으로 물리적으로 메모리가 부족하다는 뜻이다. 이러한 문제는 물리 메모리만 증설하면 사실 간단히 해결된다. 하지만 이러한 현상이 발생하는지 원인을 찾지 못한 상태에서 무한정 메모리를 증설할 수도 없다.

 

OOM Killer

서버 메모리 부족으로 OOM 발생하였을 , 리눅스에서는 메모리를 확보하기 위해 OOM Score 기준으로 점수가 높은 프로세스를 강제로 Kill 하여 메모리를 확보하는 Kernel 기능이다. 이렇게 OOM Killer 프로세스가 종료되면 내부 시스템 로그에 기록되어 추후 확인할 있다.

 

OOM Killer Log 확인

OOM Killer 프로세스가 종료되었을 때에는 각종 시스템 로그에서 확인할 있다. 시스템 로그에는 OOM Killer외에도 다양한 로그가 있기 때문에 로그 양이 많을 경우 필터를 해서 검색을 해야 수도 있다. 일반적으로 특별히 로그 경로를 수정하지 않았다면 아래 경로에서 다양한 시스템 로그를 확인할 있다.

 /var/log/

 

Kern.log에서는 아래와 같은 OOM 로그를 확인할 있었다.

cat kern.log

 

Aug 30 01:35:08 XXXXX kernel: [7189052.423131] [18540]   111 18540  1930392  1535479 12935168        0             0 mysqld
Aug 30 01:35:08 XXXXX kernel: [7189052.423132] Out of memory: Kill process 18540 (mysqld) score 512 or sacrifice child
Aug 30 01:35:08 XXXXX kernel: [7189052.424065] Killed process 18540 (mysqld) total-vm:7721568kB, anon-rss:6141916kB, file-rss:0kB, shmem-rss:0kB
Aug 30 01:35:08 xxxxx kernel: [7189052.749286] oom_reaper: reaped process 18540 (mysqld), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

 

syslog에서는 다양한 로그가 많이 기록되어 OOM이라는 필터를 사용하여 확인하였다.

cat syslog | grep oom

 

Aug 29 23:45:33 xxxxx kernel: [7182478.018455]  oom_kill_process+0x21f/0x420
Aug 29 23:45:33 xxxxx kernel: [7182478.018529] [ pid ]   uid  tgid total_vm      rss pgtables_bytes swapents oom_score_adj name
Aug 29 23:45:34 xxxxx kernel: [7182478.495925] oom_reaper: reaped process 22648 (mysqld), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
Aug 30 01:35:08 xxxxx kernel: [7189052.422998] icinga2 invoked oom-killer: gfp_mask=0x14200ca(GFP_HIGHUSER_MOVABLE), nodemask=(null), order=0, oom_score_adj=0
Aug 30 01:35:08 xxxxx kernel: [7189052.423021]  oom_kill_process+0x21f/0x420
Aug 30 01:35:08 xxxxx kernel: [7189052.423096] [ pid ]   uid  tgid total_vm      rss pgtables_bytes swapents oom_score_adj name
Aug 30 01:35:08 xxxxx kernel: [7189052.749286] oom_reaper: reaped process 18540 (mysqld), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

 

message 로그 파일에서도 동일한 오류 내역을 확인할 있다. Message 로그 파일은 다양한 로그 파일의 미러 역할을 하기 때문에 정말 다양한 로그가 기록되어 있다.

 

 

OOM killer 우선순위

로그를 살펴보면 OOM 의해 mysqld kill 되었음을 확인할 있다. 그렇다면 프로세스를 종료시키는 우선순위는 어떻게 정해질까? 가지 방법이 있다.

1.          oom_badness() 메소드에서 프로세스별 점수를 계산하여 종료시킬 프로세스를 선택한다.

2.          사용자가 특별히 지정하여 순위를 변동시킬 있다.

 

oom_badness() 사용하는 우선순위 선정 방법은 아래와 같다.

1.          특정 프로세스를 함으로써 최소한의 프로세스만 잃을 있어야 한다.

2.          많은 메모리를 회수할 있는 프로세스 (메모리 사용량이 작으면 되지 않는다.)

3.          프로세스중 Leak 발생하지 않는 프로세스 (릭이 발생하면 프로세스 Kill 의미가 없다)

4.          사용자가 특별히 지정한 프로세스

 

외에도 nice score 기반으로 우선순위를 선정할 있다.

 

 

OOM Killer score 확인

OOM score 확인 방법은 /proc/${pid}/oom_score 파일을 통해 조회할 있다. PID 확인하는 방법은 ps 명령을 사용한다.

l  ps : shell에서 실행중인 프로세스만 출력

l  ps -e : 실행 중인 모든 프로세스 출력

l  ps -f : 실행중인 모든 프로세스의 상태 정보 출력

l  ps -ef | grep mysql : grep 사용하여 특정 프로세스(mysql) PID 확인 한다.

 

ps -e | grep mywql

 

 

cat /proc/15368/oom_score

 

 

 

OOM Killer 순위 설정 방법

1.          특정 프로세스의 PID 조회

2.          /proc/PID/oom_adj 파일에 -17 입력. oom_adj -17 ~ 15 값을 가지며, 낮은 일수록 후순위.

3.          /proc_PID/oom_scroe_adj 파일에 -1000 입력. oom_score_adj -1000 ~ 1000 값을 가지며 낮은 값일수록 후순위.

 

아래 예시는 oom_adj 파일에 -17 변경하는 것으로 PID 변경하여 사용할 있다.

sudo echo -17 > /proc/${pid}/oom_ajd

 

아래 예시는 oom_score_adj파일에 -1000 변경하는 것으로 PID 변경하여 사용할 있다.

sudo echo -1000 > /proc/${pid}/oom_score_adj

 

 

메모리 누수로 인한 System hang 현상을 방지하기 위해 리눅서 커널에서는 OOM killer 자체는 비활성화 없기 때문에 순위 설정을 참고하여 중요한 프로세스는 Kill 되지 않도록 한다.

 

 

 

 

2023-08-30 / Sungwook Kang / https://sungwookkang.com

 

 

리눅스, Linux, OOM, OutOfMemory, 메모리부족현상, 강제킬, 프로세스확인, 메모리압박, 아웃오브메모리, OOMKiller, oom_score

반응형

'Linux' 카테고리의 다른 글

[Linux] 쉘(shell) 스크립트 기초  (0) 2023.09.05
[Linux] Alpine Linux (알파인 리눅스) 는 무엇일까?  (0) 2023.09.04
CnetOS 방화벽 설정  (0) 2015.07.22
CentOS 파일 압축/풀기  (0) 2015.07.22
CentOS 심볼 링크 설정  (0) 2015.07.22