Lỗi gặp phải
Error writing file '/tmp/MYxxxxxx' (Errcode: 28 - No space left on device)
Lỗi này xuất hiện khi một truy vấn cần ghi file tạm — để sắp xếp, GROUP BY, ORDER BY, hoặc JOIN lớn — nhưng phân vùng đích không còn dung lượng. MySQL đặt tên các file tạm này là MYxxxxxx và ghi vào tmpdir, mặc định là /tmp trên Linux. Khi phân vùng đó đạt 100%, mọi truy vấn cần ghi xuống đĩa sẽ thất bại ngay lập tức với Errcode 28. Không có cơ chế thử lại, không có xử lý nhẹ nhàng — chỉ là lỗi tức thì.
Bước 1 – Xác nhận phân vùng đã thực sự đầy
df -h
Kiểm tra xem phân vùng /tmp hoặc / có hiển thị 100% không. Đừng dừng lại ở đó — hãy kiểm tra thêm inode:
df -i
Một phân vùng có thể cạn kiệt inode trước khi hết dung lượng byte. Nếu IUse% hiển thị 100%, cách xử lý vẫn như vậy: xóa file. Dung lượng còn trống không có ý nghĩa gì khi không còn inode để tạo file mới.
Bước 2 – Tìm và dọn sạch rác
Xóa file tạm MySQL cũ còn sót lại từ các truy vấn bị crash
# Stop MySQL first — don't remove active temp files
sudo systemctl stop mysql
# Remove stale temp files
sudo rm -f /tmp/MY*
# Restart
sudo systemctl start mysql
Tìm các file lớn nhất trên phân vùng đầy
sudo du -sh /* 2>/dev/null | sort -rh | head -20
Trên máy chủ bận rộn, lệnh này thường phát hiện binary log của MySQL chiếm 20–50 GB, log ứng dụng chưa bao giờ được xoay vòng, hoặc các bản backup dump cũ mà ai đó quên dọn dẹp.
Xóa binary log cũ (nếu binlog đang bật)
-- See exactly how much space binlogs are using
SHOW BINARY LOGS;
-- Purge logs older than 3 days
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;
Hoặc từ shell:
sudo find /var/lib/mysql -name 'mysql-bin.*' -mtime +3 -delete
Cắt bớt các file log quá lớn
sudo truncate -s 0 /var/log/mysql/error.log
sudo journalctl --vacuum-size=200M
Bước 3 – Chuyển tmpdir sang phân vùng lớn hơn (giải pháp lâu dài)
Các phân vùng /tmp nhỏ — thường chỉ 1–5 GB trên bản cài Linux mặc định — nhanh chóng bị đầy khi MySQL xử lý các tập kết quả lớn. Hãy trỏ tmpdir đến nơi có dung lượng thực sự rộng rãi hơn.
Tạo thư mục tạm riêng biệt
sudo mkdir -p /var/lib/mysql-tmp
sudo chown mysql:mysql /var/lib/mysql-tmp
sudo chmod 750 /var/lib/mysql-tmp
Cập nhật my.cnf / my.ini
[mysqld]
tmpdir = /var/lib/mysql-tmp
Trên Ubuntu/Debian, file config nằm tại /etc/mysql/mysql.conf.d/mysqld.cnf. Trên CentOS/RHEL là /etc/my.cnf.
Khởi động lại MySQL
sudo systemctl restart mysql
Bước 4 – Giảm dung lượng tạm mà truy vấn cần dùng
Không có thêm dung lượng đĩa ngay lúc này? Bạn có thể giảm nhu cầu ghi file tạm của MySQL bằng cách đẩy nhiều công việc hơn vào RAM.
Tăng bộ đệm sắp xếp trong bộ nhớ
[mysqld]
tmp_table_size = 256M
max_heap_table_size = 256M
sort_buffer_size = 4M
Đây là các giá trị cấp session, nên bạn có thể điều chỉnh cho một truy vấn nặng duy nhất mà không cần khởi động lại MySQL:
SET SESSION tmp_table_size = 268435456;
SET SESSION sort_buffer_size = 4194304;
-- then run your heavy query
Truy tìm truy vấn gây ra lỗi
SHOW PROCESSLIST;
Tìm các truy vấn có State: Copying to tmp table hoặc Creating sort index — đó là những ứng viên đang tràn xuống đĩa. Chạy EXPLAIN trên chúng. Thiếu index trên cột sắp xếp thường loại bỏ hoàn toàn việc sử dụng file tạm.
Xác nhận đã khắc phục
# 1. Confirm tmpdir is set correctly
SHOW VARIABLES LIKE 'tmpdir';
# 2. Check free space on the new tmpdir partition
df -h /var/lib/mysql-tmp
# 3. Re-run the failing query — it should complete without error
Muốn theo dõi file tạm xuất hiện theo thời gian thực trong khi truy vấn chạy? Lệnh một dòng này sẽ làm được điều đó:
watch -n1 'ls -lh /var/lib/mysql-tmp/'
Ngăn lỗi tái diễn
- Cảnh báo ở mức 80%, không phải 100% — khi phân vùng đã đầy, các truy vấn đã bắt đầu thất bại rồi. Hãy đặt cảnh báo dung lượng đĩa trên phân vùng
tmpdirở ngưỡng 80% để có thời gian xử lý. - Tự động hết hạn binary log — thêm
binlog_expire_logs_seconds = 259200(3 ngày) vàomy.cnf. Nếu không có cấu hình này, binlog sẽ tích lũy vô thời hạn và dễ dàng chiếm hơn 20 GB trên máy chủ ghi nhiều. - Xoay vòng error log MySQL — cấu hình logrotate cho
/var/log/mysql/error.log. Máy chủ bận rộn có thể tạo ra hàng trăm MB log mỗi ngày; nếu không xoay vòng sẽ tích lũy rất nhanh. - Sửa truy vấn, không chỉ sửa đĩa — một truy vấn đổ hàng gigabyte vào
/tmpthường là do thiếu index. ChạyEXPLAIN, tìm full table scan, và thêm index phù hợp. Cách này giải quyết triệt để nguyên nhân gốc rễ.

