OOM Killer-MySQL 서버 종료


10

MySQL 마스터 중 하나에서 OOM Killer가 MySQL 서버를 호출하고 종료하여 큰 중단을 초래했습니다. 다음은 커널 로그입니다.

[2006013.230723] mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0
[2006013.230733] Pid: 1319, comm: mysqld Tainted: P           2.6.32-5-amd64 #1
[2006013.230735] Call Trace:
[2006013.230744]  [<ffffffff810b6708>] ? oom_kill_process+0x7f/0x23f
[2006013.230750]  [<ffffffff8106bde2>] ? timekeeping_get_ns+0xe/0x2e
[2006013.230754]  [<ffffffff810b6c2c>] ? __out_of_memory+0x12a/0x141
[2006013.230757]  [<ffffffff810b6d83>] ? out_of_memory+0x140/0x172
[2006013.230762]  [<ffffffff810baae8>] ? __alloc_pages_nodemask+0x4ec/0x5fc
[2006013.230768]  [<ffffffff812fca02>] ? io_schedule+0x93/0xb7
[2006013.230773]  [<ffffffff810bc051>] ? __do_page_cache_readahead+0x9b/0x1b4
[2006013.230778]  [<ffffffff810652f8>] ? wake_bit_function+0x0/0x23
[2006013.230782]  [<ffffffff810bc186>] ? ra_submit+0x1c/0x20
[2006013.230785]  [<ffffffff810b4e53>] ? filemap_fault+0x17d/0x2f6
[2006013.230790]  [<ffffffff810cae1e>] ? __do_fault+0x54/0x3c3
[2006013.230794]  [<ffffffff812fce29>] ? __wait_on_bit_lock+0x76/0x84
[2006013.230798]  [<ffffffff810cd172>] ? handle_mm_fault+0x3b8/0x80f
[2006013.230803]  [<ffffffff8103a9a0>] ? pick_next_task+0x21/0x3c
[2006013.230808]  [<ffffffff810168ba>] ? sched_clock+0x5/0x8
[2006013.230813]  [<ffffffff81300186>] ? do_page_fault+0x2e0/0x2fc
[2006013.230817]  [<ffffffff812fe025>] ? page_fault+0x25/0x30

이 기기에는 64GB RAM이 있습니다.

다음은 mysql 구성 변수입니다.

innodb_buffer_pool_size        = 48G
innodb_additional_mem_pool_size = 512M
innodb_log_buffer_size         = 64M

일부 nagios 플러그인 및 메트릭 수집 스크립트를 제외하고이 시스템에서 다른 것은 실행되지 않습니다. 누군가 OOM killer가 호출 된 이유와 나중에 호출되는 것을 방지 할 수있는 방법을 알려줄 수 있습니까? OOM 킬러에게 mysql 서버를 죽이지 말라고 말할 수있는 방법이 있습니까? oom_adj프로세스가 OOM 킬러에 의해 죽지 않도록 프로세스에 대해 값을 매우 작게 설정할 수 있다는 것을 알고 있습니다 . 그러나 이것을 방지하는 다른 방법이 있습니까?


2
고려해야 할 오버 헤드 및 기타 구조가 있기 때문에 메모리 사용량이 48G+ 512M+ 보다 높습니다 64M. 어딘가에 대한 수식이 있었지만 지금은 찾을 수 없습니다. 이것이 원인이 될지 확실하지 않습니다 64G. 그래도 free확인하기 64G위해 처음부터 사용할 수 있는지 확인하십시오 .
frostschutz

@frostschutz : 그렇습니다, 자유 명령은 64G를 보여줍니다.
pradeepchhetri

OOM Killer에게 mysqld를 죽이지 말라고하면 짧은 시간 동안 재난이 지연 될 가능성이 높습니다. 구성을보다 잘 수정하십시오.
scai

답변:


25

리눅스는 메모리 오버 커밋을한다. 즉, 프로세스가 시스템에서 실제로 사용 가능한 것보다 많은 메모리를 요청할 수 있습니다. 프로그램이 malloc ()을 시도 할 때 커널은 "OK you have a memory"라는 메시지를 표시하지만 예약하지는 않습니다. 프로세스가이 공간에 무언가를 쓸 때만 메모리가 예약됩니다.

차이점을 확인하기 위해 가상 메모리와 상주 메모리라는 두 가지 표시기가 있습니다. 가상은 프로세스가 요청한 메모리이고, 상주는 프로세스가 실제로 사용하는 메모리입니다.

이 시스템을 사용하면 커널이 사용 가능한 것보다 많은 메모리를 부여하는 "과다 예약"으로 들어갈 수 있습니다. 그런 다음 시스템이 0 바이트의 사용 가능한 메모리와 스왑을 수행하면 사용 가능한 메모리를 확보하기 위해 프로세스를 희생 (kill) 해야합니다 .

그때 OOM Killer가 작동합니다. OOM은 메모리 소비 및 기타 많은 요소 (부모가 자녀 점수의 1/2을 얻습니다. 루트 소유 프로세스 인 경우 점수는 4로 나뉩니다.)를 기준으로 프로세스를 선택합니다. Linux를 살펴보십시오. MM.org/OOM_Killer

/proc/MySQL_PID/oom_adj파일 을 조정하여 OOM 점수에 영향을 줄 수 있습니다 . 로 설정하면 -17프로세스가 종료되지 않습니다. 그러나 그렇게 하기 전에 MySQL 메모리 사용을 제한하기 위해 MySQL 구성 파일조정 해야 합니다. 그렇지 않으면 OOM Killer가 다른 시스템 프로세스 (SSH, crontab 등과 같은)를 종료하고 서버가 매우 불안정한 상태가되어 데이터 손상으로 이어질 수 있습니다.

또한 더 많은 스왑 사용을 고려할 수 있습니다.

[편집하다]

다음 2 개의 sysctls를 통해 초과 커밋 동작을 변경할 수도 있습니다.

vm.overcommit_memory
vm.overcommit_ratio

커널 문서에 명시된 바와 같이

overcommit_memory :

이 값에는 메모리 초과 커밋을 활성화하는 플래그가 포함됩니다.

이 플래그가 0이면, 커널은 사용자 공간이 더 많은 메모리를 요청할 때 남은 여유 메모리의 양을 추정하려고 시도합니다.

이 플래그가 1이면 커널은 실제로 부족할 때까지 항상 충분한 메모리가있는 것으로 가장합니다.

이 플래그가 2 인 경우, 커널은 "과도하게 커밋하지 않음"정책을 사용하여 메모리가 너무 커밋되지 않도록합니다. user_reserve_kbytes는이 정책에 영향을 미칩니다.

이 기능은 malloc () 방대한 양의 메모리가 "경우에 따라"많은 프로그램을 사용하지 않기 때문에 매우 유용 할 수 있습니다.

기본값은 0입니다.

자세한 내용은 Documentation / vm / overcommit-accounting 및 security / commoncap.c :: cap_vm_enough_memory ()를 참조하십시오.

overcommit_ratio :

overcommit_memory를 2로 설정하면 커밋 된 주소 공간이 스왑 +이 백분율의 실제 RAM을 초과 할 수 없습니다. 위 참조.

[/편집하다]


1
이것이 정답입니다. 이 문제oom_score_adj해결 하기 위해 사용 하는 기사를 보았지만 실제로 점수 메커니즘을 이해하지 못합니다.
3manuek
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.