私はArch Linuxを実行しており、ext4ファイルシステムを使用しています。
ls
今は実際には小さいですが、以前は非常に大きかったディレクトリで実行するとしばらく停止します。しかし、次回実行するとほぼ瞬時に実行されます。
私はこれを試みます:
strace ls
しかし、正直なところ、出力をデバッグする方法がわかりません。 100行を超えても必要に応じて投稿できます。
そしていいえ、エイリアスを使用しません。
$ type ls
ls is hashed (/usr/bin/ls)
$ df .
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda9 209460908 60427980 138323220 31% /home
答え1
かつて、大きなディレクトリにはまだ多くのブロックがディレクトリエントリ(=ディレクトリ内のファイルとサブディレクトリの名前とinode番号)に割り当てられている可能性がありますが、そのブロックの大部分は削除されたとマークされています。
新しいディレクトリが作成されると、ディレクトリエントリに最小限のスペースしか割り当てられません。追加のファイルが追加されると、必要に応じてディレクトリエントリを保持するために新しいブロックが割り当てられます。ただし、ファイルが削除されると、ファイルext4
システムはすぐに再び必要になる可能性があると仮定して、現在必要でないディレクトリエントリと利用可能なディレクトリメタデータブロックをマージしません。
e2fsck -C0 -f -D /dev/sda9
追加のディレクトリメタデータブロックを取得し、既存のディレクトリエントリをより小さなスペースにマージするには、ファイルシステムをマウント解除し、そのシステムのディレクトリを最適化するために実行する必要があります。
これは/home
ファイルシステムなので、すべての一般ユーザーアカウントがログアウトされていることを確認してから、ルート(通常はテキストコンソール)としてローカルにログインしてこれを実行できます。umount /home
この状況でファイルシステムが使用中であると報告された場合は、fuser -m /dev/sda9
マウント解除を妨げるプロセスを識別できます/home
。以前のユーザーセッションの残りの部分では直接終了できますが、サービスに属している場合は制御された方法で停止できます。
このタイプの主なメンテナンスを実行するもう1つの一般的な方法は、/home
システムをシングルユーザー/緊急モードで起動することです。使用されているディストリビューションでは、systemd
起動オプションがsystemd.unit=emergency.target
その役割を果たす必要があります。
他の人が述べたように、より簡単な解決策があります。ディレクトリのタイムスタンプが保存されるかどうかは重要ではありません。、問題ディレクトリは、そのディレクトリを含むファイルシステムのルートではありません。 「肥大した」ディレクトリの横に新しいディレクトリを作成し、すべてのファイルを新しいディレクトリに移動し、古いディレクトリを削除し、新しいディレクトリの名前を同じに変更します。名前は昔のようです。たとえば、/directory/A
問題がある場合:
mkdir /directory/B
mv /directory/A/* /directory/B/ # regular files and sub-directories
mv /directory/A/.??* /directory/B/ # hidden files/dirs too
rmdir /directory/A
mv /directory/B /directory/A
もちろん、ディレクトリがどのサービスで使用されている場合は、そのサービスを最初に停止するのが最善です。
答え2
好奇心でこれを再現しましょう:
$ mkdir test
$ cd test
$ time ls # Check initial speed of ls
real 0m0,002s
$ stat . # Check initial size of directory
File: .
Size: 4096 Blocks: 8 IO Block: 4096 directory
...
$ seq 1 1000000 | xargs touch # Create lot of files
$ echo 3 | sudo tee /proc/sys/vm/drop_caches # Clear cache
$ time ls > /dev/null
real 0m1.588s
$ stat . # Check size of directory when files are there
File: .
Size: 22925312 Blocks: 44776 IO Block: 4096 directory
さて、今私たちは大きなディレクトリを持っています。このファイルを削除し、何が起こるのか見てみましょう。
$ ls | xargs rm # To avoid too long argument list
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
$ time ls > /dev/null
real 0m1.242s
$ stat .
File: .
Size: 22925312 Blocks: 44776 IO Block: 4096 directory
はいls
。 TelcoMの回答でも指摘したように、ディレクトリの割り当てサイズが実際に大きく、速度が遅くなります。
問題が単一のディレクトリの場合は、ルートアクセスまたはルートアクセスを必要としないより簡単なソリューションがあります。新しいディレクトリを作成し、残りのファイルをそのディレクトリに移動して、肥大化したファイルを削除します。