ZFSにexample.log
という大きなファイル(8GB)があるとします。 cp example.log example.bak
を実行してコピーを作成します。次に、元のファイルの数バイトを追加または変更します。何が起こるか?
ZFSは8GBファイル全体をコピーしますか、それとも変更されたブロックのみ(およびファイル記述子からそのブロックを指すiノードのすべてのチェーン)をコピーしますか?
私の知る限り、FreeBSD ZFSはcpを使用したコピーオンライトをサポートしていません。ネイティブcpにはそのような軽量コピーのオプションがないようで、ZFSシステムでGNU cp with --reflink
エラーを出力しようとしています。エラーメッセージ "cp:failed to 「example.log」から「example.bak」のクローンを作成:操作はサポートされていません。
コメンターは、Solaris cpにはそのようなコピーを行うための-z
スイッチがあると述べています。
ただし、これがあなたの根本的な質問であるcopy-on-write isがファイルシステムのスナップショットに使用されていることを願っています:利用可能な1000GBのうち900GBが使用されているとしましょう。 、スナップショットは900GBを占有しません。実際、最初は新しいデータブロックをまったく占有しません。
example.log
を含む元のファイルシステムのスナップショットを作成すると、2つの「コピー」が作成されます。スナップショット内の読み取り専用バージョンと、元の場所にあるライブバージョンです。コピーが変更された場合はどうなりますか。追加によるものか、インプレースでの変更によるものですか。ここで魔法が発生します。変更されたブロックのみがコピーされ、スペースを使い始めます。ファイルが変更されるとすぐにファイル全体がコピーされるわけではありません。
cp
コマンドは新しいファイルを作成するため、すべてのブロックの複製が存在します。元のファイルの数バイトを変更すると、ZFSはまずそれらのバイトを含むデータのブロックをディスクからRAMにコピーし、新しいバイトをそれに適用してから、そのブロックをディスク上の新しい場所に書き込みます。元のブロックは解放されます(ここでは簡略化していますが、基本的にそれが行われています)。ファイルの残りのブロックはそのまま残されます。
質問のiノード部分について:ZFSにはiノードがありません。代わりに、「間接ブロック」を維持します。これらは、ファイルのデータを指すディスク上のメタデータのブロックです。ファイルサイズとファイルのブロックサイズによっては、間接ブロックのレイヤーが存在する場合があります。変更されたブロックを指す間接ブロックは更新する必要がありますが、残りはそのままになります。