Sửa lỗi 'No Space Left on Device' khi ổ đĩa vẫn còn dung lượng trống

intermediate🐧 Linux2026-07-17| Bất kỳ bản phân phối Linux nào (Ubuntu, Debian, CentOS, RHEL) sử dụng các hệ thống tệp như Ext4 hoặc XFS.

Error Message

No space left on device (despite having free disk space)
#linux#inode#sysadmin#troubleshooting

Vấn đề dung lượng 'ma'

Đây là một tình huống rất khó chịu. Bạn kiểm tra ổ đĩa bằng lệnh df -h và nó hiển thị còn 50GB trống, nhưng mỗi khi bạn cố gắng lưu một tệp, Linux lại báo lỗi: No space left on device. Điều này thường có nghĩa là bạn đã cạn kiệt Inodes.

Hãy coi Inode như một bản ghi trong cơ sở dữ liệu của hệ thống tệp. Mỗi tệp, thư mục hoặc liên kết tượng trưng (symlink) đơn lẻ đều cần một Inode. Nếu hệ thống tệp của bạn được định dạng để cho phép 1 triệu Inode và bạn tạo ra 1 triệu tệp nhỏ, bạn sẽ không thể tạo thêm tệp thứ 1.000.001—ngay cả khi bạn còn trống 500GB dung lượng vật lý.

1. Xác nhận tình trạng thiếu hụt Inode

Việc kiểm tra ổ đĩa thông thường không hiển thị tình trạng sức khỏe của Inode. Thay vào đó, bạn cần sử dụng cờ -i:

df -i

Kiểm tra cột IUse%. Nếu một phân vùng hiển thị mức sử dụng 99% hoặc 100%, bạn đã chạm giới hạn. Trên một phân vùng Ext4 20GB tiêu chuẩn, bạn thường có khoảng 1,3 triệu Inode. Khi số lượng này hết, hệ thống sẽ ngừng hoạt động.

2. Truy tìm các thư mục chứa quá nhiều tệp

Tiếp theo, bạn cần tìm xem hàng triệu tệp đó đang ẩn náu ở đâu. Thông thường, đây không phải là một tệp khổng lồ mà là hàng triệu tệp nhỏ 0KB hoặc 1KB. Chạy lệnh này để đếm số lượng tệp trên mỗi thư mục (quá trình này có thể mất vài phút trên các ổ đĩa chậm):

sudo find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n | tail -n 20

Lệnh này liệt kê 20 thư mục hàng đầu có số lượng tệp cao nhất. Nếu bạn thấy một thư mục có hơn 500.000 tệp, bạn đã tìm thấy mục tiêu của mình.

3. Dọn dẹp rác

Khi một thư mục chứa hàng triệu tệp, việc chạy lệnh rm * có thể sẽ thất bại với lỗi "Argument list too long". Điều này xảy ra vì shell không thể xử lý quá nhiều đối số cùng một lúc. Hãy sử dụng lệnh find để xóa chúng một cách an toàn theo từng đợt:

sudo find /path/to/bloated/dir -type f -delete

Các nguyên nhân phổ biến và tình huống thực tế

Tại sao điều này lại xảy ra? Thông thường, đó là do một tiến trình chạy ngầm hoặc một ứng dụng bị cấu hình sai. Trên một máy chủ web thông thường, các "nghi phạm" phổ biến là:

  • Các Session PHP bị bỏ quên: Nếu php.ini không tự động dọn dẹp, thư mục /var/lib/php/sessions có thể dễ dàng phình to lên tới 2 triệu tệp nhỏ.
  • Cơn ác mộng Maildrop: Nếu hệ thống thư nội bộ bị lỗi, /var/spool/postfix/maildrop có thể chứa đầy hàng trăm nghìn thông báo lỗi nhỏ.
  • Các Microservices không được quản lý: Các container Docker hoặc ứng dụng Node.js tạo ra hàng triệu tệp bộ nhớ tạm (cache) hoặc log nhỏ mà không bao giờ được xoay vòng (rotate).
  • Các thư mục phân cấp quá sâu: Các công cụ build tự động tạo ra cây phụ thuộc khổng lồ mà không dọn dẹp các phiên bản cũ.

Các phương pháp khôi phục nâng cao

Phương pháp 1: Xóa có chọn lọc

Nếu bạn cần giữ lại dữ liệu gần đây nhưng muốn dọn dẹp rác cũ—như các tệp session cũ hơn ba ngày—hãy sử dụng lệnh này:

sudo find /var/lib/php/sessions -type f -mtime +3 -delete

Phương pháp 2: Làm trống hàng chờ Postfix

Nếu hàng chờ thư (mail spool) là nút thắt cổ chai, đừng chỉ xóa tệp thủ công. Hãy sử dụng công cụ chuyên dụng để xóa hàng chờ một cách an toàn:

sudo postsuper -d ALL

Phương pháp 3: Săn tìm các File Descriptor "ma"

Đôi khi bạn đã xóa hàng triệu tệp, nhưng df -i vẫn hiển thị mức sử dụng 100%. Điều này xảy ra vì một tiến trình đang chạy (như Nginx hoặc Apache) vẫn đang mở các tệp đó. Nhân Linux sẽ không giải phóng Inode cho đến khi tiến trình đóng tệp. Tìm các tệp "ma" này tại đây:

sudo lsof | grep deleted

Nếu bạn thấy một dịch vụ đang giữ hàng nghìn tệp đã xóa, hãy khởi động lại dịch vụ đó để buộc giải phóng Inode:

sudo systemctl restart [tên_dịch_vụ]

Cách ngăn ngừa sự cố tái diễn

Dọn dẹp mới chỉ là một nửa chặng đường. Để ngăn chặn điều này xảy ra lần nữa, hãy thực hiện ba bước kiểm tra sau:

  • Cấu hình Logrotate: Đảm bảo các bản ghi log được nén và xóa sau một khoảng thời gian nhất định. Một thư mục log không được xoay vòng có thể ngốn 100.000 Inode trong một tháng.
  • Thiết lập cảnh báo Inode: Hầu hết các công cụ giám sát (như Nagios hoặc Zabbix) chỉ theo dõi dung lượng GB. Hãy cập nhật cảnh báo để kích hoạt khi df -i chạm mức 80%.
  • Kiểm tra các tác vụ Cron: Đảm bảo các script tự động của bạn có bao gồm bước dọn dẹp. Nếu một script tạo ra một tệp tạm mỗi phút, nó sẽ tiêu tốn 525.600 Inode trong một năm.

Related Error Notes