Làm cách nào để khôi phục dung lượng trống trên các tệp đã xóa mà không khởi động lại các quy trình tham chiếu?


11

Khi các tệp lớn bị xóa trên máy chủ, các tệp vẫn có thể được tham chiếu bởi các quy trình, vì vậy hệ thống tệp không có nhiều không gian trống.

Tôi đã thử sử dụng lsof , nhưng có vẻ như nó không liệt kê các tệp đã bị xóa. fuser -cđã làm việc tốt hơn, nhưng danh sách các quy trình chỉ là quá dài để kiểm tra nó cho từng quy trình, đặc biệt vì mỗi quy trình là một quy trình của Oracle.

bash-3.2# fuser -c /var
/var:      105o   29999o   20444c    3528c   27258o    7715o    3864o    3862o    2494o   18205o   17450co   17445co   14912co   14824co   14818co   14816o   14814o    8532c    8530c    7633com    7118o    6958o    6790c    6784co    6734o    6693o    6689o    6684o    6675o    6635o    6594c    6548o    6547o    6546o    6545o    6544o    6543o    6542o    6541o    6540o    6537o    6535o    6456o    6128co    6113o     335o     245co     229o     161o       8o
bash-3.2# du -hs /proc
 139T   /proc

Đôi khi xảy ra việc một tệp bị xóa bởi một ứng dụng hoặc người dùng, ví dụ như tệp logfile và tệp này vẫn đang được tham chiếu bởi một quy trình không thể khởi động lại.

Có phương pháp hàng hóa để lấy lại không gian đĩa trên các tệp đã xóa mà không khởi động lại quá trình có tham chiếu đến tệp đã xóa này không?


để tham khảo .. một cách tốt hơn để xóa một tệp đã mở là sao chép / dev / null vào tệpcp /dev/null file
Mike

@Mike cp /dev/nulllà một lệnh null vì cpkhông có gì để sao chép, một chuyển hướng đơn giản hoàn toàn tương đương :>filehoặc thậm chí>file
jlliagre

Câu trả lời:


11
find /proc/*/fd -ls 2> /dev/null | grep '(deleted)'

Tìm tất cả các mô tả tập tin mở.

Grep đã xóa.

StdError thành / dev / null

Đầu ra:

160448715    0 lrwx------   1 user      user            64 Nov 29 15:34 /proc/28680/fd/113 -> /tmp/vteT3FWPX\ (deleted)

Hoặc bạn có thể sử dụng awk

tìm / Proc / * / fd -ls 2> / dev / null | awk '/ đã xóa / {in $ 11}';

đầu ra awk (được thử nghiệm trong bash Ubuntu 12.04):

/proc/28680/fd/113

Tìm và cắt bớt tất cả các tệp đã bị xóa (đã được thử nghiệm trong bash Ubuntu 12.04):

(ĐỪNG LÀM ĐIỀU NÀY NẾU BẠN KHÔNG BIẾT BẠN LÀM GÌ)

find /proc/*/fd -ls 2> /dev/null | awk '/deleted/ {print $11}' | xargs -p -n 1 truncate -s 0

-p nhắc trước khi thực hiện cắt ngắn

Cách tốt hơn là cắt ngắn thủ công

Hướng dẫn cắt ngắn:

: > /proc/28680/fd/113

hoặc là:

> /proc/28680/fd/113

hoặc là:

truncate -s 0 /proc/28680/fd/113

Thưởng thức ;)


+1, nhưng tôi cũng yêu cầu sudo chạy các lệnh này
79E09796

6

Đây là một ví dụ đơn giản với less:

Giả sử chúng ta có một tập tin , my10MBfile:

$ dd if=/dev/zero of=/tmp/my10MBfile bs=1M count=10
10+0 enregistrements lus
10+0 enregistrements écrits
10485760 octets (10 MB) copiés, 0,0454491 s, 231 MB/s

$ ls -l /tmp/my10MBfile
-rw-r--r-- 1 max max 10485760 avril 23 22:49 /tmp/my10MBfile

$ df -m /tmp
/dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0     14637  9225       4662  67% /

Bây giờ tôi mở tệp đó bằng less(vâng, nó là tệp nhị phân ... không sao cả)

$ less /tmp/my10MBfile &

$ lsof -p $(pidof less) | grep 10MBfile
less    29351  max    4r   REG    8,3 10485760 521464 /tmp/my10MBfile

Sau đó tôi xóa tập tin đó

$ rm /tmp/my10MBfile

$ lsof -p $(pidof less) | grep 10MBfile
less    29351  max    4r   REG    8,3 10485760 521464 /tmp/my10MBfile (deleted)

$ df -m /tmp
/dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0     14637  9225       4662  67% /

Nó vẫn ở đó, nhưng đã bị xóa. Nhìn vào cột thứ 4 của đầu ra lsof: Bộ mô tả tệp số 4 mở để đọc (4r)

Hãy chạy GDB!

$ gdb -p $(pidof less)

GNU gdb (GDB) 7.4.1-debian
....
Attaching to process 29351
....

(gdb) p close(4)
$1 = 0
(gdb) q

Đó là nó!

$ df -m /tmp
/dev/disk/by-uuid/6835b2fd-971d-420c-ba18-3c729ec2e8a0     14637  9215       4672  67% /

10 MB của chúng tôi được chào đón trở lại :)

$ ls /proc/29351/fd
0  1  2  3

$ ps 29351
29351 pts/0    S+     0:00 less /tmp/my10MBfile

Quá trình vẫn đang chạy.


2
Ok, nhưng trong bao lâu? nhiều quy trình chỉ cần thoát nếu chúng không thể ghi vào tệp nhật ký của chúng.
longneck

Logrotate không thể làm điều này cho bạn?
maxxvw

logrotate gửi quá trình một tín hiệu để đóng tệp nhật ký và mở một cái mới.
longneck

2

Lệnh này sẽ hiển thị tất cả các tệp đã xóa vẫn mở trên hệ thống Solaris:

find /proc/*/fd -type f -links 0

Bạn có thể cắt bớt những cái bạn chắc chắn muốn với lệnh này:

:> /proc/p/fd/x

với p là id quá trình và x mô tả tệp được trả về bởi lệnh đầu tiên.

Đừng lo lắng nếu với một số chương trình, kích thước được báo cáo lsđược khôi phục về kích thước trước khi cắt sau một thời gian, kích thước thực tế được sử dụng trên đĩa sẽ nhỏ hơn nhiều vì tệp bây giờ là một tệp thưa thớt.


0

Bạn có thể thử vào /proc/<pid>/fdthư mục và bộ mô tả tệp tương ứng. Giả sử fd = 3 điểm vào tệp đã xóa của pid == 123:

# echo "" >! /proc/123/fd/3

Bạn có một ví dụ về phương pháp này hoạt động không? Không thể tìm cách thay đổi FD từ đó
maxxvw

Vâng, điều này hoạt động, nhưng làm thế nào để tìm ra pid của quá trình?
ujjain

-2

Không có giải pháp nào trong số này làm việc cho tôi. Chỉ sau khi sử dụng Bleachbit với quyền root, tôi mới có thể giải phóng đúng không gian được liên kết với các tệp đã bị xóa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.