Bagaimana cara memulihkan ruang kosong pada file yang dihapus tanpa memulai kembali proses referensi?

12

Ketika file besar dihapus di server, file mungkin masih dirujuk oleh proses, sehingga sistem file tidak memiliki lebih banyak ruang kosong.

Saya mencoba menggunakan lsof , tetapi sepertinya tidak mencantumkan file yang dihapus. fuser -cmemang bekerja lebih baik, tetapi daftar proses terlalu lama untuk memeriksanya untuk setiap proses, terutama karena setiap proses adalah proses 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

Kadang-kadang terjadi bahwa file terhapus oleh aplikasi atau pengguna, misalnya file log dan file ini masih dirujuk oleh proses yang tidak dapat dimulai ulang.

Apakah ada metode barang untuk mendapatkan kembali ruang disk pada file yang dihapus tanpa memulai kembali proses yang memiliki referensi ke file yang dihapus ini?

ujjain
sumber
untuk referensi .. cara yang lebih baik untuk menghapus file yang dibuka adalah menyalin / dev / null ke dalam filecp /dev/null file
Mike
@ Mike cp /dev/nulladalah perintah nol karena cptidak ada yang perlu disalin, pengalihan sederhana sangat setara :>fileatau bahkan>file
jlliagre

Jawaban:

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

Temukan semua deskriptor file yang dibuka.

Grep dihapus.

StdError ke / dev / null

Keluaran:

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

Atau Anda bisa menggunakan awk

find / proc / * / fd -ls 2> / dev / null | awk '/ dihapus / {print $ 11}';

output awk (diuji di bash Ubuntu 12.04):

/proc/28680/fd/113

Temukan dan pangkas semua file yang dihapus (diuji di bash Ubuntu 12.04):

(JANGAN MELAKUKAN INI JIKA ANDA TIDAK TAHU APA YANG ANDA LAKUKAN)

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

-p prompt sebelum menjalankan truncate

Cara yang lebih baik adalah pemotongan manual

Pemotongan manual:

: > /proc/28680/fd/113

atau:

> /proc/28680/fd/113

atau:

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

Nikmati ;)

pengguna3439968
sumber
+1, tapi saya juga meminta sudo untuk menjalankan perintah ini
79E09796
6

Berikut adalah contoh sederhana dengan less:

Anggaplah kita memiliki file 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% /

Sekarang saya membuka file itu dengan less(ya, itu adalah file biner ... sudahlah)

$ less /tmp/my10MBfile &

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

Lalu saya menghapus file itu

$ 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% /

Masih ada di sana, tetapi dihapus. Lihatlah kolom ke-4 keluaran lsof: File Descriptor number 4 open for Reading (4r)

Ayo jalankan GDB!

$ gdb -p $(pidof less)

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

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

Itu dia!

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

10 MB kami diterima kembali :)

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

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

Prosesnya masih berjalan.

maxxvw
sumber
2
Ok, tapi untuk berapa lama? banyak proses keluar jika mereka tidak dapat menulis ke file log mereka.
longneck
Logrotate tidak dapat melakukan ini untuk Anda?
maxxvw
logrotate mengirimkan sinyal proses untuk menutup file log dan membuka yang baru.
longneck
2

Perintah ini akan menampilkan semua file yang dihapus masih terbuka di sistem Solaris:

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

Anda dapat memotong yang Anda yakin ingin dengan perintah ini:

:> /proc/p/fd/x

dengan p menjadi id proses dan x deskriptor file dikembalikan oleh perintah pertama.

Jangan khawatir jika dengan beberapa program ukuran yang dilaporkan lsdikembalikan ke ukuran sebelum pemotongan setelah beberapa saat, ukuran sebenarnya yang digunakan pada disk akan jauh lebih kecil karena file sekarang jarang.

Jlliagre
sumber
0

Anda dapat mencoba untuk pergi ke /proc/<pid>/fddirektori dan deskriptor file truncate yang sesuai. Katakanlah fd = 3 poin ke file pid yang dihapus == 123:

# echo "" >! /proc/123/fd/3
kofemann
sumber
apakah Anda memiliki contoh di mana metode ini bekerja? Tidak dapat menemukan cara untuk mengubah FD dari sana
maxxvw
Ya, ini berfungsi, tetapi bagaimana menemukan pid dari proses?
ujjain
-2

Tidak ada solusi yang berhasil untuk saya. Hanya setelah menggunakan Bleachbit sebagai root saya bisa dengan benar membebaskan ruang yang terkait dengan file yang dihapus.

pengguna189721
sumber