ค้นหาว่ามีการใช้ไอโหนดใด


189

ดังนั้นฉันจึงได้รับคำเตือนจากระบบตรวจสอบของเราบนกล่องใดกล่องหนึ่งของเราที่จำนวนของ inodes ฟรีในระบบไฟล์มีน้อย

df -i เอาท์พุทแสดงสิ่งนี้:

Filesystem       Inodes  IUsed    IFree IUse% Mounted on
/dev/xvda1       524288 422613   101675   81% /

อย่างที่คุณเห็นพาร์ติชั่นรูทนั้นใช้ไอโหนด 81%
ฉันสงสัยว่ามันถูกใช้งานทั้งหมดในไดเรกทอรีเดียว แต่ฉันจะหาที่ที่อยู่ได้อย่างไร

คำตอบ:


214

ฉันเห็นคำถามนี้ใน stackoverflow แต่ฉันไม่ชอบคำตอบใด ๆ และเป็นคำถามที่ควรจะอยู่ที่นี่ใน U&L

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

ในกรณีนี้ระบบไฟล์ที่เราใส่ใจคือระบบไฟล์รู/ทดังนั้นเราสามารถใช้คำสั่งต่อไปนี้:

find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n

สิ่งนี้จะดัมพ์รายการของทุกไดเร็กทอรีบนระบบไฟล์ที่นำหน้าด้วยจำนวนไฟล์ (และไดเร็กทอรีย่อย) ในไดเร็กทอรีนั้น ดังนั้นไดเรกทอรีที่มีไฟล์มากที่สุดจะอยู่ด้านล่าง

ในกรณีของฉันสิ่งนี้จะปรากฏขึ้นดังต่อไปนี้:

   1202 /usr/share/man/man1
   2714 /usr/share/man/man3
   2826 /var/lib/dpkg/info
 306588 /var/spool/postfix/maildrop

ดังนั้นโดยทั่วไป/var/spool/postfix/maildropจะใช้ inodes ทั้งหมด

หมายเหตุคำตอบนี้มีคำเตือนสามข้อที่ฉันนึกได้ มันไม่สามารถจัดการกับสิ่งที่ขึ้นบรรทัดใหม่ในเส้นทางได้อย่างถูกต้อง ฉันรู้ว่าระบบแฟ้มของฉันมีไฟล์ที่มีการขึ้นบรรทัดใหม่ไม่มีและตั้งแต่นี้เป็นเพียงการใช้สำหรับการบริโภคของมนุษย์ปัญหาที่อาจเกิดขึ้นจะไม่คุ้มค่าการแก้ (และหนึ่งมักจะสามารถแทนที่\nด้วย\0และใช้sort -zด้านบน) นอกจากนี้ยังไม่จัดการหากไฟล์ถูกกระจายออกไปในไดเรกทอรีจำนวนมาก ไม่น่าเป็นไปได้ดังนั้นฉันจึงพิจารณาความเสี่ยงที่ยอมรับได้ มันจะนับฮาร์ดลิงก์ไปยังไฟล์เดียวกัน (ดังนั้นใช้เพียงไอโหนดเดียว) หลายครั้ง อีกครั้งไม่น่าจะให้ผลบวกปลอม


เหตุผลสำคัญที่ฉันไม่ชอบคำตอบใด ๆ ในคำตอบของ stackoverflow ก็คือพวกเขาข้ามขอบเขตระบบไฟล์ทั้งหมด เนื่องจากปัญหาของฉันอยู่ที่ระบบไฟล์รูทหมายความว่ามันจะข้ามทุกระบบไฟล์ที่เมาท์เดียว การโยน-xdevคำสั่ง find ไม่ทำงานอย่างถูกต้อง
ตัวอย่างเช่นคำตอบที่โหวตสูงสุดคือคำตอบนี้:

for i in `find . -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n

หากเราเปลี่ยนสิ่งนี้เป็น

for i in `find . -xdev -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n

แม้ว่า/mnt/fooมันจะเป็น mount มันก็เป็นไดเร็กตอรี่บน root filesystem, ดังนั้นมันจะเปิดขึ้นมาfind . -mount -type d, แล้วมันจะถูกส่งผ่านไปยังls -a $i, ซึ่งจะดำดิ่งลงไปใน mount.

findในคำตอบของฉันแทนแสดงรายการไดเรกทอรีของไฟล์เดียวทุกบนภูเขา ดังนั้นโดยพื้นฐานแล้วมีโครงสร้างไฟล์เช่น:

/foo/bar
/foo/baz
/pop/tart

เราจบลงด้วย

/foo
/foo
/pop

ดังนั้นเราต้องนับจำนวนบรรทัดที่ซ้ำกัน


2
@MohsenPahlevanzadeh ที่ไม่ได้เป็นส่วนหนึ่งของคำตอบของฉันฉันแสดงความคิดเห็นเกี่ยวกับสาเหตุที่ฉันไม่ชอบวิธีแก้ปัญหาเนื่องจากเป็นคำตอบทั่วไปสำหรับคำถามนี้
Patrick

7
การใช้ bind mount เป็นวิธีที่มีประสิทธิภาพมากขึ้นในการหลีกเลี่ยงการค้นหาระบบไฟล์อื่น ๆ เนื่องจากจะช่วยให้สามารถเข้าถึงไฟล์ภายใต้จุดเชื่อมต่อได้ เช่นฉันจะสร้างจินตนาการ 300,000 ไฟล์ภายใต้/tmpและต่อมาระบบการกำหนดค่าการติด tmpfs /tmpบน จากนั้นคุณจะไม่สามารถค้นหาไฟล์ด้วยตนเองfindเพียงอย่างเดียว Senario ไม่น่า แต่น่าสังเกต
แกรม

2
งานทั้งสองต้องลบการเรียงลำดับเนื่องจากการเรียงลำดับจำเป็นต้องสร้างไฟล์เมื่อเอาต์พุตมีขนาดใหญ่พอซึ่งเป็นไปไม่ได้ตั้งแต่ฉันใช้งาน inodes ถึง 100%
qwertzguy

1
โปรดทราบว่า-printfดูเหมือนว่าจะเป็นส่วนขยาย GNU เพื่อค้นหาเนื่องจากรุ่น BSD ที่มีอยู่ใน OS X ไม่รองรับ
Xiong Chiamiov

1
ข้อสันนิษฐานว่าไฟล์ทั้งหมดอยู่ในไดเรกทอรีเดียวเป็นไฟล์ที่ยาก โปรแกรมจำนวนมากรู้ว่าไฟล์จำนวนมากในไดเรกทอรีเดียวมีประสิทธิภาพที่ไม่ดีและทำให้แฮชหนึ่งหรือสองระดับของไดเรกทอรี
PlasmaHH

26

นี่คือ reposted จากที่นี่ตามคำสั่งของผู้ถาม:

du --inodes -S | sort -rh | sed -n \
        '1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'

และถ้าคุณต้องการอยู่ในระบบไฟล์เดียวกับคุณ:

du --inodes -xS

นี่คือตัวอย่างผลลัพธ์:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
...
519     /usr/lib/python2.7/site-packages/bzrlib
516     /usr/include/KDE
498     /usr/include/qt/QtCore
487     /usr/lib/modules/3.13.6-2-MANJARO/build/include/config
484     /usr/src/linux-3.12.14-2-MANJARO/include/config

ตอนนี้ด้วย LS:

มีหลายคนที่กล่าวถึงว่าพวกเขาไม่มี coreutils ที่ทันสมัยและตัวเลือก --inode ไม่สามารถใช้ได้ ดังนั้นนี่คือ ls:

ls ~/test -AiR1U | 
sed -rn '/^[./]/{h;n;};G;
    s|^ *([0-9][0-9]*)[^0-9][^/]*([~./].*):|\1:\2|p' | 
sort -t : -uk1.1,1n |
cut -d: -f2 | sort -V |
uniq -c |sort -rn | head -n10

หากคุณอยากรู้อยากเห็นหัวใจที่น่าเบื่อของสิ่งนั้นน่าเบื่อหน่ายregexแทนที่filenameในls'sผลลัพธ์การค้นหาแบบเรียกซ้ำด้วยชื่อไดเรกทอรีที่พบ จากนั้นเป็นเพียงเรื่องของการบีบหมายเลขไอโหนดซ้ำแล้วนับชื่อไดเรกทอรีซ้ำและเรียงลำดับตาม

-Uตัวเลือกที่เป็นประโยชน์อย่างยิ่งกับการเรียงลำดับในการที่จะมาโดยเฉพาะไม่ได้เรียงลำดับและแทนที่จะแสดงรายการไดเรกทอรีในการสั่งซื้อเดิม - หรือในคำอื่น ๆ โดยinodeจำนวน

และแน่นอนว่า-1มีประโยชน์อย่างไม่น่าเชื่อในการช่วยให้มั่นใจผลเดียวต่อบรรทัดโดยไม่คำนึงถึงอาจรวมถึงการขึ้นบรรทัดใหม่ในชื่อไฟล์หรือปัญหาที่โชคร้ายอื่น ๆ ที่อาจเกิดขึ้นเมื่อคุณพยายามที่จะแยกรายการ

และแน่นอน-Aสำหรับทั้งหมดและ-iinode และ-Rสำหรับการเรียกซ้ำและนั่นคือความยาวและระยะสั้นของมัน

วิธีการพื้นฐานของสิ่งนี้คือฉันแทนที่ทุกชื่อไฟล์ของ ls ด้วยชื่อไดเรกทอรีที่มีอยู่ใน sed ต่อจากนั้น ... เอาละฉันเองก็ฝืดนิดหน่อย ฉันค่อนข้างแน่ใจว่ามันนับไฟล์อย่างถูกต้องอย่างที่คุณเห็นที่นี่:

% _ls_i ~/test
> 100 /home/mikeserv/test/realdir
>   2 /home/mikeserv/test
>   1 /home/mikeserv/test/linkdir

นี่คือการให้ผลลัพธ์ที่เหมือนกันกับduคำสั่ง:

DU:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
1.9K    /usr/share/fonts/100dpi
1.9K    /usr/share/doc/arch-wiki-markdown
1.6K    /usr/share/fonts/TTF
1.6K    /usr/share/dolphin-emu/sys/GameSettings
1.6K    /usr/share/doc/efl/html

LS:

14686   /usr/share/man/man3:
4322    /usr/lib:
3653    /usr/bin:
2457    /usr/share/man/man1:
1897    /usr/share/fonts/100dpi:
1897    /usr/share/fonts/75dpi:
1890    /usr/share/doc/arch-wiki-markdown:
1613    /usr/include:
1575    /usr/share/doc/efl/html:
1556    /usr/share/dolphin-emu/sys/GameSettings:

ฉันคิดว่าincludeสิ่งที่ขึ้นอยู่กับไดเรกทอรีที่โปรแกรมดูครั้งแรก - เพราะพวกเขาเป็นไฟล์เดียวกันและฮาร์ดลิงก์ ค่อนข้างชอบสิ่งเหนือ ฉันอาจจะผิดเกี่ยวกับเรื่องนั้น - และฉันยินดีต้อนรับการแก้ไข ...

DU DEMO

% du --version
> du (GNU coreutils) 8.22

ทำไดเรกทอรีทดสอบ:

% mkdir ~/test ; cd ~/test
% du --inodes -S
> 1       .

บางไดเรกทอรีลูก:

% mkdir ./realdir ./linkdir
% du --inodes -S
> 1       ./realdir
> 1       ./linkdir
> 1       .

สร้างไฟล์บางไฟล์:

% printf 'touch ./realdir/file%s\n' `seq 1 100` | . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

บางส่วนของการเชื่อมโยง:

% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' `seq 1 100` | 
    . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

ดูการเชื่อมโยง:

% cd ./linkdir
% du --inodes -S
> 101

% cd ../realdir
% du --inodes -S
> 101

พวกเขาถูกนับคนเดียว แต่ไปหนึ่งไดเรกทอรีขึ้นไป ...

% cd ..
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

จากนั้นฉันก็เรียกใช้สคริปต์การวิ่งของฉันจากด้านล่างและ:

> 100     /home/mikeserv/test/realdir
> 100     /home/mikeserv/test/linkdir
> 2       /home/mikeserv/test

และแกรม:

> 101 ./realdir
> 101 ./linkdir
> 3 ./

ดังนั้นฉันคิดว่านี่แสดงให้เห็นว่าวิธีเดียวที่จะนับ inodes คือโดย inode และเนื่องจากการนับไฟล์หมายถึงการนับไอโหนดคุณจึงไม่สามารถนับไอโหนดได้สองเท่า - การนับไฟล์อย่างแม่นยำไอโหนดจึงไม่สามารถนับได้มากกว่าหนึ่งครั้ง


2
เพิ่มรุ่น--inodesไหน? "หลากหลาย" / "รสชาติ" / "posix-wannabes" / "implementations" ใด / มีอะไรบ้าง
n611x007

Ubuntu 14.04.5: du: ตัวเลือกที่ไม่รู้จัก '--inodes'
Putnik

du (GNU coreutils) 8.23 ​​จาก 2014 มี (มันอยู่ใน Debian Jessie ที่ล้าสมัยของฉัน) Debian> Ubuntu ขอโทษที่เล่นสำนวนนั่น: P Ubuntu มีแพ็คเกจเก่า ...
Daniel W.

6

ฉันใช้คำตอบนี้จาก SO Q&A เรื่อง: inodes ของฉันทั้งหมดถูกใช้ที่ไหน เมื่อ NAS ของเราหมดประมาณ 2 ปีที่แล้ว:

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n

ตัวอย่าง

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n
...
110 ./MISC/nodejs/node-v0.8.12/out/Release/obj.target/v8_base/deps/v8/src
120 ./MISC/nodejs/node-v0.8.12/doc/api
123 ./apps_archive/monitoring/nagios/nagios-check_sip-1.3/usr/lib64/nagios
208 ./MISC/nodejs/node-v0.8.12/deps/openssl/openssl/doc/crypto
328 ./MISC/nodejs/node-v0.8.12/deps/v8/src
453 ./MISC/nodejs/node-v0.8.12/test/simple

ตรวจสอบ Inodes ของอุปกรณ์

ทั้งนี้ขึ้นอยู่กับ NAS ของคุณอาจไม่มีdfคำสั่งที่มีคุณสมบัติครบถ้วน ดังนั้นในกรณีเหล่านี้คุณสามารถใช้tune2fsแทน:

$ sudo tune2fs -l /dev/sda1 |grep -i inode
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Inode count:              128016
Free inodes:              127696
Inodes per group:         2032
Inode blocks per group:   254
First inode:              11
Inode size:           128
Journal inode:            8
Journal backup:           inode blocks

การข้ามขอบเขตระบบไฟล์

คุณสามารถใช้-xdevสวิตช์เพื่อกำหนดfindให้การค้นหาแคบลงเฉพาะอุปกรณ์ที่คุณกำลังเริ่มการค้นหา

ตัวอย่าง

ว่าฉันมี/homeไดเรกทอรีของฉันโดยอัตโนมัติผ่าน NFS หุ้นจาก NAS ของฉันที่มีชื่อเป็น mulder

$ df -h /home/sam 
Filesystem            Size  Used Avail Use% Mounted on
mulder:/export/raid1/home/sam
                      917G  572G  299G  66% /home/sam

ขอให้สังเกตว่าจุดเชื่อมต่อยังคงถูกพิจารณาเป็นแบบโลคัลกับระบบ

$ df -h /home/ .
Filesystem            Size  Used Avail Use% Mounted on
-                        0     0     0   -  /home
/dev/mapper/VolGroup00-LogVol00
                      222G  159G   52G  76% /

ตอนนี้เมื่อฉันเริ่มfind:

$ find / -xdev  | grep '^/home'
/home

พบ/homeแต่ไม่มีเนื้อหาที่ถูกเมานท์เนื่องจากอยู่ในอุปกรณ์อื่น!

ประเภทระบบไฟล์

คุณสามารถใช้สลับไปfind, -fstypeเพื่อควบคุมประเภทของระบบไฟล์findจะมีลักษณะเป็น

   -fstype type
          File is on a filesystem of type type.  The valid filesystem types 
          vary among different versions of Unix; an incomplete list of 
          filesystem  types that are accepted on some version of Unix or 
          another is: ufs, 4.2, 4.3, nfs, tmp, mfs, S51K, S52K.  You can use 
          -printf with the %F directive to see the types of your
          filesystems.

ตัวอย่าง

ฉันมีระบบไฟล์อะไร

$ find . -printf "%F\n" | sort -u
ext3

ดังนั้นคุณสามารถใช้สิ่งนี้เพื่อควบคุมการข้าม:

ext3 เท่านั้น

$ find . -fstype ext3 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt

เฉพาะ nfs

$ find . -fstype nfs | head -5
$ 

ext3 & ext4

$ find . -fstype ext3 -o -fstype ext4 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt

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

@ แพทริก - ดูการปรับปรุงคุณสามารถควบคุมได้โดยใช้การ-fstype find
slm

1
@Gilles - คำตอบง่าย ๆ ... ไม่ได้ลดหน้าลงในหน้าค้นหาของ find 8-)
slm

@Gilles - หน้าคนดูเหมือนจะไม่ได้ระบุว่า-xtypeไม่รวมระบบไฟล์ดูเหมือนว่าจะดูที่ประเภทของไฟล์ ฉันแค่ค้นหาตัวอย่างเช่นนี้:find . \( -fstype nfs -prune \)
slm

@Gilles - ฉันพูดถึง Q ของ Patrick ในความคิดเห็นเกี่ยวกับวิธีการป้องกันไม่ให้findข้ามขอบเขตของระบบไฟล์ ในอดีตของเขา เขากล่าวถึง "เหมือนว่า / คืออะไรและคุณติดตั้งระบบไฟล์เครือข่ายแล้วคุณไม่ต้องการไปดำน้ำในระบบไฟล์เครือข่าย"
slm


3

หากต้องการแสดงรายการการใช้ inode อย่างละเอียดให้/ใช้คำสั่งต่อไปนี้:

echo "Detailed Inode usage for: $(pwd)" ; for d in `find -maxdepth 1 -type d |cut -d\/ -f2 |grep -xv . |sort`; do c=$(find $d |wc -l) ; printf "$c\t\t- $d\n" ; done ; printf "Total: \t\t$(find $(pwd) | wc -l)\n" 

ยินดีต้อนรับ! ฉันขอแนะนำรูปแบบครั้งต่อไปดีกว่าโปรด
เตอร์

1
ฉันเป็นคนทำเองฉันไม่เห็นอะไรผิดปกติ
sjas

2

คำตอบที่แน่นอนพร้อมอัพโวลุ่มสูงสุดช่วยให้เข้าใจถึงแนวคิดของ inodes ใน linux และ unix แต่มันไม่ได้ช่วยอะไรจริง ๆ เมื่อจัดการกับปัญหาจริงของการลบหรือลบ inodes ออกจากดิสก์ วิธีที่ง่ายกว่าในการทำเช่นนี้บนระบบที่ใช้อูบุนตูคือการลบส่วนหัวเคอร์เนลและรูปภาพของ linux ที่ไม่ต้องการ

sudo apt-get autoremove

จะทำเพื่อคุณ ในกรณีของฉันการใช้งาน inodes อยู่ที่ 78% เนื่องจากฉันได้รับการแจ้งเตือน

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 407957 116331   78% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user

หลังจากรันsudo apt-get autoremoveคำสั่งมันลดลงเหลือ 29%

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 150472 373816   29% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user

นี่เป็นเพียงการสังเกตของฉันที่ช่วยประหยัดเวลาของฉัน ผู้คนอาจพบทางออกที่ดีกว่านี้


2

ฉันพบว่ารวดเร็วและง่ายกว่าในการเจาะลึกโดยใช้คำสั่งต่อไปนี้:

$ sudo du -s --inodes * | sort -rn

170202  var
157325  opt
103134  usr
53383   tmp
<snip>

จากนั้นคุณสามารถเข้าไปในvarตัวอย่างและดูว่า inode ใหญ่ที่ใช้ไดเรกทอรีอยู่ในนั้น


0

ทุกคำตอบสมมติว่าปัญหาอยู่ที่หลาย ๆ ไฟล์ในไดเรกทอรีเดียวแทนที่จะเป็นไดเรกทอรีย่อยมากมายที่ทำให้เกิดปัญหา โชคดีที่วิธีแก้ปัญหาคือใช้ธงน้อยลง

# du --inodes --one-file-system /var | sort --numeric-sort
...
2265    /var/cache/salt/minion
3818    /var/lib/dpkg/info
3910    /var/lib/dpkg
4000    /var/cache/salt/master/gitfs/refs
4489    /var/lib
5709    /var/cache/salt/master/gitfs/hash
12954   /var/cache/salt/master/gitfs
225058  /var/cache/salt/master/jobs
241678  /var/cache/salt/master
243944  /var/cache/salt
244078  /var/cache
248949  /var

du --inodes -x | sort -nหรือมีตัวเลือกสั้น: น่าเสียดายที่ไม่ใช่ว่าทุกรุ่นduมีตัวเลือกไอโหนด

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