Bagaimana cara membebaskan penggunaan inode?

275

Saya memiliki disk drive di mana penggunaan inode adalah 100% (menggunakan df -iperintah). Namun setelah menghapus file secara substansial, penggunaannya tetap 100%.

Apa cara yang benar untuk melakukannya?

Bagaimana mungkin disk drive dengan penggunaan ruang disk lebih sedikit dapat memiliki penggunaan inode lebih tinggi daripada disk drive dengan penggunaan ruang disk lebih tinggi?

Apakah mungkin jika saya zip banyak file yang akan mengurangi jumlah inode yang digunakan?

neversaint
sumber
4
Ingin memberi Anda 50 poin untuk pertanyaan ini. Bagaimana saya bisa melakukannya! :)
Sophy
@Sophy Jangan lakukan itu. Anda akan diblokir secara otomatis
Steven Lu
1
@ SevenLu Terima kasih atas info Anda! Saya ingin memberikan kredit kepadanya karena saya menghabiskan beberapa hari untuk menyelesaikan masalah saya. Tapi masalah ini bisa membantu saya. Terima kasih lagi,
Sophy
1
@ Sophy: mengapa memberi sesuatu di luar topik untuk SO? :) Itu jelas bukan pertanyaan pemrograman, tidak peduli berapa banyak upvotes yang didapat.
tink
Direktori kosong juga mengkonsumsi inode. Menghapusnya dapat membebaskan beberapa inode. Jumlahnya bisa signifikan dalam beberapa kasus penggunaan. Anda dapat menghapus direktori kosong dengan: find. -type d -empty -delete
Patel

Jawaban:

170

Sangat mudah bagi disk untuk memiliki sejumlah besar inode yang digunakan bahkan jika disk tidak terlalu penuh.

Sebuah inode dialokasikan untuk sebuah file jadi, jika Anda memiliki banyak file, masing-masing 1 byte, Anda akan kehabisan inode jauh sebelum Anda kehabisan disk.

Mungkin juga menghapus file tidak akan mengurangi jumlah inode jika file memiliki banyak tautan keras. Seperti yang saya katakan, inode milik file, bukan entri direktori. Jika file memiliki dua entri direktori yang ditautkan, menghapus satu tidak akan membebaskan inode.

Selain itu, Anda dapat menghapus entri direktori tetapi, jika proses yang berjalan masih membuka file, inode tidak akan dibebaskan.

Saran awal saya adalah menghapus semua file yang Anda bisa, kemudian reboot kotak untuk memastikan tidak ada proses yang tersisa dengan membuka file.

Jika Anda melakukan itu dan Anda masih memiliki masalah, beri tahu kami.

Omong-omong, jika Anda mencari direktori yang berisi banyak file, skrip ini dapat membantu:

#!/bin/bash
# count_em - count files in all subdirectories under current directory.
echo 'echo $(ls -a "$1" | wc -l) $1' >/tmp/count_em_$$
chmod 700 /tmp/count_em_$$
find . -mount -type d -print0 | xargs -0 -n1 /tmp/count_em_$$ | sort -n
rm -f /tmp/count_em_$$
paxdiablo
sumber
12
Tentu saja, >/tmp/count_em_$$hanya akan berfungsi jika Anda memiliki ruang untuk itu ... jika itu masalahnya, lihat jawaban @ simon.
alxndr
1
@alxndr, itu sebabnya sering kali merupakan ide bagus untuk memisahkan sistem file Anda - dengan cara itu, mengisi sesuatu seperti /tmptidak akan memengaruhi sistem file Anda yang lain.
paxdiablo
Jawaban Anda sangat cocok untuk "sistem tidak akan tetap menggunakan file setelah reboot jika itu dihapus". Tetapi pertanyaan yang diajukan adalah "bagaimana cara mendapatkan kembali atau menggunakan kembali inode setelah inode pointer dihapus?". Pada dasarnya kernel linux membuat inode baru ke file kapan pun dibuat, dan juga secara otomatis tidak mengklaim kembali inode setiap kali Anda menghapus file.
Mohanraj
1
@AshishKarpe, saya berasumsi Anda sedang berbicara tentang situasi Anda sendiri karena OP tidak menyebutkan server produksi. Jika Anda tidak dapat memulai ulang dengan segera, maka ada dua kemungkinan. Pertama, berharap bahwa proses dalam penerbangan akhirnya menutup file saat ini sehingga sumber daya disk dapat dibebaskan. Kedua, bahkan server produksi harus memiliki ruang untuk me-reboot di beberapa titik - cukup jadwalkan beberapa downtime yang direncanakan atau tunggu jendela downtime berikutnya muncul.
paxdiablo
2
Saya kira Anda ingin ls -Abukan ls -a. Mengapa Anda ingin menghitung. dan ..?
jarno
205

Jika Anda sangat sial, Anda telah menggunakan sekitar 100% dari semua inode dan tidak dapat membuat skrip. Anda dapat memeriksanya dengan df -ih.

Maka perintah bash ini dapat membantu Anda:

sudo find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n

Dan ya, ini akan memakan waktu, tetapi Anda dapat menemukan direktori dengan sebagian besar file.

simon
sumber
8
itu berhasil. masalah saya adalah memiliki jumlah sesi yang luar biasa di direktori / lib / php / sesi. mungkin seseorang memiliki masalah yang sama
SteMa
2
Seseorang harus menulis ulang find, cut, uniq sort menjadi satu perintah awk!
mogsie
5
@alxndr awkdapat menyimpan hash dari direktori dan jumlah file tanpa uniqing dan menyortir trilyun baris. Yang mengatakan, mungkin inilah perbaikan: find . -maxdepth 1 -type d | grep -v '^\.$' | xargs -n 1 -i{} find {} -xdev -type f | cut -d "/" -f 2 | uniq -c | sort -n- ini hanya mengurutkan daftar terakhir.
mogsie
12
Jika Anda tidak dapat membuat file apa pun, bahkan itu dapat gagal karena sortmungkin gagal menyimpan semua yang ada di memori dan akan mencoba untuk secara otomatis kembali menulis file sementara. Sebuah proses yang jelas akan gagal ...
Mikko Rantalainen
10
sortgagal untuk saya, tetapi saya bisa memberikan --buffer-size=10Gyang berhasil.
Frederick Nord
69

Situasi saya adalah saya keluar dari inode dan saya sudah menghapus semua yang saya bisa.

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361     11  100% /

Saya menggunakan Ubuntu 12.04LTS dan tidak dapat menghapus kernel linux lama yang memakan sekitar 400.000 inode karena apt rusak karena paket yang hilang. Dan saya tidak bisa menginstal paket baru karena saya kehabisan inode jadi saya macet.

Saya akhirnya menghapus beberapa kernel linux lama dengan tangan untuk membebaskan sekitar 10.000 inode

$ sudo rm -rf /usr/src/linux-headers-3.2.0-2*

Ini cukup untuk membiarkan saya menginstal paket yang hilang dan memperbaiki apt

$ sudo apt-get install linux-headers-3.2.0-76-generic-pae

dan kemudian hapus sisa kernel linux lama dengan apt

$ sudo apt-get autoremove

segalanya jauh lebih baik sekarang

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/sda1      942080 507361 434719   54% /
LNamba
sumber
3
Ini adalah yang paling dekat dengan pendekatan saya sendiri dalam situasi yang sama. Perlu dicatat bahwa pendekatan yang lebih hati-hati didokumentasikan dengan baik di help.ubuntu.com/community/Lubuntu/Documentation/…
beldaz
Kasus saya tepatnya! Tetapi harus menggunakan "sudo apt-get autoremove -f" untuk maju
Tony Sepia
Apakah aman untuk melakukan ini:, sudo rm -rf /usr/src/linux-headers-3.2.0-2*jika saya yakin saya tidak menggunakan kernel itu?
Mars Lee
@ MarsLee Anda dapat memeriksa kernel mana yang sedang berjalan dengan "uname -a"
Dominique Eav
Menelepon $ sudo apt-get autoremovesendirian, melakukan trik untuk saya.
Morten Grum
49

Solusi saya:

Coba cari tahu apakah ini masalah inode dengan:

df -ih

Cobalah untuk menemukan folder root dengan jumlah inode yang besar:

for i in /*; do echo $i; find $i |wc -l; done

Cobalah untuk menemukan folder tertentu:

for i in /src/*; do echo $i; find $i |wc -l; done

Jika ini adalah tajuk linux, coba hapus yang terlama dengan:

sudo apt-get autoremove linux-headers-3.13.0-24

Secara pribadi saya memindahkannya ke folder yang terpasang (karena bagi saya perintah terakhir gagal) dan menginstal yang terbaru dengan:

sudo apt-get autoremove -f

Ini menyelesaikan masalah saya.

dardarlt
sumber
1
Dalam masalah kasus saya adalah SpamAssasin-Temp. find /var/spool/MailScanner/incoming/SpamAssassin-Temp -mtime +1 -print | xargs rm -fmelakukan pekerjaan :) Terima kasih!
joystick
4
Bagi saya, ini butuh berjam-jam. Namun, ada solusi sederhana: Ketika perintah kedua tergantung pada direktori tertentu, bunuh perintah saat ini dan mulai kembali pengubahan / * ke direktori apa pun yang sedang digunakan. Saya dapat menelusuri <menit pelakunya.
Michael Terry
Saya menggunakan varian ini dari perintah Anda untuk mencetak angka-angka pada baris yang sama: for i in /usr/src/*; do echo -en "$i\t"; find $i 2>/dev/null |wc -l; done
cscracker
for i in /src/*; do echo "$i, `find $i |wc -l`"; done|sort -nrk 2|head -10pamerkan top 10 direktori terbesar
Mark Simon
12

Saya memiliki masalah yang sama, memperbaikinya dengan menghapus sesi direktori php

rm -rf /var/lib/php/sessions/

Mungkin ada di bawah /var/lib/php5jika Anda menggunakan versi php yang lebih lama.

Buat kembali dengan izin berikut

mkdir /var/lib/php/sessions/ && chmod 1733 /var/lib/php/sessions/

Izin secara default untuk direktori pada Debian menunjukkan drwx-wx-wt(1733)

Anyone_ph
sumber
1
Adakah yang tahu mengapa ini terjadi?
Sibidharan
1
@Sibidharan dalam kasus saya itu karena tugas PHP cron untuk menghapus sesi PHP lama tidak berfungsi.
muram
3
rm -rf /var/lib/php/sessions/*mungkin akan menjadi perintah yang lebih baik - itu tidak akan menghapus direktori sesi, hanya isinya ... Maka Anda tidak perlu khawatir tentang membuatnya kembali
Shadow
Saya tidak punya sesi php tapi masalah sesi magento, mirip dengan ini. Terima kasih untuk arahannya.
Mohit
Sesi php tidak boleh dihapus melalui cron jobs, set session.gc_maxlifetime di php.ini php.net/manual/en/…
2

Kami mengalami ini di akun HostGator (yang membatasi inode pada semua hosting mereka) setelah serangan spam. Itu meninggalkan sejumlah besar catatan antrian di /root/.cpanel/comet. Jika ini terjadi dan Anda tidak memiliki inode gratis, Anda dapat menjalankan utilitas cpanel ini melalui shell:

/usr/local/cpanel/bin/purge_dead_comet_files
designgroop
sumber
2

Anda dapat menggunakan RSYNC untuk HAPUS sejumlah besar file

rsync -a --delete blanktest/ test/

Buat folder blanktest dengan 0 file di dalamnya dan perintah akan menyinkronkan folder pengujian Anda dengan sejumlah besar file (Saya telah menghapus hampir 5 juta file menggunakan metode ini).

Terima kasih kepada http://www.slashroot.in/which-is-the-fastest-method-to-delete-files-in-linux

VIGNESH
sumber
Dari apa yang dapat saya katakan dari artikel / komentar, ini lebih cepat daripada rm *banyak file, karena memperluas wildcard dan melewati / memproses setiap argumen, tetapi boleh rm test/saja menghapus test/folder yang berisi banyak file.
mwfearnley
Kepala, ini berfungsi dengan baik, tetapi pastikan Anda mengatur izin dengan benar di direktori kosong! Saya tidak melakukan ini dan secara tidak sengaja mengubah izin pada direktori sesi PHP saya. Butuh dua jam untuk mencari tahu apa yang saya lakukan.
aecend
1

eaccelerator dapat menyebabkan masalah karena mengkompilasi PHP ke dalam blok ... Saya punya masalah dengan server Amazon AWS di situs dengan beban berat. Bebaskan Inode dengan menghapus cache eaccelerator di / var / cache / eaccelerator jika Anda terus mengalami masalah.

rm -rf /var/cache/eaccelerator/*

(atau apa pun dir cache Anda)

supershwa
sumber
1

Kami menghadapi masalah serupa baru-baru ini, Jika suatu proses merujuk pada file yang dihapus, Inode tidak akan dirilis, jadi Anda perlu memeriksa lsof /, dan membunuh / memulai ulang proses akan merilis inode.

Koreksi saya jika saya salah di sini.

Razal
sumber
1

Seperti yang dikatakan sebelumnya, sistem file mungkin kehabisan inode, jika ada banyak file kecil. Saya telah menyediakan beberapa cara untuk menemukan direktori yang berisi sebagian besar file di sini .

jarno
sumber
0

Jawaban terlambat: Dalam kasus saya, ini adalah file sesi saya di bawah

/var/lib/php/sessions

yang menggunakan Inodes.
Saya bahkan tidak dapat membuka crontab saya atau membuat direktori baru apalagi memicu operasi penghapusan. Karena saya menggunakan PHP, kami memiliki panduan ini tempat saya menyalin kode dari contoh 1 dan mengatur cronjob untuk menjalankan bagian kode itu.

<?php
// Note: This script should be executed by the same user of web server 
process.

// Need active session to initialize session data storage access.
session_start();

// Executes GC immediately
session_gc();

// Clean up session ID created by session_gc()
session_destroy();
?>

Jika Anda bertanya-tanya bagaimana saya bisa membuka crontab saya, maka yah, saya menghapus beberapa sesi secara manual melalui CLI.

Semoga ini membantu!

Han
sumber
0

Anda bisa melihat info ini

for i in /var/run/*;do echo -n "$i "; find $i| wc -l;done | column -t
张馆长
sumber
-2

Banyak jawaban untuk yang ini sejauh ini dan semua yang di atas tampak konkret. Saya pikir Anda akan aman dengan menggunakan statsaat Anda melanjutkan, tetapi OS tergantung, Anda mungkin mendapatkan beberapa kesalahan inode merayap pada Anda. Jadi menerapkan statfungsi panggilan Anda sendiri menggunakan 64bituntuk menghindari masalah overflow tampaknya cukup kompatibel.

kinokaf
sumber
kami menyukai contoh di sini;)
Bohne
-3

Jika Anda menggunakan buruh pelabuhan, hapus semua gambar. Mereka menggunakan banyak ruang ....

Hentikan semua kontainer

docker stop $(docker ps -a -q)

Hapus semua kontainer

docker rm $(docker ps -a -q)

Hapus semua gambar

docker rmi $(docker images -q)

Bekerja untukku

Pankaj Shinde
sumber
Ini tidak membantu mendeteksi jika "terlalu banyak inode" adalah masalahnya.
Mark Stosberg
Ini tidak ada hubungannya dengan Docker.
Urda