MySQL Error Log và General Query Log: Kỹ thuật ‘soi’ lỗi Production cho Sysadmin

MySQL tutorial - IT technology blog
MySQL tutorial - IT technology blog

Khi PagerDuty réo vang lúc 2 giờ sáng

Hệ thống sập ngay lúc bạn đang ngủ say sau ngày release căng thẳng. SSH vào server, bạn thấy CPU vẫn thấp, RAM còn dư nhưng ứng dụng liên tục báo Connection Refused. Cảm giác lúc đó cực kỳ bất lực nếu bạn không biết bắt đầu từ đâu.

Mình từng gặp ca khó: Database từ chối mọi kết nối mới mà không rõ lý do. Nhờ kiểm tra Error Log, mình phát hiện MySQL bị cạn kiệt open_files_limit (file descriptors). Chỉ mất 5 phút để tăng limit và restart, thay vì ngồi đoán mò cả đêm. Kinh nghiệm cho thấy: Quản trị MySQL mà không nắm vững log chẳng khác nào lái xe trong sương mù mà không có đèn pha.

Bài viết này mình sẽ tập trung vào hai loại log “sinh tử”: Error Log (bắt lỗi hệ thống) và General Query Log (giám sát mọi câu lệnh).

1. MySQL Error Log: Nhật ký sự cố hệ thống

Error Log là nơi đầu tiên bạn phải tìm đến khi MySQL crash hoặc không thể khởi động. Nó ghi lại mọi biến cố từ lúc engine bắt đầu chạy cho đến khi gặp lỗi nghiêm trọng.

Cấu hình Error Log chuẩn xác

Trên Production, đừng để log chạy mặc định. Hãy chỉ định đường dẫn cụ thể để dễ quản lý và backup. Bạn hãy mở file my.cnf (thường ở /etc/mysql/) và thêm các dòng sau:

[mysqld]
# Lưu log vào thư mục riêng
log_error = /var/log/mysql/error.log

# Với MySQL 8.0+, dùng verbosity để kiểm soát độ chi tiết
# 1: Chỉ Error, 2: Error + Warning, 3: Error + Warning + Note
log_error_verbosity = 3

Lưu ý: Việc restart MySQL trên Production rất rủi ro. Bạn nên dùng lệnh sau để kiểm tra vị trí log hiện tại mà không cần dừng dịch vụ:

SHOW VARIABLES LIKE 'log_error';

Mẹo đọc log không bị hoa mắt

Thay vì mở file nặng hàng GB, hãy dùng tail để theo dõi các dòng mới nhất theo thời gian thực:

tail -f /var/log/mysql/error.log | grep -i "error"

Các lỗi như Out of memory, Table is marked as crashed, hay Too many connections sẽ hiện ra ngay lập tức. Nếu thấy tag [ERROR], đó là tín hiệu bạn cần xử lý ngay.

2. General Query Log: Camera giám sát 24/7

Nếu Error Log báo hệ thống hỏng gì, thì General Query Log cho biết ai đã làm gì. Nó ghi lại mọi kết nối và mọi câu lệnh SQL mà server nhận được.

Mình từng phát hiện một module cũ chạy vòng lặp SELECT 1 hàng chục nghìn lần mỗi giây nhờ loại log này. Query đó không sai cú pháp nhưng nó ngốn sạch IOPS của server.

Kích hoạt General Query Log (Dùng thận trọng!)

Cảnh báo: General Log có thể làm giảm hiệu năng server từ 10% đến 15%. Nó ghi lại 100% hoạt động, khiến file log phình to rất nhanh. Chỉ bật khi cần debug sự cố cụ thể và tắt ngay sau đó.

Bạn có thể bật log trực tiếp trong MySQL shell mà không cần restart:

-- Kích hoạt log
SET GLOBAL general_log = 'ON';

-- Lưu vào file text truyền thống
SET GLOBAL log_output = 'FILE';
SET GLOBAL general_log_file = '/var/log/mysql/query_debug.log';

Nếu muốn dùng SQL để truy vấn log cho tiện, hãy đổi output sang TABLE. Dữ liệu sẽ được lưu vào bảng mysql.general_log. Tuy nhiên, lưu vào table sẽ gây áp lực lên storage engine nhiều hơn lưu file.

Khi nào bạn thực sự cần đến nó?

  • Kiểm tra xem ứng dụng có đang gửi query thừa (N+1 query) hay không.
  • Audit truy cập khi nghi ngờ có user truy cập trái phép vào bảng nhạy cảm.
  • Debug lỗi logic nghiệp vụ mà Error Log không thể bắt được.

3. Bài học xương máu: Đừng để log làm đầy ổ cứng

Một đồng nghiệp của mình từng quên tắt General Log trên server có traffic 5000 request/s. Kết quả là ổ cứng 200GB đầy sạch chỉ sau một đêm, khiến database treo cứng. Đây là sai lầm sơ đẳng nhưng cực kỳ phổ biến.

Giải pháp: Cấu hình Log Rotation

Hãy tận dụng logrotate trên Linux để tự động nén và xóa log cũ. Tạo file /etc/logrotate.d/mysql-server với nội dung:

/var/log/mysql/*.log {
    daily
    rotate 7
    missingok
    compress
    postrotate
        mysqladmin flush-logs
    endscript
}

Cấu hình này giúp bạn giữ lại 7 bản log gần nhất. Hệ thống sẽ tự động nén chúng để tiết kiệm dung lượng, giúp bạn yên tâm ngủ ngon.

4. Phân biệt nhanh các loại log

Đừng nhầm lẫn công dụng của chúng. Hãy nhớ quy tắc 3 dòng này:

  1. Error Log: Dùng khi MySQL không chạy được hoặc crash.
  2. General Log: Dùng để audit mọi hành động (bật khi debug logic).
  3. Slow Query Log: Dùng để tìm câu lệnh chạy chậm (> 1s) để tối ưu index.

Trong thực tế, Error Log luôn phải ở trạng thái ON. General Log chỉ nên bật trong khoảng thời gian ngắn (ví dụ 15-30 phút) để lấy mẫu dữ liệu.

Lời kết

Làm chủ log file là bước đầu tiên để trở thành một Senior Database Engineer. Đừng đợi đến khi sự cố xảy ra mới đi tìm file cấu hình. Hãy kiểm tra ngay hôm nay xem Error Log của bạn có đang ghi đúng chỗ không và logrotate đã hoạt động chưa. Chúc các bạn quản trị hệ thống ổn định và ít phải thức đêm!

Share: