Cách khắc phục lỗi MySQL ERROR 145: Table is marked as crashed and should be repaired

trung bình🗄️ MySQL2026-04-24| MySQL hoặc MariaDB chạy trên Linux (Ubuntu, CentOS, Debian) sử dụng storage engine MyISAM.

Error Message

ERROR 145 (HY000): Table './dbname/tablename' is marked as crashed and should be repaired
#mysql#myisam#bị-lỗi#sửa-lỗi#check-table

Vấn đề

Có thể bạn đang thực hiện một tác vụ thông thường thì đột nhiên truy vấn thất bại. Thay vì nhận được dữ liệu, bạn nhận được một thông báo khó hiểu: ERROR 145. Lỗi này là một "cơn đau đầu" kinh điển đối với bất kỳ ai vẫn đang sử dụng storage engine MyISAM.

Khác với InnoDB (đã trở thành mặc định từ MySQL 5.5.5 và sở hữu hệ thống khôi phục sau sự cố mạnh mẽ), MyISAM rất mong manh. Nó dễ bị hỏng nếu tiến trình MySQL bị gián đoạn trong khi đang ghi vào đĩa. Nếu máy chủ của bạn vừa bị đầy bộ nhớ 100% hoặc bị khởi động lại đột ngột, tệp chỉ mục (index file) có khả năng không được đóng đúng cách, khiến bảng bị gắn dấu "marked as crashed".

Cách khắc phục nhanh (TL;DR)

Bạn có quyền truy cập vào MySQL terminal hoặc phpMyAdmin? Hãy chạy lệnh này ngay lập tức để khắc phục khoảng 95% các trường hợp này:

REPAIR TABLE tablename;

Nếu cách sửa tiêu chuẩn không thành công, hãy thử phiên bản chuyên sâu hơn:

REPAIR TABLE tablename EXTENDED;

Tại sao bảng MyISAM bị lỗi (Crash)

Hiểu rõ nguyên nhân gốc rễ sẽ giúp ngăn lỗi này xảy ra thường xuyên. MyISAM lưu trữ dữ liệu qua ba tệp: .frm (schema), .MYD (dữ liệu) và .MYI (chỉ mục). Lỗi xảy ra khi phần header của tệp .MYI không đồng bộ với dữ liệu thực tế. Các nguyên nhân phổ biến bao gồm:

  • Tắt máy không đúng cách: Mất điện hoặc lập trình viên chạy lệnh kill -9 trên tiến trình MySQL.
  • Dung lượng đĩa: Máy chủ hết bộ nhớ trong khi đang cập nhật một bảng 5GB, khiến chỉ mục bị dở dang.
  • Lỗi phần cứng: SSD bị hỏng hoặc các cung từ (sector) RAM bị lỗi có thể làm hỏng dữ liệu trên đĩa.
  • Giới hạn tệp cũ: Chạm tới giới hạn kích thước tệp 2GB hoặc 4GB trên các hệ thống tệp 32-bit cũ.

Cách 1: Sửa lỗi qua SQL (An toàn và dễ dàng)

Hãy luôn thử phương pháp này đầu tiên. Nó hoạt động ngay cả khi máy chủ MySQL đang chạy và engine sẽ xử lý mọi việc khóa tệp phức tạp cho bạn.

1. Sửa lỗi tiêu chuẩn

Đăng nhập vào MySQL console và chọn cơ sở dữ liệu của bạn:

USE your_database_name;
REPAIR TABLE tablename;

Tìm hàng kết quả có Msg_type là "status". Nếu Msg_text hiển thị "OK", mọi thứ đã hoạt động trở lại.

2. Sửa lỗi mở rộng (Extended)

Đôi khi chỉ mục quá hỗn loạn để sửa nhanh. Thay vào đó, MyISAM có thể tạo lại chỉ mục theo từng hàng. Cách này tốn nhiều thời gian hơn nhưng triệt để hơn nhiều:

REPAIR TABLE tablename EXTENDED;

3. Sửa lỗi bằng tệp .frm

Nếu tệp .MYI của bạn bị mất hoặc bị hỏng hoàn toàn, bạn có thể yêu cầu MySQL xây dựng lại mọi thứ bằng cách sử dụng định nghĩa bảng được lưu trong tệp .frm:

REPAIR TABLE tablename USE_FRM;

Cách 2: Sửa lỗi qua dòng lệnh (myisamchk)

Đôi khi, sự hư hỏng nghiêm trọng đến mức dịch vụ MySQL thậm chí không thể khởi động hoặc nó bị sập mỗi khi bạn truy vấn bảng bị hỏng. Trong những tình huống này, hãy sử dụng tiện ích myisamchk từ Linux shell.

CẢNH BÁO: Bạn phải dừng dịch vụ MySQL trước khi sử dụng myisamchk. Chạy công cụ này trên một bảng đang hoạt động có thể dẫn đến mất dữ liệu vĩnh viễn.

# Dừng dịch vụ trước
sudo systemctl stop mysql

Di chuyển đến thư mục dữ liệu của bạn, thường nằm tại /var/lib/mysql/[db_name]/:

cd /var/lib/mysql/your_db_name/
myisamchk -r tablename.MYI

Cờ -r có nghĩa là "recover" (khôi phục). Nếu cách đó không hiệu quả, hãy thử cờ "safe recovery" (-o), chậm hơn nhưng cẩn thận hơn:

myisamchk -o tablename.MYI

Sau khi hoàn tất, hãy đưa cơ sở dữ liệu hoạt động trở lại:

sudo systemctl start mysql

Cách xác minh kết quả

Kiểm tra tình trạng của bảng sau khi sửa chữa để đảm bảo không còn vấn đề tồn đọng:

CHECK TABLE tablename;

Nếu trạng thái là "OK", bảng đã ổn định. Hãy chạy SELECT COUNT(*) để đảm bảo số lượng hàng khớp với mong đợi của bạn trước khi tiếp tục cho phép lưu lượng truy cập thực tế.

Cách ngăn ngừa lỗi trong tương lai

Mặc dù MyISAM đã từng là tiêu chuẩn trong nhiều năm, nhưng hiện nay nó được coi là công nghệ cũ đối với hầu hết các trường hợp sử dụng. Hãy chấm dứt chu kỳ sửa chữa này bằng ba bước sau:

1. Chuyển sang InnoDB

InnoDB tuân thủ tính chất ACID. Nó sử dụng redo log để tự động khôi phục sau sự cố mà không cần can thiệp thủ công. Hãy chuyển đổi engine của bảng chỉ với một lệnh duy nhất:

ALTER TABLE tablename ENGINE=InnoDB;

2. Theo dõi dung lượng đĩa

Hầu hết các lỗi sập MyISAM xảy ra do đĩa bị đầy 100%. Hãy thiết lập cảnh báo (như Monit hoặc Prometheus) để thông báo cho bạn khi dung lượng đĩa vượt quá 80%.

3. Tắt máy đúng quy trình

Đừng bao giờ ngắt nguồn điện máy chủ cơ sở dữ liệu đột ngột. Luôn sử dụng systemctl stop mysql hoặc mysqladmin shutdown để MySQL có thời gian đẩy dữ liệu từ bộ đệm (flush buffers) và đóng các index header một cách chính xác.

Related Error Notes