誤って何百万ものファイルをディレクトリに書き込んだ後(削除した後)、[Bash]タブの完了が遅くなる

誤って何百万ものファイルをディレクトリに書き込んだ後(削除した後)、[Bash]タブの完了が遅くなる

ある日、私のホームディレクトリに400万の小さなテキストファイルを書き込むスクリプトエラーが発生しました。

誤って400万個の小さなテキストファイルをフォルダに書きました。削除する最良の方法は何ですか?

ファイルを削除しましたが、それ以降、ファイル名またはパスを完了するためにタブをクリックするたびに何かが発生するまで0.5秒の遅延が発生します。

これでファイルが削除されましたが、gptまたは同様のファイルに継続的な破損があったようです。この問題をクリーンアップするために使用できる便利なツールはありますか?

ファイルシステムはext4(RAID 1の3TBドライブ2台)で、CentOS 7を実行しています。

% ls -ld "$HOME"
drwx------. 8 myname myname 363606016 Nov 18 09:21 /home/myname 

ありがとう

答え1

説明で述べたように、ホームディレクトリ自体はサイズが大きいため、もはや縮小されません。ホームディレクトリの内容を取得するには、毎回(キャッシュまたはディスクから)大量のデータを読み取る必要があります。

この問題を解決するには、ホームディレクトリを再作成する必要があります。

  • ログアウトしてルートとしてログインしたら、ホームディレクトリを参照する実行中のプロセスがないことを確認してください。

    lsof /home/myname
    
  • ホームディレクトリをコピーします。

    cd /home
    cp -al myname myname.new
    
  • ホームディレクトリの名前を変更します。

    mv myname myname.old
    
  • 新しいホームディレクトリの名前を変更します。

    mv myname.new myname
    

これでもう一度ログインできます。輝く新しいホームディレクトリは実際に必要なスペースだけを占有し、ファイル操作は予想通りに速くなければなりません。cp -al新しいディレクトリの下のすべてのファイルが利用可能であることを確認してください。ただし、ディレクトリ構造に加えて余分なスペースを占有しないようにハードリンクを使用してください。ハードリンクがあるため、いずれかのディレクトリにあるファイルに対するすべての変更は他のディレクトリに反映されますが、安全に削除できますmyname.old

一度に多数のファイルを含むすべてのディレクトリに同様のアプローチを使用できますが、ほとんどの場合、最初にログアウトする必要はありません。

答え2

他の回答で述べたように、ディレクトリを簡単に再作成できる場合は、システムをシャットダウンすることなくこれを行うことができます。

他の場合は、ディレクトリツリー内のファイルの数またはサイズのため、ファイルを新しいディレクトリにコピーするのがより困難になります。ファイルシステムのマウント解除(またはルートファイルシステムの場合はリカバリディスクからの起動)をe2fsck -fD /dev/sdX実行することもできます。ディレクトリを最適化するファイルシステム(-Dオプション)。これにより、ファイルデータをコピーせずにディレクトリエントリを最小ブロック数に圧縮します。

答え3

mvStephen Kittの答えは基本的に正しいアプローチですが、完了するのではなく使用する必要がありますcp。ファイルの移動にはほとんど時間がかからないため、すべてのファイルをコピーするのに数分または数時間を費やす必要はありません。たとえば、

  1. ユーザー(Sshセッションを含むすべてのログインインスタンス)でログアウトし、rootとしてログインします。

    システムが直接ルートログインを防止するように設定されている場合(たとえば、ルートパスワードが無効になっている場合)、rootとしてログインします。その他suユーザー(必要に応じて1つを作成し、アクセスまたは許可sudo)ルートシェルをインポートします。

  2. ユーザーがプログラムを実行していないか、ホームディレクトリにファイルが開いているかどうかを確認する必要はありません。ファイルハンドル(およびinode番号)は変更されないためホームディレクトリに独自の専用ファイルシステムがない場合(たとえば/home/username/home

    実際の移動(以下の手順3)は1秒もかかりません(ホームディレクトリの最上位レベルのファイルとディレクトリの数によって異なります。これが移動する必要があるすべてです)。mv代わりにcp- データはコピーされず、名前変更を介してすべてがすばやく完了します。

    そのような短い時間内に新しいファイルを作成したり、移動していないファイルを開こうとすることはほとんどありません。

    しかし、妄想があるか、可能cronまたは、仕事などでこれを実行してatから一時的に無効にすることもできます。後で再起動することを忘れないでください。

    これを実行できる他の実行中のプロセス(NFS、Samba、メール配信、ftpdなど)も同様です。今すぐこのプロセスを終了し、後で再起動してください。たとえば、pkill -u username次のようにしてすべてのユーザー所有プロセスを終了できます。

  3. mvホームディレクトリのすべての内容を新しいホームディレクトリにコピーします。たとえば、ホームディレクトリがある場合は、root/home/usernameとして次のコマンドを実行します。

    cd /home
    mv username username.old
    mkdir username
    
    # move the files and subdirectories to the new home
    # BTW, using `find` ensures that "hidden" dotfiles and dotdirs are moved
    # along with the non-hidden files & dirs.
    cd username.old
    find . -mindepth 1 -maxdepth 1 -exec mv {} ../username/ +
    cd ..
    
    # fix ownership and perms of the new home dir
    gid="$(getent passwd username | cut -d: -f4)"
    perms="$(stat --printf "%a" username.old)"
    chown "username:$gid" username
    chmod "$perms" username
    
    rmdir username.old
    

注:stat --printf ...上記の操作にはGNU統計が必要です。 Centos 7を実行していると言われましたが、これがCentos 7です。

GNU以外のシステムで同様の問題が発生した場合は、権限を複製する別の方法を見つける必要があります。 FreeBSDのバージョンはstat機能は似ていますが、オプションが異なります。または、新しいディレクトリの権限を手動で設定します。おそらく775or 755(set-gidなどを使用して)です。ただし、2775orまたは他のものを使用して2755確認してください。ls -ldstat

関連情報