วิธีการใช้ Inode ฟรี


275

ฉันมีดิสก์ไดรฟ์ที่ใช้ inode 100% (ใช้df -iคำสั่ง) อย่างไรก็ตามหลังจากลบไฟล์อย่างมีนัยสำคัญการใช้งานยังคงอยู่ 100%

แล้ววิธีที่ถูกต้องในการทำคืออะไร?

เป็นไปได้อย่างไรที่ดิสก์ไดรฟ์ที่มีการใช้พื้นที่ดิสก์น้อยกว่าสามารถมีการใช้งานไอโหนดสูงกว่าดิสก์ไดรฟ์ที่มีการใช้พื้นที่ดิสก์มากขึ้น

เป็นไปได้หรือไม่ถ้าฉันซิปไฟล์จำนวนมากที่จะลดจำนวน inode ที่ใช้ไป


4
ต้องการให้คุณ 50 คะแนนสำหรับคำถามนี้ ฉันจะทำอย่างไร! :)
โซฟี

@ โซฟีอย่าทำอย่างนั้น คุณจะถูกแบนอัตโนมัติ
Steven Lu

1
@StevenLu ขอบคุณสำหรับข้อมูลของคุณ! ฉันต้องการให้เครดิตกับเขาเพราะฉันใช้เวลาสองสามวันเพื่อแก้ไขปัญหาของฉัน แต่ปัญหานี้สามารถช่วยฉันได้ ขอบคุณอีกครั้ง
โซฟี

1
@ โซฟี: ทำไมจึงต้องมอบรางวัลนอกสถานที่ให้กับ SO? :) นั่นไม่ใช่คำถามการเขียนโปรแกรมแน่นอนไม่ว่าจะมีจำนวนผู้อัปโหลดเท่าใดก็ตาม
ทิงค์

ไดเรกทอรีว่างยังใช้ inodes การลบออกสามารถเพิ่ม inodes ได้ จำนวนอาจมีความสำคัญในบางกรณีการใช้งาน คุณสามารถลบไดเรกทอรีว่างด้วย: ค้นหา -type d -empty -delete
Ruchit Patel

คำตอบ:


170

มันค่อนข้างง่ายสำหรับดิสก์ที่มี inode จำนวนมากที่ใช้แม้ว่าดิสก์จะไม่เต็มมาก

inode จะถูกจัดสรรไปยังไฟล์ดังนั้นหากคุณมี gazillions ของไฟล์ทั้งหมด 1 ไบต์ละคุณจะหมด inode นานก่อนที่คุณจะหมดดิสก์

อาจเป็นไปได้ว่าการลบไฟล์จะไม่ลดจำนวนไอโหนดหากไฟล์นั้นมีฮาร์ดลิงค์หลายลิงค์ อย่างที่บอกไปว่า inodes เป็นของไฟล์ไม่ใช่รายการไดเร็กตอรี่ หากไฟล์มีรายการไดเรกทอรีสองรายการเชื่อมโยงอยู่การลบหนึ่งรายการจะไม่ทำให้ inode ว่าง

นอกจากนี้คุณสามารถลบรายการไดเรกทอรีได้ แต่หากกระบวนการที่กำลังรันยังเปิดไฟล์อยู่ inode จะไม่ถูกทำให้เป็นอิสระ

คำแนะนำเริ่มต้นของฉันคือการลบไฟล์ทั้งหมดที่คุณสามารถทำได้จากนั้นรีบูทกล่องเพื่อให้แน่ใจว่าไม่มีกระบวนการใดถูกเปิดค้างไว้เปิดไฟล์

หากคุณทำเช่นนั้นและคุณยังคงมีปัญหาแจ้งให้เราทราบ

อย่างไรก็ตามหากคุณกำลังมองหาไดเรกทอรีที่มีไฟล์จำนวนมากสคริปต์นี้อาจช่วย:

#!/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_$$

12
แน่นอนว่า>/tmp/count_em_$$จะใช้ได้ก็ต่อเมื่อคุณมีที่ว่างสำหรับมัน ... หากเป็นกรณีนี้ให้ดูที่ @ simon ของคำตอบ
alxndr

1
@alxndr นั่นเป็นเหตุผลที่มักจะเป็นความคิดที่ดีที่จะทำให้ระบบไฟล์ของคุณแยกจากกัน - วิธีนี้การเติมบางอย่างเช่น/tmpจะไม่มีผลกับระบบไฟล์อื่นของคุณ
paxdiablo

คำตอบของคุณเหมาะสมอย่างยิ่งสำหรับ "ระบบจะไม่ยังคงใช้ไฟล์หลังจากรีบูตหากถูกลบ" แต่คำถามที่ถามคือ "วิธีการเรียกคืนหรือนำไอโหนดกลับมาใช้ใหม่หลังจากลบตัวชี้ไอโหนด" โดยทั่วไปเคอร์เนล linux จะสร้าง inode ใหม่ให้กับไฟล์เมื่อใดก็ตามที่สร้างขึ้นและจะไม่เรียกคืน inode โดยอัตโนมัติเมื่อใดก็ตามที่คุณลบไฟล์
Mohanraj

1
@AshishKarpe ฉันคิดว่าคุณกำลังพูดถึงสถานการณ์ของคุณเองเนื่องจาก OP ไม่ได้กล่าวถึงเซิร์ฟเวอร์ที่ใช้งานจริง หากคุณไม่สามารถรีบูทได้โดยไม่ตั้งใจ ครั้งแรกหวังว่ากระบวนการในการบินในที่สุดก็ปิดไฟล์ปัจจุบันเพื่อให้ทรัพยากรดิสก์สามารถเป็นอิสระ ประการที่สองแม้แต่เซิร์ฟเวอร์ที่ใช้งานจริงควรมีขอบเขตสำหรับการรีบูตในบางช่วงเวลาเพียงกำหนดเวลาการหยุดทำงานตามแผนหรือรอหน้าต่างถัดไปของการหยุดทำงาน
paxdiablo

2
ฉันคิดว่าคุณต้องการแทนls -A ls -aทำไมคุณต้องการนับ และ ..
jarno

205

หากคุณโชคร้ายมากคุณใช้ไอโหนดทั้งหมดประมาณ 100% และไม่สามารถสร้างสแครปได้ df -ihคุณสามารถตรวจสอบเรื่องนี้ด้วย

จากนั้นคำสั่ง bash นี้อาจช่วยคุณได้:

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

และใช่ต้องใช้เวลา แต่คุณสามารถค้นหาไดเรกทอรีด้วยไฟล์ส่วนใหญ่


8
นั่นเป็นการหลอกลวง ปัญหาของฉันคือการมีเซสชันจำนวนมากในไดเรกทอรี / lib / php / times บางทีใครบางคนมีปัญหาเดียวกัน
SteMa

2
ใครบางคนควรเขียน find, cut, uniq นี้ให้เรียงเป็นคำสั่ง awk เดียว!
mogsie

5
@alxndr awkสามารถเก็บแฮชของไดเรกทอรีและจำนวนไฟล์โดยไม่ต้อง uniqing และเรียงลำดับบรรทัด gazillion ที่กล่าวว่าบางทีนี่คือการปรับปรุง: find . -maxdepth 1 -type d | grep -v '^\.$' | xargs -n 1 -i{} find {} -xdev -type f | cut -d "/" -f 2 | uniq -c | sort -n- นี่เรียงลำดับรายการสุดท้ายเท่านั้น
mogsie

12
หากคุณไม่สามารถสร้างไฟล์ใด ๆ ได้แม้จะล้มเหลวเพราะsortอาจไม่สามารถเก็บทุกอย่างไว้ในหน่วยความจำและจะพยายามถอยกลับไปเขียนไฟล์ชั่วคราวโดยอัตโนมัติ กระบวนการที่ล้มเหลวอย่างเห็นได้ชัด ...
มิกโกแรนทาเลนเฮน

10
sortล้มเหลวสำหรับฉัน แต่ฉันสามารถให้--buffer-size=10Gซึ่งทำงานได้
Frederick Nord

69

สถานการณ์ของฉันคือว่าฉันออกจาก inodes และฉันได้ลบไปแล้วเกี่ยวกับทุกสิ่งที่ฉันสามารถทำได้

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

ฉันใช้ Ubuntu 12.04LTS และไม่สามารถลบเคอร์เนลลินุกซ์เก่าซึ่งใช้เวลาประมาณ 400,000 inodes เพราะฉลาดเสียเนื่องจากขาดแพ็คเกจ และฉันไม่สามารถติดตั้งแพ็กเกจใหม่ได้เพราะฉันไม่มี inodes ดังนั้นฉันจึงติดอยู่

ฉันลงเอยด้วยการลบเคอร์เนลลินุกซ์เก่า ๆ ออกมาด้วยมือเพื่อให้ได้อิสระประมาณ 10,000 inodes

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

นี่ก็เพียงพอแล้วที่จะให้ฉันติดตั้งแพ็คเกจที่หายไปและแก้ไข apt ของฉัน

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

แล้วเอาเมล็ดลินุกซ์ส่วนที่เหลือออกด้วยส่วนที่เหลือ

$ sudo apt-get autoremove

ตอนนี้ทุกอย่างดีขึ้นมาก

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

3
นี่เป็นวิธีที่ใกล้เคียงที่สุดกับแนวทางของฉันในสถานการณ์ที่คล้ายกัน เป็นที่น่าสังเกตว่าวิธีการที่ระมัดระวังมากขึ้นนั้นได้รับการบันทึกไว้เป็นอย่างดีที่help.ubuntu.com/community/Lubuntu/Documentation/?hl=th
beldaz

กรณีของฉันอย่างแน่นอน! แต่ต้องใช้ "sudo apt-get autoremove -f" เพื่อความก้าวหน้า
Tony Sepia

การทำเช่นนี้ปลอดภัยหรือไม่: sudo rm -rf /usr/src/linux-headers-3.2.0-2*หากฉันแน่ใจว่าฉันไม่ได้ใช้เคอร์เนลนั้น
ดาวอังคารลี

@MarsLee คุณสามารถตรวจสอบเคอร์เนลที่ทำงานอยู่ในปัจจุบันด้วย "uname -a"
Dominique Eav

โทรหา$ sudo apt-get autoremoveคนเดียวได้หลอกลวงฉัน
Morten Grum

49

ทางออกของฉัน:

ลองค้นหาว่านี่เป็นปัญหา inodes กับ:

df -ih

ลองค้นหาโฟลเดอร์รูทที่มี inode ใหญ่นับ:

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

ลองค้นหาโฟลเดอร์เฉพาะ:

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

หากนี่คือส่วนหัวของลินุกซ์ลองลบเก่าที่สุดด้วย:

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

ส่วนตัวฉันย้ายพวกเขาไปยังโฟลเดอร์ที่ติดตั้ง (เพราะสำหรับฉันคำสั่งสุดท้ายล้มเหลว) และติดตั้งล่าสุดด้วย:

sudo apt-get autoremove -f

นี่เป็นการแก้ไขปัญหาของฉัน


1
SpamAssasin-Tempในประเด็นกรณีของฉันคือ find /var/spool/MailScanner/incoming/SpamAssassin-Temp -mtime +1 -print | xargs rm -fทำงานได้ :) ขอบคุณ!
จอยสติก

4
สำหรับฉันนี่ใช้เวลาหลายชั่วโมง อย่างไรก็ตามมีวิธีแก้ไขปัญหาง่าย ๆ : เมื่อคำสั่งที่สองหยุดทำงานในไดเรกทอรีเฉพาะให้ฆ่าคำสั่งปัจจุบันและเริ่มการเปลี่ยน / * ไปยังไดเรกทอรีใด ๆ ที่มันค้างอยู่ ฉันสามารถที่จะเจาะลึกผู้ร้าย <นาที
Michael Terry

ฉันใช้ตัวแปรคำสั่งของคุณเพื่อพิมพ์ตัวเลขในบรรทัดเดียวกัน: 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 -10อวดไดเรกทอรีที่ใหญ่ที่สุด 10 อันดับแรก
Mark Simon

12

ฉันมีปัญหาเดียวกันแก้ไขได้โดยลบเซสชันไดเรกทอรีของ php

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

อาจอยู่ภายใต้/var/lib/php5หากคุณใช้ php เวอร์ชั่นเก่ากว่า

สร้างมันใหม่ด้วยการอนุญาตต่อไปนี้

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

การอนุญาตโดยค่าเริ่มต้นสำหรับไดเรกทอรีใน Debian แสดงdrwx-wx-wt(1733)


1
มีความคิดว่าทำไมสิ่งนี้เกิดขึ้น?
Sibidharan

1
@Sibidharan ในกรณีของฉันมันเป็นเพราะงาน cron PHP เพื่อล้างเซสชัน PHP เก่าไม่ทำงาน
น่ากลัว

3
rm -rf /var/lib/php/sessions/*อาจเป็นคำสั่งที่ดีกว่า - มันจะไม่ลบไดเรกทอรีเซสชันเพียงเนื้อหา ... จากนั้นคุณไม่ต้องกังวลเกี่ยวกับการสร้างมันขึ้นมาใหม่
Shadow

ฉันไม่ได้มีเซสชั่น php แต่ปัญหาเซสชันวีโอไอพีคล้ายกับสิ่งนี้ ขอบคุณสำหรับทิศทาง
Mohit

เซสชัน php ไม่ควรล้างผ่านงาน cron ตั้ง session.gc_maxlifetime ใน php.ini php.net/manual/en/…

2

เราพบสิ่งนี้ในบัญชี HostGator (ผู้ที่ จำกัด inode ในการโฮสต์ทั้งหมด) หลังจากการโจมตีด้วยสแปม มันเหลือเร็กคอร์ดคิวจำนวนมากมายใน /root/.cpanel/comet หากสิ่งนี้เกิดขึ้นและคุณพบว่าไม่มี inodes ฟรีคุณสามารถเรียกใช้ยูทิลิตี้ cpanel ผ่านเชลล์ได้:

/usr/local/cpanel/bin/purge_dead_comet_files

2

คุณสามารถใช้ RSYNC เพื่อลบไฟล์จำนวนมาก

rsync -a --delete blanktest/ test/

สร้างโฟลเดอร์ blanktest ด้วย 0 ไฟล์ในนั้นและคำสั่งจะซิงค์โฟลเดอร์ทดสอบของคุณด้วยไฟล์จำนวนมาก (ฉันลบไฟล์เกือบ 5M โดยใช้วิธีนี้)

ขอบคุณhttp://www.slashroot.in/which-is-the-fastest-method-to-delete-files-in-linux


จากสิ่งที่ฉันสามารถบอกได้จากบทความ / ความคิดเห็นสิ่งนี้เร็วกว่าrm *ไฟล์จำนวนมากเนื่องจากการขยายตัวสัญลักษณ์และการส่งผ่าน / ประมวลผลแต่ละอาร์กิวเมนต์ แต่rm test/ก็ดีสำหรับการลบtest/โฟลเดอร์ที่มีไฟล์จำนวนมาก
mwfearnley

ใช้งานได้ดี แต่ให้แน่ใจว่าคุณตั้งค่าการอนุญาตอย่างถูกต้องในไดเรกทอรีว่าง! ฉันไม่ได้ทำเช่นนี้และเปลี่ยนสิทธิ์ในไดเรกทอรีเซสชัน PHP ของฉันโดยไม่ได้ตั้งใจ ใช้เวลาสองชั่วโมงเพื่อหาว่าฉันทำอะไรผิดพลาด
เฉลี่ย

1

eaccelerator อาจทำให้เกิดปัญหาเนื่องจากรวบรวม PHP เป็นบล็อก ... ฉันเคยพบปัญหานี้กับเซิร์ฟเวอร์ Amazon AWS บนไซต์ที่มีภาระจำนวนมาก เพิ่ม Inodes ให้ว่างโดยลบแคช eaccelerator ใน / var / cache / eaccelerator หากคุณยังคงมีปัญหา

rm -rf /var/cache/eaccelerator/*

(หรือแคชแคชของคุณ)


1

เราเผชิญกับปัญหาที่คล้ายกันเมื่อเร็ว ๆ นี้ในกรณีที่กระบวนการอ้างถึงไฟล์ที่ถูกลบ Inode จะไม่ถูกปล่อยดังนั้นคุณต้องตรวจสอบ lsof /, และ kill / restart กระบวนการนั้นจะปล่อย inodes

แก้ไขฉันหากผิดที่นี่


1

ดังที่ได้กล่าวไว้ก่อนหน้านี้ระบบไฟล์อาจหมด inodes หากมีไฟล์ขนาดเล็กจำนวนมาก ผมได้ให้วิธีการบางอย่างเพื่อหาไดเรกทอรีที่มีไฟล์ส่วนใหญ่ที่นี่


0

ตอบล่าช้า: ในกรณีของฉันมันเป็นไฟล์เซสชันของฉันภายใต้

/var/lib/php/sessions

ที่ใช้ Inodes
ฉันยังไม่สามารถเปิด crontab ของฉันหรือสร้างไดเรกทอรีใหม่ได้เพียงอย่างเดียวทำให้เกิดการลบ เนื่องจากฉันใช้ PHP เรามีคู่มือนี้ที่ฉันคัดลอกรหัสจากตัวอย่างที่ 1 และตั้งค่า cronjob เพื่อเรียกใช้งานส่วนนั้นของรหัส

<?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();
?>

หากคุณสงสัยว่าฉันจัดการเปิด crontab ของฉันได้อย่างไรฉันลบบางเซสชันด้วยตนเองผ่าน CLI

หวังว่านี่จะช่วยได้!



-2

หลายคำตอบสำหรับเรื่องนี้จนถึงขณะนี้และทั้งหมดข้างต้นดูเหมือนเป็นรูปธรรม ฉันคิดว่าคุณจะปลอดภัยด้วยการใช้statตามที่คุณทำ แต่ระบบปฏิบัติการขึ้นอยู่กับว่าคุณอาจได้รับข้อผิดพลาดของไอโหนดบ้าง ดังนั้นการใช้statฟังก์ชั่นการโทรของคุณเองโดยใช้64bitเพื่อหลีกเลี่ยงปัญหาการล้นใด ๆ


เรารักตัวอย่างที่นี่ในตอนนี้;)
Bohne

-3

หากคุณใช้นักเทียบท่าให้ลบภาพทั้งหมด พวกเขาใช้พื้นที่มากมาย ....

หยุดภาชนะทั้งหมด

docker stop $(docker ps -a -q)

ลบคอนเทนเนอร์ทั้งหมด

docker rm $(docker ps -a -q)

ลบภาพทั้งหมด

docker rmi $(docker images -q)

ทำงานให้ฉัน


สิ่งนี้ไม่ช่วยในการตรวจสอบว่า "inodes มากเกินไป" เป็นปัญหา
Mark Stosberg

สิ่งนี้ไม่เกี่ยวข้องกับ Docker
Urda
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.