Hướng dẫn sử dụng mysqlcheck để bảo trì, tối ưu và sửa lỗi hỏng bảng dữ liệu trong MySQL

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

Khi database không còn là “màu hồng”

Làm quản trị hệ thống, cảm giác tệ nhất không phải là code lỗi build failed — mà là lúc 3 giờ sáng nhận tin nhắn hệ thống sập vì database corruption. Mình từng dính đúng một vố như vậy với server chạy MyISAM, bảng ~8GB bỗng dưng báo Table is marked as crashed and should be repaired. Thay vì hoảng loạn tìm backup (vốn đã cũ 4 tiếng), mình chạy mysqlcheck và xử lý xong trong 7 phút.

Dù đang dùng InnoDB hay MyISAM, bảo trì định kỳ vẫn không thể bỏ qua. mysqlcheck không chỉ để sửa lỗi — nó còn lấy lại không gian đĩa bị phân mảnh và cập nhật index statistics để query chạy đúng plan sau nhiều tháng INSERT/DELETE liên tục.

mysqlcheck là gì và tại sao cần nó?

mysqlcheck là tiện ích CLI đi kèm MySQL và MariaDB. Hiểu đơn giản: nó là wrapper cho các câu lệnh SQL như CHECK TABLE, REPAIR TABLE, ANALYZE TABLEOPTIMIZE TABLE.

Thay vì phải login vào MySQL shell rồi gõ từng lệnh cho từng table một, bạn chạy một dòng ngoài terminal là xử lý xong cả database — hoặc toàn bộ server. Điểm cần nhớ: nó chạy được khi database đang online. Tuy nhiên, một số thao tác nặng sẽ lock table tạm thời, nên chọn giờ thấp điểm.

Thực hành: Các lệnh mysqlcheck phổ biến nhất

Trước khi chạy bất kỳ lệnh nào, cần có user với đủ quyền trên các table cần xử lý. Cấu trúc cơ bản:

mysqlcheck [options] [db_name [table_names]]

1. Kiểm tra lỗi toàn bộ Database

Đây là việc đầu tiên nên làm khi database phản hồi chậm bất thường hoặc trả về lỗi lạ. Chạy lệnh này để quét cấu trúc bảng, phát hiện corruption sớm trước khi nó leo thang thành sự cố lớn hơn.

# Kiểm tra tất cả các database trên server
mysqlcheck -u root -p --all-databases

# Chỉ kiểm tra một database cụ thể
mysqlcheck -u root -p ten_database

2. Tự động sửa lỗi (Auto-repair)

Khi check phát hiện lỗi — thường gặp với MyISAM — thêm flag --auto-repair để sửa ngay trong cùng lượt chạy. Một lưu ý kỹ thuật quan trọng: InnoDB không hỗ trợ REPAIR TABLE theo cách này. Nếu InnoDB bị corrupt, bạn cần dùng innodb_force_recovery trong my.cnf — đó là câu chuyện khác, phức tạp hơn nhiều.

mysqlcheck -u root -p --auto-repair --databases ten_database

3. Tối ưu hóa bảng (Optimize)

Sau vài tháng chạy production, các bảng log hay bảng thường xuyên DELETE sẽ tích lũy fragmentation. File .ibd phình ra, query đọc nhiều block hơn cần thiết, ổ đĩa tốn dung lượng vô ích. Mình từng chạy OPTIMIZE trên bảng log ~15GB và thu hồi được gần 4GB ngay lập tức.

mysqlcheck -u root -p --optimize ten_database

Với InnoDB, MySQL thực hiện ALTER TABLE ... ENGINE=InnoDB để rebuild lại bảng từ đầu — nên thao tác này lock table hoàn toàn trong suốt quá trình. Tránh chạy giờ cao điểm bằng mọi giá.

4. Phân tích bảng (Analyze)

Lệnh này cập nhật index statistics — con số mà MySQL Query Optimizer dùng để chọn execution plan. Khi statistics lỗi thời, optimizer có thể chọn sai index và biến một query 10ms thành full table scan mất vài giây. Nên chạy ANALYZE sau mỗi lần import dữ liệu lớn hoặc migration.

mysqlcheck -u root -p --analyze ten_database

Kinh nghiệm thực tế khi vận hành

Vài điều rút ra sau nhiều lần xử lý sự cố database thực tế:

  • Đừng chạy Optimize trên bảng lớn giờ cao điểm: Một bảng 20GB với hàng nghìn request đang chạy mà bị lock là cả hệ thống đứng hình ngay. Lên lịch 2–3 giờ sáng, hoặc dùng pt-online-schema-change nếu cần chạy zero-downtime.
  • Kết hợp nhiều flag: Gom check + repair + optimize vào một lượt để tiết kiệm thời gian:
mysqlcheck -u root -p --auto-repair --check --optimize --databases my_app_db
  • Dùng –fast sau sự cố mất điện đột ngột: Flag này chỉ kiểm tra những bảng không được đóng đúng cách, bỏ qua các bảng còn nguyên vẹn. Với server có 50+ tables, cách này tiết kiệm được 80–90% thời gian so với check toàn bộ.

Tự động hóa bảo trì với Cronjob

Đợi đến khi có lỗi mới xử lý là cách tiếp cận phòng thủ kém. Mình thiết lập script chạy mỗi Chủ Nhật để dọn dẹp định kỳ. Tạo file /opt/scripts/db_maintenance.sh:

#!/bin/bash
LOG="/var/log/db_maintenance.log"
echo "=== $(date) ===" >> "$LOG"
mysqlcheck -u root -p'YOUR_PASSWORD' --all-databases --optimize --silent >> "$LOG" 2>&1

Thêm vào crontab (chạy 3:00 sáng mỗi Chủ Nhật):

0 3 * * 0 /opt/scripts/db_maintenance.sh

Ghi log ra file giúp trace lại lịch sử khi cần điều tra sự cố sau này. Flag --silent chỉ output khi có lỗi — log sạch, dễ đọc hơn nhiều.

Kết luận

mysqlcheck không có giao diện đẹp, không có dashboard màu mè. Chỉ là một lệnh terminal — nhưng đúng lúc 3 giờ sáng khi database báo lỗi, một lệnh đó có thể là thứ duy nhất đứng giữa bạn và một sự cố nghiêm trọng.

Backup trước khi repair hoặc optimize sâu là nguyên tắc không thể bỏ. Và nên đưa mysqlcheck --check vào monitoring định kỳ — phát hiện sớm bao giờ cũng rẻ hơn sửa muộn.

Share: