OOM Killer - MySQL 서버 종료

OOM Killer - MySQL 서버 종료

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_adjOOM 킬러에 의해 프로세스가 종료되는 것을 방지하기 위해 프로세스의 값을 매우 작게 설정할 수 있다는 것을 알고 있습니다 . 하지만 이런 일이 발생하는 것을 방지할 수 있는 다른 방법이 있습니까?

답변1

Linux에는 메모리 오버커밋이 존재합니다. 이는 프로세스가 시스템에서 실제로 사용 가능한 것보다 더 많은 메모리를 요청할 수 있음을 의미합니다. 프로그램이 malloc()을 시도하면 커널은 "좋아, 메모리를 얻었습니다"라고 말하지만 유지하지는 않습니다. 메모리는 프로세스가 해당 공간에 무언가를 쓸 때만 예약됩니다.

차이점을 확인하기 위해 가상 메모리와 상주 메모리라는 2가지 측정항목이 있습니다. Virtual은 프로세스가 요청한 메모리이고 Resident는 프로세스가 실제로 사용하는 메모리입니다.

이 시스템을 사용하면 커널이 사용 가능한 것보다 더 많은 메모리를 부여하는 "초과 구독"이 발생할 수 있습니다. 그런 다음 시스템에 0바이트의 여유 메모리와 스왑이 있을 때 그는 다음을 수행해야 합니다.희생(살인)여유 메모리를 얻는 과정입니다.

OOM Killer가 작동하는 곳입니다. OOM은 메모리 소비 및 기타 여러 요인을 기준으로 프로세스를 선택합니다(상위 프로세스는 하위 프로세스의 1/2을 가져오고, 루트 소유 프로세스인 경우 점수는 4로 나뉩니다.Linux-MM.org/OOM_Killer

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

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

[편집하다]

다음 두 sysctls를 통해 오버커밋 동작을 변경할 수도 있습니다.

vm.overcommit_memory
vm.overcommit_ratio

에서 언급했듯이커널 문서

과도한 메모리 사용량:

값에는 메모리 오버커밋을 활성화하는 플래그가 포함되어 있습니다.

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

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

이 플래그가 2이면 커널은 "오버 커밋 안 함" 정책을 사용하여 메모리 오버 커밋을 방지하려고 합니다. user_reserve_kbytes가 이 정책에 영향을 미친다는 점에 유의하세요.

이 기능은 "만약의 경우"에 많은 양의 메모리를 malloc()하지만 메모리를 많이 사용하지 않는 프로그램이 많기 때문에 유용합니다.

기본값은 0입니다.

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

남용 비율:

overcommit_memory가 2로 설정되면 커밋된 주소 공간은 스왑에 이 비율의 물리적 RAM을 더한 값을 초과할 수 없습니다. 찾다.

[/편집하다]

관련 정보