OOM Killer - giết máy chủ MySQL


10

Trên một trong những bậc thầy MySQL của chúng tôi, OOM Killer đã gọi và giết máy chủ MySQL dẫn đến mất điện lớn. Sau đây là nhật ký kernel:

[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

Máy này có RAM 64GB.

Sau đây là các biến cấu hình mysql:

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

Ngoại trừ một số plugin nagios và tập lệnh bộ sưu tập số liệu, không có gì khác chạy trên máy này. Ai đó có thể giúp tôi tìm hiểu lý do tại sao kẻ giết người OOM bị triệu tập và làm thế nào tôi có thể ngăn chặn nó để được triệu tập trong tương lai. Có cách nào tôi có thể nói với sát thủ OOM không giết máy chủ mysql không. Tôi biết chúng ta có thể đặt oom_adjgiá trị rất ít cho một quá trình để ngăn chặn nó bị giết bởi kẻ giết người OOM. Nhưng có cách nào khác để ngăn chặn điều này.


2
Việc sử dụng bộ nhớ sẽ cao hơn 48G+ 512M+ 64Mvì cũng có một số chi phí và các cấu trúc khác cần xem xét; có một công thức cho việc này ở đâu đó nhưng tôi không thể tìm thấy nó ngay bây giờ. Không chắc chắn nếu điều này sẽ làm cho nó thổi 64G. Chỉ để chắc chắn rằng, freexác nhận 64Gcó sẵn ở nơi đầu tiên?
frostschutz

@frostschutz: có, lệnh miễn phí hiển thị 64G.
pradeepchhetri

Nói OOM Killer không giết mysqld rất có thể sẽ chỉ trì hoãn thảm họa trong một thời gian ngắn. Sửa chữa tốt hơn cấu hình của bạn.
SCAI

Câu trả lời:


25

Linux làm bộ nhớ quá mức. Điều đó có nghĩa là nó cho phép quá trình yêu cầu nhiều bộ nhớ hơn thực sự có sẵn trên hệ thống. Khi một chương trình cố gắng malloc (), kernel nói "OK bạn có bộ nhớ", nhưng không bảo lưu nó. Bộ nhớ sẽ chỉ được bảo lưu khi quá trình sẽ viết một cái gì đó trong không gian này.

Để thấy sự khác biệt, bạn có 2 chỉ số: Bộ nhớ ảo và Bộ nhớ thường trú. Ảo là bộ nhớ được yêu cầu bởi quy trình, Resident là bộ nhớ thực sự được sử dụng bởi quy trình.

Với hệ thống này, bạn có thể đi vào "đặt trước quá nhiều", kernel cấp nhiều bộ nhớ hơn khả dụng. Sau đó, khi hệ thống của bạn sử dụng 0 byte bộ nhớ trống và Hoán đổi, anh ta phải hy sinh (giết) một quá trình để có được bộ nhớ trống.

Đó là khi OOM Killer đi vào hoạt động. OOM chọn một quy trình dựa trên mức tiêu thụ bộ nhớ của anh ấy và nhiều yếu tố khác (phụ huynh đạt được 1/2 điểm số của con anh ấy; nếu đó là quy trình sở hữu gốc, điểm số được chia cho 4, v.v. Hãy xem Linux- MM.org/OOM_Killer

Bạn có thể ảnh hưởng đến điểm OOM bằng cách điều chỉnh /proc/MySQL_PID/oom_adjtệp. Bằng cách đặt nó thành -17, quá trình của bạn sẽ không bao giờ bị giết. Nhưng trước khi làm điều đó , bạn nên điều chỉnh tệp cấu hình MySQL của mình để hạn chế việc sử dụng bộ nhớ MySQL. Nếu không, OOM Killer sẽ giết quá trình hệ thống khác (như SSH, crontab, v.v.) và máy chủ của bạn sẽ ở trạng thái rất không ổn định, có thể dẫn đến hỏng dữ liệu tồi tệ hơn bất cứ điều gì.

Ngoài ra, bạn có thể xem xét sử dụng trao đổi nhiều hơn.

[BIÊN TẬP]

Bạn cũng có thể thay đổi hành vi quá mức của mình thông qua 2 sysctls này:

vm.overcommit_memory
vm.overcommit_ratio

Như đã nêu trong Tài liệu hạt nhân

overcommit_memory:

Giá trị này chứa một cờ cho phép vượt quá bộ nhớ.

Khi cờ này là 0, kernel cố gắng ước tính dung lượng bộ nhớ còn lại khi không gian người dùng yêu cầu thêm bộ nhớ.

Khi cờ này là 1, kernel giả vờ luôn có đủ bộ nhớ cho đến khi nó thực sự hết.

Khi cờ này là 2, kernel sử dụng chính sách "không bao giờ thừa" nhằm cố gắng ngăn chặn bất kỳ bộ nhớ quá mức nào. Lưu ý rằng user_reserve_kbytes ảnh hưởng đến chính sách này.

Tính năng này có thể rất hữu ích vì có rất nhiều chương trình mà malloc () số lượng lớn bộ nhớ "chỉ trong trường hợp" và không sử dụng nhiều chương trình.

Giá trị mặc định là 0.

Xem Tài liệu / vm / kế toán quá mức và bảo mật / commoncap.c :: cap_vm_enough_memory () để biết thêm thông tin.

overcommit_ratio:

Khi overcommit_memory được đặt thành 2, không gian địa chỉ đã cam kết không được phép vượt quá trao đổi cộng với tỷ lệ phần trăm RAM vật lý này. Xem ở trên.

[/BIÊN TẬP]


1
Đây là câu trả lời đúng. Tôi đã thấy các bài viết xung quanh sử dụng oom_score_adjđể sửa lỗi này, nhưng họ không thực sự hiểu cơ chế điểm số.
3manuek
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.