OOM Killer: Tại sao Linux ‘trảm’ MySQL của bạn và cách cứu vãn

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Khi dịch vụ bỗng dưng “bay màu” không dấu vết

Sáng thứ Hai, bạn kiểm tra dashboard và thấy MySQL hoặc Redis đã ngừng hoạt động từ lúc nào. Log ứng dụng sạch bóng, không một dòng báo lỗi. Bạn restart lại thì mọi thứ chạy bình thường, nhưng chỉ vài tiếng sau, kịch bản cũ lại lặp lại.

Nhiều sysadmin mới vào nghề thường mất cả ngày để debug code hoặc kiểm tra config app. Thực tế, thủ phạm lại nằm ở tầng hệ điều hành. Linux đã âm thầm ra tay “trảm” tiến trình của bạn để cứu vãn hệ thống. Kẻ thực thi mệnh lệnh này chính là OOM Killer (Out of Memory Killer).

Bài viết này sẽ giúp bạn bắt quả tang OOM Killer và trang bị bộ “giáp” bảo vệ các tiến trình quan trọng nhất trên server.

Tại sao Linux lại giết ứng dụng của bạn?

Vấn đề bắt nguồn từ cơ chế Overcommit Memory. Kernel Linux cho phép các ứng dụng yêu cầu (allocate) lượng RAM lớn hơn mức vật lý thực tế. Kernel làm vậy vì tin rằng các ứng dụng hiếm khi dùng hết sạch số RAM chúng đã đăng ký cùng một lúc.

Hãy tưởng tượng server có 8GB RAM nhưng tổng lượng RAM các app đăng ký lên tới 12GB. Khi tất cả đồng loạt ngốn tài nguyên hoặc một app bị Memory Leak (rò rỉ bộ nhớ), RAM và Swap sẽ cạn kiệt. Để ngăn toàn bộ hệ thống bị treo cứng (Kernel Panic), OOM Killer sẽ được kích hoạt. Nó chọn ra một “nạn nhân” để khai tử nhằm giải phóng bộ nhớ ngay lập tức.

Thuật toán chọn mục tiêu

Linux không chọn bừa. Nó tính toán một chỉ số gọi là oom_score (từ 0 đến 1000). Điểm càng cao, khả năng bị “lên đoạn đầu đài” càng lớn. Các yếu tố ảnh hưởng bao gồm:

  • Tỷ lệ chiếm dụng RAM: App ngốn 90% RAM chắc chắn nằm trong tầm ngắm hàng đầu.
  • Thời gian sống: Các tiến trình lâu đời thường được ưu tiên giữ lại hơn là các tiến trình mới sinh.
  • Quyền hạn: Tiến trình chạy dưới quyền root có một chút ưu thế so với user thường.
  • Cấu hình oom_score_adj: Đây là biến số mà bạn có thể can thiệp.

Cách xác nhận dịch vụ bị OOM Killer hạ sát

Vì OOM Killer tác động từ bên ngoài, ứng dụng thường không kịp ghi log. Bạn phải tìm bằng chứng trong log hệ thống.

1. Truy vết bằng dmesg

Đây là công cụ nhanh nhất để xem các thông điệp từ kernel buffer. Hãy chạy lệnh:

dmesg -T | grep -i "out of memory"

Tham số -T giúp chuyển đổi timestamp sang thời gian thực. Nếu thấy dòng “Killed process [PID] (mysqld)”, bạn đã tìm đúng thủ phạm.

2. Sử dụng journalctl

Trên các hệ điều hành hiện đại như Ubuntu 22.04 hoặc CentOS 7/8, hãy dùng lệnh sau để xem chi tiết:

journalctl -xe | grep -i oom-killer

Một bản án “tử hình” điển hình sẽ hiển thị như sau:

[Oct 25 14:30:02] Out of memory: Killed process 1234 (mysqld) total-vm:2048500kB, anon-rss:1500400kB, oom_score_adj:0

Thông số anon-rss cho biết lượng RAM thực tế (khoảng 1.5GB) mà tiến trình đang chiếm giữ tại thời điểm bị giết.

Cách cấp “kim bài miễn tử” cho tiến trình

Nếu bạn muốn bảo vệ Database bằng mọi giá, hãy can thiệp vào file /proc/[PID]/oom_score_adj. Giá trị này chạy từ -1000 (không bao giờ giết) đến 1000 (ưu tiên giết trước).

Thiết lập tạm thời

Giả sử MySQL có PID là 1234, bạn chạy lệnh:

echo -1000 > /proc/1234/oom_score_adj

Cách này đơn giản nhưng sẽ mất hiệu lực ngay khi service restart vì PID sẽ thay đổi.

Cấu hình bền vững qua Systemd

Đây là phương pháp chuyên nghiệp nhất. Hãy chỉnh sửa file unit của service (ví dụ mysql.service):

sudo systemctl edit mysql

Thêm các dòng sau vào:

[Service]
OOMScoreAdjust=-1000

Sau đó, áp dụng thay đổi bằng cách reload daemon:

sudo systemctl daemon-reload
sudo systemctl restart mysql

Lời khuyên thực chiến: Đừng quá lạm dụng

Việc đặt -1000 cho mọi dịch vụ là một sai lầm chết người. OOM Killer là chốt chặn cuối cùng bảo vệ server. Nếu bạn cấm nó giết MySQL trong khi MySQL đang bị leak RAM nghiêm trọng, cả hệ thống sẽ rơi vào trạng thái treo cứng. Khi đó, bạn thậm chí không thể SSH vào để xử lý từ xa.

Thay vì chỉ lo chống chế, hãy thực hiện các bước sau:

  1. Giới hạn RAM ứng dụng: Cấu hình innodb_buffer_pool_size cho MySQL chiếm khoảng 60-70% RAM tổng.
  2. Thiết lập Swap: Dù Swap chậm hơn RAM, nó tạo ra một vùng đệm an toàn giúp hệ thống không bị sốc khi RAM tăng đột biến.
  3. Giám sát (Monitoring): Cài đặt cảnh báo khi RAM vượt ngưỡng 85% bằng Prometheus hoặc Zabbix.

Tổng kết

OOM Killer không phải là lỗi, nó là một tính năng bảo vệ. Hiểu rõ cách đọc log và điều chỉnh oom_score_adj giúp bạn làm chủ hệ thống tốt hơn. Lần tới, nếu thấy ứng dụng biến mất, đừng vội check code, hãy dmesg trước nhé!

Share: