再帰的に走査せずにZFS上の大きなディレクトリを一括削除する


9

大量のデータが含まれているディレクトリを削除したい。これは私のバックアップアレイです。これは、ZFSファイルシステム、線形スパン、「san」と呼ばれる単一のプールです。Sanがマウントされている/san ので、/ san / thispc / certainFolderを一括削除したい

$ du -h -d 1 certainFolder/
1.2T    certainFolder/

私が待つ必要rm -rf certainFolder/があるのではなく、そのディレクトリへのハンドルを破棄して、上書き可能にすることができます(再作成することを選択した場合でも、同じディレクトリ名でも)??

たとえば、zfs fs内部mgmntがディレクトリを具体的にどのようにマップするかを詳しく知らない場合などですが、たとえば、そのマップがたとえばを見つけ、適切なエントリを削除すると、たとえば、ディレクトリが表示されなくなり、ディレクトリが以前保持していたスペースがある種の監査からも削除する必要があります。

ext3 fsを使用している場合でも、これを行う簡単な方法はありますか?それとも、再帰的な削除コマンドが最初に行う必要があること、つまり、ジャーナルを調べて編集することですか?

私はちょうどkill thisDirそれがいくつかの種類のIDを削除し、ディレクトリが表示されなくなりls -la、データがドライブにまだ残っているのに、スペースが再利用されるようにしたいと思っています上書きされます)、ZFSはそれだけでクールなので?

つまり、zfsは本当にかっこいいと思います。どうすればよいでしょうか。理想的には?手をこすり合わせる:-)

私の特定のユースケース(zfsへの私の愛情以外)は、バックアップアーカイブの管理です。このバックアップディレクトリは、Windowsボックスのfreefilesync(AWESOME PROG)を介してsmbファイル共有にプッシュされますが、古いファイルが移動するバージョンディレクトリもあります。メインバックアップにあるトップレベルのディレクトリを削除します。これは、バージョンにコピーされます。たとえば/san/version/someStuffrm -rf /san/version/someStuff/*パテターミナルから隔月でクリーンアップする場合、別のターミナルを開く必要があります。毎回そうしたくないので、無駄にrm -rfを監視する必要があります。

つまり、おそらくハンドルを解放するようにコマンドを設定してから、標準出力に出力する必要があります。 より現実的には、zfs destroy san/version; zfs create -p -o compression=on san/version@ Gillesからの応答から数秒でデータセットを再作成します。


FYI、私は現在使用してイムのデータセットを作成するには、このコマンドを実行しました。.. `zfs create dataset -p -o compression=on yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
ブライアン・トーマス

元の質問に記載された問題を解決した場合は、回答を受け入れてください。質問に追加するだけの問題はまったく異なるように見えるため、新しい質問で実際に質問する必要があります。
jlliagre 2015

回答:


12

適切なファイルシステムでは解放されたブロックの追跡は避けられず、ZFS も例外ではありませんただし、ZFSでは、基になるクリーンアップを「延期」することにより、ほぼ瞬時にディレクトリを削除する簡単な方法があります。それは技術的にGillesの提案に非常に似ていますが、追加のコードを必要とせずに本質的に信頼性があります。

ディレクトリを削除する前にファイルシステムのスナップショットを作成すると、その下で調査/解放する必要がなく、すべてスナップショットで参照されているため、ディレクトリの削除は非常に高速になります。その後、バックグラウンドでスナップショットを破棄して、スペースを徐々に回復することができます。

d=yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
zfs snapshot ${d}@quickdelete && { 
    rm -rf /${d}/certainFolder
    zfs destroy ${d}@quickdelete & 
}

さて、私はスナップショットに慣れていません。それは私を助けるかもしれません。一日中削除/移動しています。メインのバックアップディレクトリだけでなく、内部の最上位ディレクトリ(それぞれホスト名で始まるいくつかの最上位レベル)のデータセットを作成しました。そのため、プールを破壊して再作成するだけの柔軟性がありますが、完全ではありません。 、私は常にこれらのプールディレクトリ全体を削除する必要はないので、さらに作成する必要があり、データセットを大量に作成する必要があるため、その理由であなたの提案が好きです!
ブライアントーマス

4
可能な場合は、有効にfeature@async_destroyすると(ユーザーまたは管理者の観点から)これを高速化するのにも役立ちます。参照してくださいzpool get all $pool。少なくとも最後に調べたところ、プールのインポートで保留中の破棄が進行中の場合、その破棄は同期になり、破棄が完了するまでプールのインポートは完了しません。再起動する必要がある場合は注意してください!
CVn 2016

大量の削除でSMB接続が失われたフリーナスを使用しているお客様がいます。定期的なスナップショット(および自動削除)を有効にすると、問題が「消えた」。スペースの解放にはバックグラウンドで時間がかかりますが、SMB共有にはいつでもアクセスできます。
Martin Seitl 2017年

6

あなたが求めていることは不可能です。または、より正確には、ディレクトリとそのファイルを削除する際にコストがかかります。削除時に支払わなかった場合は、別の場所で支払う必要があります。

ディレクトリを削除するだけではなく、ほぼ瞬時に削除されます。ディレクトリとその中のすべてのファイルを削除し、同様にそのすべてのサブディレクトリを再帰的に削除します。ファイルを削除することは、リンクカウントをデクリメントし、リンクカウントが0に達し、ファイルが存在しない場合、リソース(ファイルの内容とファイルメタデータに使用されるブロック、およびファイルシステムがiノードテーブルを使用する場合はiノード)を空きとしてマークすることを意味します開いた。これはディレクトリツリー内のすべてのファイルに対して実行する必要がある操作であるため、かかる時間は少なくともファイル数に比例します。

リソースを無料としてマークするコストを遅らせることができます。たとえば、ガベージコレクションされたファイルシステムがあり、そこに含まれるファイルを削除せずにディレクトリを削除できます。ガベージコレクターを実行すると、ディレクトリ構造を介して到達できないファイルが検出され、空きファイルとしてマークされます。rm -f directory; garbage-collectガベージコレクションされたファイルシステムで行うことは、rm -rf従来のファイルシステムで、異なるトリガーを使用します。GCは、めったに必要とされない追加の複雑さであるため、ガベージコレクションされたファイルシステムはほとんどありません。ファイルシステムに空きブロックが必要なためにGCが見つからない場合、GCの時間はいつでも来る可能性があります。そのため、操作のパフォーマンスは操作だけでなく、過去の履歴にも依存するため、通常は望ましくありません。実際の空き容量を取得するには、ガベージコレクターを実行する必要があります。

通常のファイルシステムでGCの動作をシミュレートする場合は、次のように実行できます。

mv directory .DELETING; rm -rf .DELETING &

(エラーチェック、停電への耐性など、重要な詳細の多くは省略しました。)ディレクトリ名はすぐに存在しなくなります。スペースは徐々に再利用されます。

GCなしで削除中にコストを支払うことを回避する別のアプローチは、割り当て中に支払うことです。ディレクトリツリーを削除済みとしてマークし、ブロックを割り当てるときに削除されたディレクトリを通過します。これはハードリンクとの調整が困難ですが、ハードリンクのないファイルシステムでは、割り当てのO(1)コストを増やすことで実現できます。ただし、これにより、非常に一般的な操作(ファイルの作成または拡大)がより高価になり、唯一の利点は、比較的まれな操作(大きなディレクトリツリーの削除)がより安価になることです。

ディレクトリツリーが独自のブロックのプールとして格納されている場合は、ディレクトリツリーを一括削​​除できます。(注:ZFSの「ストレージプール」とは異なる意味で「プール」という言葉を使用しています。適切な用語が何なのかわかりません。)それは非常に速いかもしれません。しかし、空きスペースをどうしますか?別のプールに再割り当てすると、ファイルを個別に削除するよりもはるかにコストはかかります。このスペースを未使用の予約スペースとして残しておくと、すぐに再利用できません。ディレクトリツリーに個別のプールを使用すると、そのプールのサイズを(その場でまたは明示的に)増加または減少させるための追加コストが発生します。ツリーを独自のストレージプールにすると、ファイルをツリーの内外に移動するコストも増加します。


いい答えですね!前半は通常のシステムで完全に満足できます。ZFSにはいくつかのトリックがあります。たとえば、フォーマットする必要はないので、プールを破棄した場合、次回プールを(複数形に)するつもりだと思ったら、tiが消えます。レーダーは瞬時に、そしてそのスペースはすぐに利用可能です。私はそれをzfs、プール内のディレクトリで再作成しようとしていると思います。プール自体ではないため、プールの性質はより標準的になり、あなたが言及した方法はその場合に適用されるようです。面白い。
ブライアントーマス

私は間違いを犯した場所だと思います。昨晩記事を読んだら、それが見つかるかどうかわかりません。プールは、FSで最大18,446,744兆プールに制限されているディレクトリのように使用されることを示しています。上位のバックアップディレクトリをそれぞれプールとして作成すると、バックアップがそれらに書き込まれるときに、dirはすでに変更されておらず、簡単に削除できます。プールが存在しなかった場合、バックアップはdirを作成するだけで、プールはには表示されませんzfs list。それまでは、他の誰かがプールのサブディレクトリでZFSを一括削除する方法についていくつかの情報を提供することを期待しています。:-)
ブライアントーマス

また、あなたの最初の応答を読んだとき、私の最初の考えは、「正しい!」「コスト」!これは、ジャーナルエントリの削除について話していたときに触れていたものです。私が疑ったように。くそー!しかし、あなたは正しい軌道に乗っています。ここで何かを考えてみましょう。そうすれば、これを実行するスクリプトをまとめることができます...考え:-)
Brian Thomas

ブライアン、zpoolとデータセットを混同しないように注意してください。実際に、作成できるzpoolsの数にハードコードされた到達可能な制限はありませんが、マシンで使用できる基礎となるデバイス(パーティションなど)の数によってすぐに制限されます。さらに、単一のディレクトリ専用のプールがあると、いくつかの貴重なzfs機能が無効になり、移動操作が大幅に遅くなります。
jlliagre

このコメントについて、ここで@Gillesが作成しました。「しかし、空きスペースをどうしますか?それを別のプールに再割り当てすると、コストはかかりますが、ファイルを個別に削除するよりもはるかに少ないです」確かではありませんが、そこにはないと思います新しいプールを作成するペナルティバーです。書き込み時にのみ対処すると思います。..私は、これは同じメカニズムであると考えている...同じ理由で分割する必要はありません
ブライアン・トーマス

1

高速にする必要がある場合は、新しい一時ディレクトリとmvその下のディレクトリを生成してから、再帰的に一時ディレクトリを削除します。

t=`mktemp -d`
mv certainFolder $t/
rm -rf $t &

&削除ハンドルまたはスカッシュエラーはありますか?
ブライアントーマス

1
これはGillesの提案と実際には同じで、同じ欠陥があります。OSが再起動されるか、rmコマンドが他の理由で完了しない場合、ファントムディレクトリは削除されずに残ります。
jlliagre 2015

ああ、そうですが、&は私にとって新しいものです。それはパズルの一部です...ハンドルを取り除きたかったのです。しかし、はいあなたの権利、問題がある場合はそのごみを望まないでください..
ブライアントーマス

@BrianThomasは&単にプロセスのバックグラウンドを設定するだけなので、削除の実行中に同じシェルで他のことを続けることができます(関連するパフォーマンスペナルティの対象となります)。
CVn 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.