Linux disk space incident là một trong những sự cố phổ biến nhất trong vận hành Linux production. Một phân vùng đầy có thể làm database ngừng ghi, ứng dụng trả lỗi 500, CI/CD fail, log mất dữ liệu, service không restart được hoặc thậm chí SSH login chậm bất thường. Điều nguy hiểm là nhiều người xử lý bằng cách “xóa đại file lớn nhất”, dẫn đến mất log điều tra, hỏng package cache, hoặc xóa nhầm dữ liệu ứng dụng.
Bài viết này là một runbook thực chiến cho sysadmin. Bối cảnh production/lab: máy Linux chạy Ubuntu/Debian hoặc RHEL/Rocky/Alma, có systemd-journald, logrotate, Docker/container runtime, một số service web/database và phân vùng root hoặc /var đang gần đầy. Mục tiêu là khôi phục dịch vụ nhanh nhưng vẫn an toàn, có khả năng truy vết và phòng ngừa tái diễn.
1. Dấu hiệu nhận biết ổ đĩa đầy
Ổ đĩa đầy thường xuất hiện dưới nhiều dạng khác nhau, không phải lúc nào cũng báo trực tiếp “No space left on device”. Một số dấu hiệu hay gặp:
- Ứng dụng báo lỗi ghi file, upload thất bại, session không lưu được.
- Database dừng ghi WAL/binlog hoặc không tạo được temporary file.
- Service restart fail vì không tạo được PID/socket/cache.
- Log có thông báo
No space left on device. - Package manager fail khi update vì không ghi được vào
/var/cache. - Filesystem còn dung lượng nhưng vẫn lỗi do hết inode.
2. Nguyên tắc xử lý trong production
Trước khi chạy lệnh cleanup, hãy giữ bốn nguyên tắc:
- Xác định phân vùng bị đầy: root,
/var,/home, volume data hay mount riêng của Docker/database. - Không xóa dữ liệu ứng dụng khi chưa hiểu: đặc biệt là database files, upload của người dùng, backup gần nhất.
- Ưu tiên cleanup có thể tái tạo: cache, log đã rotate, journal cũ, image/container không dùng.
- Ghi lại bằng chứng: output
df, thư mục lớn, service bị ảnh hưởng, hành động đã làm.
3. Bước 1: Xác định filesystem nào đang đầy
Lệnh đầu tiên cần chạy là df với định dạng dễ đọc:
df -hT
df -ih
df -hT cho biết dung lượng block, loại filesystem và mount point. df -ih kiểm tra inode. Nếu inode 100% thì xóa file nhỏ hoặc tăng dung lượng block chưa chắc giải quyết được.
Output mẫu:
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 ext4 40G 39G 200M 100% /
/dev/sdb1 xfs 200G 120G 80G 60% /data
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda2 2.6M 2.5M 20K 99% /
Trong ví dụ này, root vừa đầy block vừa gần hết inode. Runbook phải xử lý cả hai.
4. Bước 2: Tìm thư mục chiếm dung lượng lớn
Không dùng du -sh /* một cách máy móc trên server bận rộn nếu có mount network hoặc thư mục đặc biệt. Hãy giới hạn trong cùng filesystem bằng -x:
sudo du -xhd1 / 2>/dev/null | sort -h
sudo du -xhd1 /var 2>/dev/null | sort -h
sudo du -xhd1 /var/log 2>/dev/null | sort -h
Giải thích:
-x: không nhảy sang filesystem khác.-h: hiển thị dạng GB/MB dễ đọc.-d1: chỉ xem cấp thư mục đầu tiên để khoanh vùng nhanh.sort -h: sắp xếp theo dung lượng.
Nếu cần tìm file lớn:
sudo find /var -xdev -type f -size +500M -printf '%s %p
' 2>/dev/null | sort -n | tail -20
5. Bước 3: Xử lý systemd journal an toàn
Trên nhiều server, /var/log/journal tăng rất nhanh nếu service spam log. Kiểm tra dung lượng journal:
journalctl --disk-usage
sudo du -sh /var/log/journal 2>/dev/null
Cleanup an toàn theo thời gian hoặc dung lượng:
sudo journalctl --vacuum-time=14d
# hoặc giới hạn còn 1GB
sudo journalctl --vacuum-size=1G
Đừng xóa thủ công file journal đang dùng nếu không cần. Sau khi xử lý, cấu hình giới hạn lâu dài trong /etc/systemd/journald.conf:
[Journal]
SystemMaxUse=1G
SystemKeepFree=2G
MaxRetentionSec=14day
Áp dụng:
sudo systemctl restart systemd-journald
6. Bước 4: Kiểm tra logrotate và log ứng dụng
Nhiều sự cố disk full đến từ log ứng dụng không đi qua logrotate, hoặc logrotate cấu hình sai. Kiểm tra nhanh:
sudo logrotate -d /etc/logrotate.conf
sudo ls -lh /var/log | sort -k5 -h | tail -20
sudo find /var/log -type f -size +200M -printf '%s %p
' | sort -n | tail -20
logrotate -d chạy ở chế độ debug, không xoay log thật. Nếu cần ép rotate sau khi đã kiểm tra:
sudo logrotate -f /etc/logrotate.conf
Với log ứng dụng tự ghi, nên tạo rule riêng, ví dụ /etc/logrotate.d/myapp:
/var/log/myapp/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
copytruncate
}
copytruncate hữu ích khi app không reopen log sau rotate, nhưng có rủi ro mất vài dòng log trong lúc copy. Với app hỗ trợ signal reopen log, dùng postrotate sẽ tốt hơn.
7. Bước 5: Cleanup package cache đúng cách
Cache package thường có thể dọn an toàn hơn log/dữ liệu. Trên Debian/Ubuntu:
sudo apt-get clean
sudo apt-get autoremove --purge
Trên RHEL/Rocky/Alma:
sudo dnf clean all
sudo package-cleanup --oldkernels --count=2
Lưu ý: đừng xóa kernel đang boot. Kiểm tra trước:
uname -r
rpm -qa kernel | sort
8. Bước 6: Docker/container cleanup có kiểm soát
Docker có thể chiếm hàng chục GB vì image cũ, stopped container, build cache và volume. Kiểm tra:
docker system df
sudo du -sh /var/lib/docker 2>/dev/null
Cleanup tương đối an toàn:
docker container prune
docker image prune
docker builder prune
Chỉ dùng lệnh mạnh sau khi hiểu rủi ro:
docker system prune -a
-a xóa cả image không còn container dùng, có thể khiến lần deploy sau phải pull lại toàn bộ image. Không xóa volume bằng --volumes nếu chưa xác nhận volume không chứa dữ liệu stateful.
9. Bước 7: Tìm file đã bị xóa nhưng process vẫn giữ
Trường hợp hay gặp: ai đó xóa file log lớn, nhưng process vẫn mở file descriptor nên dung lượng chưa được trả về filesystem. Kiểm tra bằng lsof:
sudo lsof +L1
sudo lsof | grep deleted | head -50
Output mẫu:
nginx 1234 www-data 5w REG 8,2 2147483648 0 /var/log/nginx/access.log (deleted)
Cách xử lý là reload/restart service giữ file sau khi đánh giá ảnh hưởng:
sudo systemctl reload nginx
# nếu reload không nhả file
sudo systemctl restart nginx
10. Bước 8: Khi hết inode
Nếu df -h còn dung lượng nhưng df -ih đầy, nguyên nhân thường là quá nhiều file nhỏ: session file, cache, mail queue, tmp, build artifact. Tìm thư mục có nhiều file:
sudo find /var -xdev -type f | awk -F/ '{print "/"$2"/"$3}' | sort | uniq -c | sort -n | tail -20
Dọn theo policy của ứng dụng. Ví dụ xóa file tạm cũ hơn 7 ngày:
sudo find /tmp -xdev -type f -mtime +7 -print -delete
sudo find /var/tmp -xdev -type f -mtime +14 -print -delete
Không áp dụng lệnh find ... -delete cho thư mục ứng dụng nếu chưa hiểu naming convention và retention.
11. Bước 9: Mở rộng dung lượng bằng LVM/cloud volume
Nếu cleanup chỉ là tạm thời, cần mở rộng volume. Với LVM, quy trình thường là tăng disk/cloud volume, rescan, mở rộng partition/PV/LV rồi filesystem.
lsblk
sudo pvs
sudo vgs
sudo lvs
Ví dụ mở rộng LV dùng toàn bộ free space trong VG:
sudo lvextend -r -l +100%FREE /dev/mapper/vg0-root
-r tự resize filesystem nếu hỗ trợ. Với cloud, hãy snapshot trước khi thao tác nếu có thể. Với XFS, mở rộng online dùng xfs_growfs; ext4 dùng resize2fs.
12. Checklist nghiệm thu sau khi xử lý
df -hTcòn ít nhất 15–20% free hoặc đạt ngưỡng nội bộ.df -ihkhông còn cảnh báo inode.- Service bị ảnh hưởng đã hoạt động lại và health check pass.
- Không xóa nhầm dữ liệu ứng dụng, backup hoặc log điều tra quan trọng.
- Đã xác định root cause: log spam, journal không giới hạn, Docker cache, inode, backup local, upload tăng bất thường.
- Đã thêm cảnh báo monitoring cho disk usage và inode.
- Đã cập nhật logrotate/journald retention hoặc chính sách cleanup định kỳ.
- Đã ghi incident note: thời gian, impact, lệnh đã chạy, dung lượng giải phóng, hành động phòng ngừa.
13. Monitoring nên có để không bị bất ngờ
Tối thiểu, hãy cảnh báo khi filesystem vượt 80% và critical ở 90–95%, đồng thời theo dõi inode. Với Prometheus node_exporter, metric thường dùng là:
node_filesystem_avail_bytes
node_filesystem_size_bytes
node_filesystem_files_free
node_filesystem_files
Alert ý tưởng:
Disk usage > 85% for 15 minutes
Inode usage > 85% for 15 minutes
Filesystem read-only detected
Unexpected growth rate > 5GB/hour
Growth rate rất quan trọng. Một filesystem 70% nhưng tăng 10GB/giờ nguy hiểm hơn một filesystem 86% ổn định nhiều tháng.
14. Lab thực hành
- Tạo VM Linux 20GB, cài Nginx hoặc một service demo.
- Tạo file giả lập dung lượng bằng
fallocate -l 5G /var/log/big-test.log. - Dùng
df,du,findđể xác định nguyên nhân. - Cấu hình logrotate cho file demo và chạy
logrotate -d. - Tạo nhiều file nhỏ để mô phỏng inode và dùng
df -ihkiểm tra. - Viết runbook nội bộ gồm: lệnh chẩn đoán, cleanup được phép, escalation khi gặp database volume.
Kết luận
Linux disk space incident không nên được xử lý bằng phản xạ xóa file bừa. Sysadmin giỏi cần khoanh vùng đúng filesystem, phân biệt block với inode, dọn phần có thể tái tạo, kiểm tra process giữ file deleted, điều chỉnh retention và bổ sung monitoring. Khi có runbook rõ ràng, sự cố ổ đĩa đầy sẽ chuyển từ một ca chữa cháy hoảng loạn thành quy trình vận hành có kiểm soát.
