Tất cả bài viết
Lập trìnhQuản trị LinuxLệnh du và dfLỗi tốn dung lượngHệ điều hànhThủ thuật Server

Tại sao xóa tệp tin rồi nhưng ổ cứng Linux vẫn báo đầy? Cách tìm và xử lý triệt để

Tại sao xóa tệp tin rồi nhưng ổ cứng Linux vẫn báo đầy? Cách tìm và xử lý triệt để

Bài viết giải thích nghịch lý giữa lệnh df và du khi kiểm tra dung lượng ổ cứng Linux và hướng dẫn cách tìm các tệp tin đã bị xóa nhưng vẫn bị tiến trình chiếm dụng bộ nhớ.

Nghịch lý dung lượng: Tại sao df và du cho kết quả khác nhau?

Hãy tưởng tượng bạn nhận được cảnh báo ổ cứng đầy vào lúc 2 giờ sáng. Bạn nhanh chóng đăng nhập vào máy chủ Linux và chạy lệnh 'df' để kiểm tra, kết quả hiện màu đỏ báo động 80-90% dung lượng đã dùng. Tuy nhiên, khi bạn chạy 'du /' để tìm thư mục nào đang chiếm dụng nhiều không gian nhất, kết quả lại chỉ ra rằng bạn chỉ mới sử dụng chưa tới một nửa ổ cứng. Bạn chạy đi chạy lại các lệnh này vài lần, tự hỏi liệu mình có đọc nhầm hay hệ thống đang gặp lỗi. Tình trạng này rất phổ biến trên các hệ điều hành dựa trên nhân Linux như Ubuntu hay CentOS, đặc biệt là trong các môi trường sản xuất (production) có cường độ ghi log cao.

Nguyên nhân nằm ở cách đo lường khác nhau của hai công cụ này. Lệnh 'df' (disk free) lấy thông tin trực tiếp từ metadata của hệ thống tệp (filesystem), hỏi hạt nhân (kernel) về số lượng khối (blocks) thực tế đang được đánh dấu là đã sử dụng. Trong khi đó, 'du' (disk usage) lại hoạt động bằng cách quét qua cấu trúc cây thư mục, đếm từng tệp tin mà nó có thể nhìn thấy được. Khi một tệp bị xóa nhưng vẫn đang bị một tiến trình (process) nào đó sử dụng, 'du' sẽ không thấy nó vì mục nhập trong thư mục đã mất, nhưng 'df' vẫn tính vì các khối dữ liệu trên ổ đĩa chưa thực sự được giải phóng.

Nguyên nhân cốt lõi: Tệp đã xóa nhưng vẫn bị giữ lại (Deleted-but-open)

Lý do phổ biến nhất khiến con số của df và du không khớp là do các tệp tin đã bị xóa bằng lệnh 'rm' nhưng vẫn đang được một tiến trình mở (open). Trong Linux, khi một chương trình mở một tệp, hệ điều hành sẽ tạo ra một bộ mô tả tệp (file descriptor). Nếu bạn xóa tệp đó bằng lệnh rm, Linux chỉ xóa mục nhập tên tệp trong thư mục (directory entry) để người dùng không nhìn thấy nữa. Tuy nhiên, nếu tiến trình vẫn đang giữ bộ mô tả tệp đó mở, hạt nhân sẽ giữ nguyên các khối dữ liệu trên đĩa để tiến trình tiếp tục làm việc. Chỉ khi tiến trình đóng tệp hoặc kết thúc hoàn toàn, hạt nhân mới thực sự thu hồi không gian đĩa đó.

Trường hợp điển hình nhất tại Việt Nam là các quản trị viên hệ thống thường xuyên xóa các tệp log lớn của Nginx, Apache hoặc các ứng dụng Java/Tomcat để giải phóng không gian nhanh chóng. Kết quả là lệnh 'du' báo dung lượng đã giảm, nhưng 'df' thì không có gì thay đổi và ổ đĩa vẫn trong trạng thái báo động đầy. Tại các môi trường doanh nghiệp sử dụng container hoặc hệ thống tệp overlay, hiện tượng này còn phức tạp hơn do các lớp lưu trữ chồng chéo, khiến việc quản lý tài nguyên trở nên khó khăn nếu không nắm rõ cơ chế này.

Cách tìm các tiến trình đang 'chiếm đoạt' dung lượng ẩn

Để tìm ra kẻ thủ ác đứng sau lượng dung lượng bị mất này, chúng ta cần sử dụng công cụ 'lsof' (list open files). Đây là công cụ mạnh mẽ để liệt kê tất cả các tệp đang được mở bởi mọi tiến trình trên hệ thống. Để lọc ra những tệp đã bị xóa nhưng vẫn còn bị giữ lại, bạn hãy thực thi lệnh sau với quyền sudo (quyền root là bắt buộc để quét được các tiến trình hệ thống):

bash
sudo lsof +L1

Tham số +L1 sẽ tìm kiếm các tệp có số lượng liên kết (link count) nhỏ hơn 1. Điều này có nghĩa là tệp đã mất liên kết trong bảng thư mục (đã bị xóa) nhưng vẫn được tham chiếu bởi một PID cụ thể. Một kết quả trả về thông thường sẽ cung cấp các cột quan trọng như: COMMAND (tên lệnh), PID (mã tiến trình), USER (người chạy), FD (bộ mô tả tệp), SIZE/OFF (dung lượng tệp) và NODE NAME (đường dẫn kèm nhãn deleted).

Ví dụ, nếu bạn thấy kết quả như bên dưới, bạn sẽ biết ngay Nginx đang giữ một tệp log có kích thước lên tới 500MB mặc dù tệp đó không còn tồn tại trong thư mục /var/log/.

bash
COMMAND  PID   USER   FD   TYPE  DEVICE    SIZE/OFF  NLINK  NODE  NAME
nginx    1423  root   10w  REG   253,1     524288000 0      1048  /var/log/nginx/access.log (deleted)
java     2201  tomcat 22w  REG   253,1     209715200 0      2341  /tmp/app.log (deleted)

Hướng dẫn giải phóng dung lượng mà không cần khởi động lại máy

Sau khi đã xác định được tiến trình đang chiếm giữ tệp, bạn có hai phương án để xử lý. Cách an toàn nhất là khởi động lại dịch vụ đó. Việc này sẽ buộc tiến trình đóng mọi tệp đang giữ và bắt đầu phiên làm việc mới, đồng thời giải phóng hoàn toàn các khối dữ liệu cũ cho hệ điều hành.

bash
sudo systemctl restart nginx

Tuy nhiên, trong một số trường hợp khẩn cấp trên hệ thống đang chạy ổn định (production) mà bạn không được phép gây gián đoạn (zero downtime), bạn có thể sử dụng thủ thuật ghi đè (truncate) trực tiếp vào bộ mô tả tệp thông qua hệ thống tệp ảo /proc. Bạn cần lấy PID và số hiệu FD từ kết quả lệnh lsof phía trên để thực hiện:

bash
sudo truncate -s 0 /proc/1423/fd/10

Lệnh này sẽ ngay lập tức đưa kích thước tệp về 0 mà không làm ngắt kết nối của tiến trình. Tuy nhiên, cần lưu ý: Tuyệt đối không áp dụng chiêu này cho các tệp dữ liệu quan trọng như tệp ghi nhật ký của cơ sở dữ liệu (write-ahead log) vì nó có thể gây hỏng hóc dữ liệu nghiêm trọng. Chỉ nên dùng cho các tệp văn bản log thông thường.

Tổng kết và bảng tra cứu nhanh

Quản trị hệ thống Linux đòi hỏi sự tinh tế trong việc hiểu cách hệ điều hành tương tác với phần cứng. Đừng bao giờ vội vàng xóa tệp một cách bừa bãi khi thấy ổ cứng đầy. Thay vào đó, hãy luôn kiểm tra xem dung lượng thực sự đi đâu bằng các công cụ phù hợp cho từng tình huống cụ thể.

Dưới đây là bảng tóm tắt các lệnh bạn nên nhớ để xử lý sự cố dung lượng: - Kiểm tra tổng quan hệ thống tệp: df -h - Tìm thư mục/tệp lớn nhất: du -sh * | sort -rh - Tìm tệp đã xóa nhưng vẫn chiếm chỗ: sudo lsof +L1 - Kiểm tra các thông số dự phòng hệ thống tệp: tune2fs -l /dev/sdX Kỹ năng xử lý sự cố đĩa đầy lúc nửa đêm sẽ trở nên nhẹ nhàng hơn nhiều nếu bạn nắm vững lệnh lsof kết hợp cùng việc sắp xếp theo kích thước: lsof +L1 | sort -k7 -rn. Điều này giúp bạn nhắm thẳng vào 'kẻ chiếm đất' lớn nhất để xử lý hiệu quả.

Chia sẻ: