web-dev-qa-db-ja.com

rsyncを使用してデータをコピーすると、サイズの不一致が発生します

マシンを切り替えて、古いハードドライブ(/dev/sda4)を新しいマシンに接続しました。

古いマシンのハードドライブ(720G)は、新しいマシン(736G)に比べて少し小さかったので、少し大きめのパーティションも作成しました。

そこで、次に示すように、rsyncを実行して、すべてのデータを新しいパーティションにコピーしました。

linux-70e2:/ # time rsync -azprvl /mnt/external-disk/foo /media/sda4/

...
sent 169,237,139,987 bytes  received 24,529 bytes  24,419,185.41 bytes/sec
total size is 190,542,953,489  speedup is 1.13

real    115m30.297s
user    112m13.068s
sys     3m59.996s

データはエラーなしでコピーされます。

しかし、私がそうするとき:

du -h -m -s /mnt/external-disk/foo /media/sda4/foo

私は得る:

162414  /mnt/external-disk/foo
181721  /media/sda4/foo

誰かがこの大きな違いを説明してもらえますか?同じ結果が得られないのはなぜですか?これは私を何日も狂わせています。他にもいくつかのパーティションがあり、同様の不一致が発生しています。

両方のパーティションはext4です。

linux-70e2:/ # mount | grep sda4
/dev/nvme0n1p5 on /media/sda4 type ext4 (rw,relatime,data=ordered)
/dev/sda4 on /mnt/external-disk type ext4 (rw,nosuid,nodev,relatime,data=ordered,uhelper=udisks2)

私の知る限り、SSDである両方のドライブに問題はありません。それらの1つは真新しいです。両方でe2fsckを実行しました。

さらに、私は実行しました:

find -L /mnt/external-disk type/foo -type l

これは、ソースディレクトリの下にシンボリックリンクをリストしません。

この種の目的でrsyncを使用するのはこれが初めてではありませんが、これまでこの種の問題が発生したことはありません。お知らせ下さい!

3
carlspring

不一致は、ほとんどの場合、古いディスク上のファイルの数が少ないことが原因である可能性があります。

とにかく、最初にファイル番号とiノード番号が同じであることを確認しましょう。

  • 両方のマウントポイントでfind <path> | wc -lを発行します。ファイル/ディレクトリの数は同じですか?
  • df -iを発行します。 iノードの数は同じですか?

両方の質問に対する答えが「はい」の場合、違いは新しいディスク上のよりまばらなファイルによって説明できます。しかし、スパースファイルとは何ですか?要するに、スパースファイルは見た目よりも小さい通常のファイルです。これは、(比較的)最新のファイルシステムの機能のおかげで可能です。ファイルにすべてのゼロを書き込む代わりに、システムに「このファイル(またはその一部)はゼロでいっぱいです。書き込ませないでください」というフラグを設定するだけです。モール"。

デフォルトでは、duは、見かけのサイズではなく、ファイルが使用する実際のスペースを報告します。見かけのサイズを表示するには、du --apparent-sizeを使用します(他のオプションについては、 du manpage を参照してください)

実際の例として、コマンドtruncate test.img -s 1Gを使用してスパースファイルを作成できます。 lsによって報告されているように、新しく作成されたファイルのサイズは1 GBですが、du -hs test.imgを試してみると、非常に小さいファイルサイズ(場合によってはゼロ)が表示されます。どうすれば可能ですか?上で述べたように、現代のファイルシステムは時々アプリケーションに「嘘をつき」、実際には存在しない割り当てられたサイズを報告します。反対側では、du -hs --apparent-size test.imglsと同じサイズを出力します。

スパースファイルへの書き込みを開始すると、ファイルシステムは必要なスペースを動的に割り当てます。たとえば、dd if=/etc/services of=test.img conv=notrunc,nocreatを発行すると、以前はすべてスパースだったtest.imgファイルにデータが書き込まれます。これで、du -hs test.imgを実行すると、データストレージに割り当てられた最大600KBが報告されます。

明らかですが、非常に重要な意味は、スパースファイルのサポートは、ゼロで埋められたファイル(またはその一部)に対してのみ最適化できるということです。ファイルへの書き込みとまったく同じ瞬間に、割り当てられたスペースが増え始めます。これは、アプリケーションがスパースファイルの処理方法を知らない限り、ファイルに他のゼロを書き込む場合に当てはまります(この場合、アプリケーションはファイルシステムにすべてゼロを書き込むことを通知し、ファイルシステムはそれに応じて最適化します)。

本当にスペースを事前に割り当てたい場合はどうなりますか?次に、fallocate test.img -l 1Gを使用できます。 ls; du -hs test.img; du -hs --apparent-size test.imgを実行すると、ファイルがfallocate呼び出しによって実際に完全に割り当てられたため、すべてのツールがまったく同じサイズを報告することがわかります。

つまり、コピー中に、一部のファイルがそれほどまばらに再作成され、まばらなセクションが「実際の」ゼロに置き換えられた可能性があります。 rsyncでスパースファイルを使用するには、-Sオプションを使用する必要がありました。

4
shodanshok

Rsyncオプションはハードリンクをコピーしません。-Hを追加してみてください

-H、-hard-linksこれは、転送でハードリンクされたファイルを探し、受信側で対応するファイルをリンクするようにrsyncに指示します。このオプションがないと、転送内のハードリンクされたファイルは、個別のファイルであるかのように扱われます。空でない宛先を更新する場合、このオプションは、ソースで一緒にハードリンクされているファイルが宛先で一緒にハードリンクされていることを保証するだけです。現在、ソースファイル間に存在しない宛先上の既存のハードリンクを切断しようとはしていません。ただし、1つ以上の追加リンクファイルにコンテンツの変更がある場合、更新時にリンクが解除されることに注意してください(--inplaceオプションを使用していない場合)。

VM画像などのスパースファイルも、ボイドを実際のブロックに置き換えることで使用量を増やしている可能性があります。rsyncで--sparseオプションを使用してみてください。

diffを使用してディレクトリツリーを比較することもできます。 https://stackoverflow.com/questions/4997693/given-two-directory-trees-how-can-i-find-out-which-files-differ を参照してください

1

過去にこのような違いを見たとき、それは通常、ドライブのブロックサイズの違いが原因でした。これは、元のドライブが古い場合に特に当てはまります。これは、次の方法で確認できます。

tune2fs -l /dev/sdXX | grep -i 'block size'
1
Tim Brigham