8 年間で多くのことが変わりました。
ファロケイト
fallocate -d
filename
既存のファイルに穴を開けるために使用できます。 fallocate(1)
から マニュアルページ:
-d, --dig-holes
Detect and dig holes. This makes the file sparse in-place,
without using extra disk space. The minimum size of the hole
depends on filesystem I/O block size (usually 4096 bytes).
Also, when using this option, --keep-size is implied. If no
range is specified by --offset and --length, then the entire
file is analyzed for holes.
You can think of this option as doing a "cp --sparse" and then
renaming the destination file to the original, without the
need for extra disk space.
See --punch-hole for a list of supported filesystems.
(そのリスト:)
Supported for XFS (since Linux 2.6.38), ext4 (since Linux
3.0), Btrfs (since Linux 3.7) and tmpfs (since Linux 3.5).
そのリストにある tmpfs は、私が最も興味深いと思うものです。ファイルシステム自体は、コンテンツを保存するのに必要なだけの RAM しか消費しないほど効率的ですが、コンテンツ sparse を使用すると、その効率がさらに向上する可能性があります。
GNU cp
さらに、途中のどこかで GNU cp
スパースファイルについて理解しました。 cp(1)
の引用 デフォルトモードに関するマニュアルページ --sparse=auto
:
疎な SOURCE ファイルは大まかなヒューリスティックによって検出され、対応する DEST ファイルも同様に疎になります。
でも --sparse=always
もあります 、これは fallocate -d
に相当するファイルコピーをアクティブにします インプレース:
--sparse=always
を指定 SOURCE ファイルにゼロ バイトの十分な長さのシーケンスが含まれている場合は常に、スパース DEST ファイルを作成します。
ようやく tar cpSf - SOURCE | (cd DESTDIR && tar xpSf -)
を引退させることができました これは 20 年間、スパース ファイルをスパース性を維持したままコピーする私の白ひげの方法でした。
Linux / UNIX の一部のファイルシステムには、既存のファイルに「穴を開ける」機能があります。参照:
- 機能に関する LKML の投稿
- UNIX ファイルの切り捨てに関するよくある質問 (F_FREESP を検索)
これはあまり移植性が高くなく、全面的に同じ方法で行われるわけではありません。現時点では、Java の IO ライブラリはこのためのインターフェースを提供していないと思います。
fcntl(F_FREESP)
経由で穴あけが利用できる場合 または他のメカニズムを介して、コピー/シーク ループよりも大幅に高速になるはずです。
ファイル全体を事前に割り当て、占有されているページ/セクションのテーブル/ビットセットを維持する方がよいと思います。
ファイルをスパースにすると、これらのセクションが再利用された場合に断片化されます。おそらく、数 TB のディスク領域を節約しても、高度に断片化されたファイルのパフォーマンス ヒットに見合う価値はありません。