私が理解したように、「スパースファイル」とは、ファイルに「ギャップ」がある可能性があるため、実際に使用されるデータが論理ファイルサイズよりも小さくなる場合があることを意味します。
Linuxファイルシステムはどのようにファイルをディスクに保存しますか?私は主にext4に興味があります。だが:
ファイルをディスクに順次保存できますかできません?つまり、ファイルの一部は物理アドレスXの下にあり、他の部分は物理アドレスYの下にあり、X +オフセットに近くありません)。
はい;これはファイルの断片化と呼ばれ、特に大きなファイルの場合は珍しくありません。ほとんどのファイルシステムは、必要に応じてほぼ順次スペースを割り当てますが、将来の動作を推測することはできません。したがって、ファイルに200MiBを書き込んでからさらに100MiBを追加すると、両方のデータセットがゼロ以外の確率でディスクのさまざまな領域に格納されます(基本的に、最初の書き込みの後、2番目の書き込みの前に発生する、ディスク上でより多くのスペースを必要とする他の書き込みは、2つの書き込みの間に入る可能性があります)。ファイルシステムが満杯に近い場合、通常は状況が悪化します。新しいファイルを保持するのに十分な大きさの連続した空き領域がない可能性があるため、断片化する必要があります。
どういうわけかファイルの連続性を制御できますか? 10GBの大きなファイルを割り当てたい。ディスク内でシーケンシャルになり、異なるオフセット間で分割されないようにします。
作成時に、ファイルのターゲットサイズをファイルシステムに通知できます。これはファイルシステムがそれを最適に保存するのに役立ちます。最新のファイルシステムの多くは、遅延割り当てと呼ばれる手法を使用しています。この手法では、新しいファイルのディスク上のレイアウトが可能な限り遅く計算され、計算の実行時に利用できる情報が最大化されます。 posix_fallocate(3)
関数を使用して、合計でどのくらいのディスク容量を割り当てる必要があるかをファイルシステムに通知することで、このプロセスを支援できます。最近のファイルシステムは、この割り当てを順番に実行しようとします。
タイプによって動作が異なりますか?
ファイルシステムが異なると、動作も異なります。 NILFS2などのログベースのファイルシステムは、Ext4などのエクステントベースのファイルシステムと同じ方法でストレージを割り当てません。これはバリエーションの1つの例にすぎません。
コマンドfilefrag
は、ファイルがデバイスに物理的にどのように保存されているかを示します。
# filefrag -v /var/log/messages.1
Filesystem type is: ef53
File size of /var/log/messages.1 is 41733 (11 blocks, blocksize 4096)
ext logical physical expected length flags
0 0 2130567 1
1 1 15907576 2130568 1
2 2 15910400 15907577 1
3 3 15902720 15910401 7
4 10 2838546 15902727 1 eof
/var/log/messages.1: 5 extents found
ファイルを1つのパスで書き込む場合、おそらくファイルはフラグメント化されません。
fallocate
(1)のmanページはかなり明確です:
fallocate
は、ブロックをファイルに事前に割り当てるために使用されます。fallocate
システムコールをサポートするファイルシステムの場合、これは、ブロックを割り当て、初期化されていないものとしてマークすることで迅速に行われ、データブロックにIOを必要としません。これは、ファイルをゼロで埋めます。Linuxカーネルv2.6.31以降、
fallocate
システムコールは、btrfs、ext4、ocfs2、およびxfsファイルシステムでサポートされています。
シーケンシャルですか?システムは最初にブロックを順番に割り当てようとします。できない場合は、警告は表示されません。
スパースファイルについて言及しましたが、他の回答ではそれらについて言及していません。
ほとんどのファイルはスパースではありません。ファイルを作成する最も一般的な方法は、最初から最後まで、すべてを一度に書き込むことです。そこに穴はありません。
ただし、「1,000,000,000,000の位置に移動して、そこにバイトを書き込む」と言うことはできます。これにより、サイズがエタバイトのように見えるファイルが作成されますが、実際には(おそらく)ディスク上で4kしか使用されません。これはスパースファイルです。
同じファイルに対してこれを何度も行うことができ、大量の空に散在する少量のデータが残ります。
これは便利ですが、欠点が2つあります。
1つ目は、ファイルが断片化することです。これは、あなたが心配していることです。
2つ目は、すべてのプログラムがこれらのファイルを適切に処理できるわけではないことです。例えば。一部のバックアップソフトウェアは、空をバックアップし、それによって必要以上に大きいバックアップを作成しようとします。バックアップメディアには too 大きい可能性があります。
ファイルの連続性をどうにかして制御できますか? 10GBのファイルを割り当てたい。ディスク上でシーケンシャルになり、異なるオフセット間で分割されないようにします。
これを実現するには、少なくともいくつかの方法があります。
大量の予備スペースがあるファイルシステムを使用し、スペースを事前に割り当てます(たとえば、アプリケーション固有のデータ終了マーカーを使用し、ファイルサイズが10GBに達するまでランダムデータを追加します)。これによりフラグメント化されていないデータが生成されるとは限りません。
Ext4などの代わりに raw(未調理の)ファイルシステム を使用します。DBMSは、パフォーマンス上の理由からこれを行うことがあります。トレードオフは、必要に応じて独自のキャッシング/ジャーナリング/リカバリなどを行う必要があることです。
これを行うことで多くのことを得るインスタンスは比較的まれです。まず、パフォーマンスを最適化するために他の場所を探します。
こちらもご覧ください