Xác định vị trí sử dụng Inode


15

Gần đây tôi đã cài đặt Munin trên một máy chủ web phát triển để theo dõi việc sử dụng hệ thống. Tôi đã thông báo rằng việc sử dụng inode của hệ thống đang tăng khoảng 7-8% mỗi ngày mặc dù mức độ sử dụng đĩa hầu như không tăng. Tôi đoán một cái gì đó đang viết rất nhiều tập tin nhỏ nhưng tôi không thể tìm thấy cái gì / ở đâu.

Tôi biết cách tìm cách sử dụng dung lượng ổ đĩa nhưng dường như tôi không thể tìm ra cách tóm tắt việc sử dụng inode.

Có cách nào tốt để xác định việc sử dụng inode theo thư mục để tôi có thể xác định vị trí nguồn sử dụng không?

Câu trả lời:


15

Đừng mong đợi điều này sẽ chạy nhanh ...

cd vào một thư mục mà bạn nghi ngờ có thể có một thư mục con có rất nhiều nút. Nếu tập lệnh này mất một lượng lớn thời gian, bạn có thể tìm thấy vị trí trong hệ thống tập tin. / var là một khởi đầu tốt ...

Mặt khác, nếu bạn thay đổi thư mục trên cùng trong hệ thống tập tin đó và chạy nó và đợi nó kết thúc, bạn sẽ tìm thấy thư mục có tất cả các nút.

find . -type d | 
while 
  read line  
do 
  echo "$( find "$line" -maxdepth 1 | wc -l) $line"  
done | 
sort -rn | less

Tôi không lo lắng về chi phí phân loại. Tôi đã chạy thử nghiệm và sắp xếp thông qua đầu ra chưa được sắp xếp của nó với 350.000 thư mục mất 8 giây. Các tìm thấy ban đầu mất. Chi phí thực sự đang mở tất cả các thư mục này trong vòng lặp while. (vòng lặp mất 22 giây). (Dữ liệu thử nghiệm được chạy trên thư mục con với 350.000 thư mục, một trong số đó có một triệu tệp, phần còn lại có từ 1 đến 15 thư mục).

Nhiều người đã chỉ ra rằng ls không tuyệt vời ở chỗ đó vì nó sắp xếp đầu ra. Tôi đã thử echo, nhưng điều đó cũng không tuyệt vời. Một số người khác đã chỉ ra rằng stat cung cấp thông tin này (số lượng mục nhập thư mục) nhưng nó không khả dụng. Hóa ra find -maxdepth thực sự rất nhanh trong việc mở thư mục và đếm .files, vì vậy ... đây là .. điểm cho tất cả mọi người!


2
@mike G: Bạn đúng 100% về việc này không phải là cách nhanh nhất để làm việc này. Trong tâm trí của tôi, cách chính xác để tối ưu hóa điều này là chuyển hướng đến stderr khi bắt đầu và hoàn thành phần "mục nhập thư mục" của tập lệnh. Theo cách đó, khi bạn nhấn một thư mục có một triệu mục, nó sẽ nói "xử lý thư mục spool / postfix / maildrop" và sau đó không nói ngay là "kết thúc" và bùng nổ - hãy nhìn vào spool / postfix / maildrop và bạn sẽ thấy rất nhiều các tập tin.
chris

Tôi cũng không lo lắng về chi phí sắp xếp vì đây là nhiệm vụ một lần hoặc ít nhất là không thường xuyên.
Dave Forgac

7

Nếu vấn đề là một thư mục có quá nhiều tệp, thì đây là một giải pháp đơn giản:

# Let's find which partition is out of inodes:
$ df -hi
Filesystem            Inodes   IUsed   IFree IUse% Mounted on
/dev/sda3               2.4M    2.4M       0  100% /
...

# Okay, now we know the mount point with no free inodes,
# let's find a directory with too many files:
$ find / -xdev -size +100k -type d

Ý tưởng đằng sau finddòng này là kích thước của một thư mục tỷ lệ thuận với số lượng tệp trực tiếp bên trong thư mục đó. Vì vậy, ở đây chúng tôi tìm kiếm các thư mục với hàng tấn các tập tin bên trong nó.

Nếu bạn không muốn đoán một số và thích liệt kê tất cả các thư mục nghi ngờ được sắp xếp theo "kích thước", điều đó cũng dễ dàng:

# Remove the "sort" command if you want incremental output
find / -xdev -size +10k -type d -printf '%s %p\n' | sort -n

6

Grrr, bình luận cần 50 rep. Vì vậy, câu trả lời này thực sự là một nhận xét về câu trả lời của chris.

Vì người hỏi có thể không quan tâm đến tất cả các thư mục, chỉ những thư mục tồi nhất, nên việc sử dụng sắp xếp có thể rất tốn kém.

find . -type d | 
while 
  read line  
do 
  echo "$(ls "$line" | wc -l) $line"  
done | 
perl -a -ne'next unless $F[0]>=$max; print; $max=$F[0]'  | less

Phiên bản này không hoàn chỉnh như phiên bản của bạn, nhưng đây là dòng in nếu chúng lớn hơn mức tối đa trước đó, giúp giảm đáng kể lượng nhiễu được in ra và tiết kiệm chi phí sắp xếp.

Nhược điểm của việc này là nếu bạn có 2 thư mục rất lớn và lần đầu tiên xảy ra có thêm 1 nút inode so với thứ 2, bạn sẽ không bao giờ thấy thư mục thứ 2.

Một giải pháp hoàn chỉnh hơn sẽ là viết một tập lệnh perl thông minh hơn để theo dõi 10 giá trị hàng đầu được nhìn thấy và in chúng ra ở cuối. Nhưng đó là quá dài cho một câu trả lời máy chủ nhanh chóng.

Ngoài ra, một số tập lệnh perl thông minh hơn giữa chừng sẽ cho phép bạn bỏ qua vòng lặp while - trên hầu hết các nền tảng, chúng tôi sắp xếp kết quả và điều đó cũng có thể rất tốn kém cho các thư mục lớn. Sắp xếp ls là không cần thiết ở đây, vì tất cả những gì chúng ta quan tâm là số lượng.


1
Đúng về ls - trong những tình huống như thế này tôi lo lắng nhiều hơn về việc rõ ràng những gì tôi đang làm và không quá nhiều về hiệu suất. Tôi khá chắc chắn rằng bạn có thể sử dụng echo $ line / * | wc -w thay cho ls $ line | wc -l và bạn tránh được vấn đề sắp xếp ls.
chris

Tôi vừa chạy thử nghiệm trên một thư mục có một triệu tệp và ls mất 22 giây và tiếng vang * mất 12 giây. (Đối với bản ghi, echo * in shell sẽ không đạt giới hạn arg vì echo trong 99% shell đang sử dụng là tích hợp)
chris

ls -f sẽ không sắp xếp kết quả. Sắp xếp kết quả thư mục dẫn đến một vấn đề phổ biến với NFS và các thư mục lớn. Nếu thời gian để đọc và sắp xếp thư mục (trên máy chủ) vượt quá thời gian chờ NFS, thư mục và thư mục con không thể sử dụng được.
mpez0

5

Bạn có thể sử dụng đoạn trích nhỏ này:

find | cut -d/ -f2 | uniq -c | sort -n

Nó sẽ in ra có bao nhiêu tệp và thư mục trong mỗi thư mục trong thư mục hiện tại, với những người phạm tội lớn nhất ở phía dưới. Nó sẽ giúp bạn tìm các thư mục có nhiều tệp. ( thêm thông tin )


Điều này làm việc rực rỡ.
ptman

3

Đây không phải là câu trả lời trực tiếp cho câu hỏi của bạn, nhưng việc tìm kiếm các tệp được sửa đổi gần đây với kích thước nhỏ bằng cách sử dụng find có thể thu hẹp tìm kiếm của bạn:

find / -mmin -10 -size -20k

3
find /path ! -type d | sed 's,/[^/]*$,,' | uniq -c | sort -rn

Tôi sẽ không tìm thấy các tập tin có tên bắt đầu bằng một dấu chấm. Sử dụng find tránh điều này. Điều này tìm thấy mọi tệp trong cây thư mục, bỏ tên cơ sở từ cuối mỗi đường dẫn và đếm số lần mỗi đường dẫn thư mục xuất hiện trong kết quả đầu ra. Bạn có thể phải đặt dấu "!" trong dấu ngoặc kép nếu vỏ của bạn phàn nàn về nó.

Các nút cũng có thể được sử dụng hết bởi các tệp đã bị xóa nhưng đang được giữ bởi một quy trình đang chạy. Nếu gói Munin này bao gồm bất kỳ chương trình chạy liên tục nào, một điều cần kiểm tra là liệu nó có mở một số lượng tệp bất thường hay không.


Các nút cũng có thể được thực hiện bởi các thư mục thực sự sâu, điều này sẽ không tìm thấy. Có một số trường hợp cạnh kỳ lạ trong trường hợp này, nhưng tình huống phổ biến nhất là một thư mục chứa đầy các tệp có tên bình thường.
chris

3

Tôi sẽ buộc thứ này: chạy tripwire trên toàn bộ thiết bị cho đường cơ sở, sau đó chạy kiểm tra một thời gian sau đó và thư mục vi phạm sẽ dính ra như ngón tay cái đau.


Điều đó có thể sẽ mất một tỷ năm. Một cách nhanh hơn để làm là chạy lsof | grep DIR và tìm trong mỗi thư mục đó để tìm nhiều tệp mới.
chris

2
Ok, làm thế nào về điều này: tìm / | sắp xếp> /tmp/find1.txt; tìm / | sắp xếp> /tmp/find2.txt; diff /tmp/find1.txt /tmp/find2.txt
Geoff Fritz

2

(không thể nhận xét là thực sự già đi - đây là cho egorgry)

egorgry - ls -i in SỐ inode cho một mục nhập, không phải là inode COUNT.

Hãy thử nó với một tệp trong thư mục của bạn - bạn (có thể) sẽ thấy một số lượng cao tương đương, nhưng đó không phải là số lượng các nút, nó chỉ là inode # mục nhập thư mục của bạn.


cười lớn. Tôi đã bình chọn cho bạn một. Cảm ơn đã giải thích. sử dụng inode luôn luôn gây nhầm lẫn.
egorgry

cảm ơn Bây giờ tôi sợ chuyển đổi nhận xét này thành nhận xét về nút của bạn, trong trường hợp tôi mất nghiệp khi xóa câu trả lời này :)
Mike G.

2

Cập nhật

Một lớp lót trả về số lượng inode của mỗi con của thư mục đã cho với các mục lớn nhất ở dưới cùng.

find . -mindepth 1 -printf "%p/%i\n" \
  | awk -F/ '{print $2"/"$NF}' | sort -u \
  | cut -d/ -f1 | uniq -c | sort -n

Câu trả lời gốc

#!/bin/bash
# Show inode distribution for given directory

dirs=$(find $1 -mindepth 1 -maxdepth 1 -type d)

for dir in $dirs
do
    inode_count=$(find $dir -printf "%i\n" 2> /dev/null | sort -u | wc -l)
    echo "$inode_count $dir"
done

Chạy nó như thế này (với điều kiện là đoạn script trên nằm trong tệp thực thi trong thư mục làm việc của bạn)

./indist / | sort -n

1

sử dụng inode là khoảng một cho mỗi tập tin hoặc thư mục, phải không? Vậy làm

find [path] -print | wc -l

để đếm khoảng bao nhiêu nút được sử dụng trong [đường dẫn].


1

Tôi đã cố gắng viết một đường ống vỏ hiệu quả, nhưng nó trở nên khó sử dụng và chậm hoặc không chính xác, ví dụ,

find . -depth -printf '%h\n' | uniq -c | awk '$1>1000'

sẽ liệt kê các thư mục lá (và một số thư mục khác) với hơn 1000 tệp trong đó. Vì vậy, đây là tập lệnh Perl để thực hiện nó hiệu quả cả về thời gian và RAM. Đầu ra giống như

«Files-in-Subree» «files-direct-in-thư mục» «tên thư mục»

vì vậy bạn có thể xoa bóp và lọc nó một cách dễ dàng bằng các công cụ bình thường, ví dụ: sort (1) hoặc awk (1) như trên.

#! /usr/bin/perl -w
# Written by Kjetil Torgrim Homme <kjetil.homme@redpill-linpro.com>

use strict;
use File::Find;

my %counted;
my %total;

sub count {
    ++$counted{$File::Find::dir};
}

sub exeunt {
    my $dir = $File::Find::dir;

    # Don't report leaf directories with no files
    return unless $counted{$dir}; 

    my $parent = $dir;
    $parent =~ s!/[^/]*$!!;

    $total{$dir} += $counted{$dir};
    $total{$parent} += $total{$dir} if $parent ne $dir;
    printf("%8d %8d %s\n", $total{$dir}, $counted{$dir}, $dir);
    delete $counted{$dir};
    delete $total{$dir};
}

die "Usage: $0 [DIRECTORY...]\n" if (@ARGV && $ARGV[0] =~ /^-/);
push(@ARGV, ".") unless @ARGV;

finddepth({ wanted => \&count, postprocess => \&exeunt}, @ARGV);

-1
[gregm@zorak2 /]$ ls -i /home
131191 gregm

nhà của tôi trên máy tính xách tay của tôi đang sử dụng 131191 inodes.


3
ls -i in SỐ inode cho một mục nhập, không phải là inode COUNT. Hãy thử nó với một tệp trong thư mục của bạn - bạn (có thể) sẽ thấy một số lượng cao tương đương, nhưng đó không phải là số lượng các nút, nó chỉ là inode # mục nhập thư mục của bạn.
egorgry
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.