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 킬러에 의해 죽지 않도록 프로세스에 대해 값을 매우 작게 설정할 수 있다는 것을 알고 있습니다 . 그러나 이것을 방지하는 다른 방법이 있습니까?
답변
리눅스는 메모리 오버 커밋을한다. 즉, 프로세스가 시스템에서 실제로 사용 가능한 것보다 많은 메모리를 요청할 수 있습니다. 프로그램이 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을 초과 할 수 없습니다. 위 참조.
[/편집하다]