データのバックアップにrsyncを使ってみたのですが、appendオプションをつけたせいでファイルが壊れたり転送されなかったりしてはまったので、もうはまらないように備忘録を残しておきます。
現象
rsyncでファイルの同期をとろうと思ったのですが、一部ファイルが転送されなかったり壊れたりしました。
差分があるのにファイルが更新されないパターン
まずは差分があるのにファイルが更新されないパターンです。以下のようなファイルがあって、src/
以下のファイルをdst/
に転送したいです。
$ cat src/hoge.txt hogehoge $ cat dst/hoge.txt fugafuga
この場合、append付きのrsyncのコマンドは以下のようになります。期待としては、src/hoge.txt
とdst/hoge.txt
が同じ内容になっていてほしいです。
$ rsync -a --append src/ dst/
実行してみました。dst/hoge.txt
の内容は更新されませんでした。
$ cat dst/hoge.txt fugafuga
いろいろ試したところ転送前の状態が、src/hoge.txtのファイルサイズ
≦dst/hoge.txtのファイルサイズ
の場合、差分があっても更新されないみたいです。
そもそもファイルが転送されないパターン
差分バックアップをしたかったので、上のコマンドにlink-dest
オプションも追加してみました。ファイルは以下のようになっています。link-dest
にはdst/
を指定します。
$ cat src/hoge.txt hogehoge $ cat dst/hoge.txt fugafuga // 何も表示されない $ ls dst2/
この場合、rsyncのコマンドは以下のようになります。期待としては、新しくdst2/hoge.txt
が作成されていてほしいです。
$ rsync -a --append --link-dest=`pwd`/dst/ src/ dst2/
実行してみました。dst2/
以下には何も転送されていません。
// 何も表示されない $ ls dst2/
先ほど同様、転送前の状態がsrc/hoge.txtのファイルサイズ
≦dst/hoge.txtのファイルサイズ
の場合、差分があっても更新されないみたいです。
ファイルが壊れるパターン
次はappendオプションをつけてファイルが壊れるパターンです。以下のようなファイルがあります。これをappendオプションをつけてrsyncで転送してみます。
$ cat src/hoge.txt hogeeeeeee $ cat dst/hoge.txt fugafuga
rsyncコマンドは以下です。src/hoge.txt
の内容がdst/hoge.txt
に反映されていてほしいです。
$ rsync -a --append src/ dst/
実行してみました。dst/hoge.txt
が2つのファイルが混ざったようなおかしなことになりました。
$ cat dst/hoge.txt fugafugaee
諸々試してみた感じ、転送前の状態で次の2つの条件を満たすとこの事象は発生しました。
src/hoge.txtのファイルサイズ
<dst/hoge.txtのファイルサイズ
src/hoge.txt
とdst/hoge.txt
の先頭数バイトの内容が異なる
原因
rsyncについて調べたときに、途中で中断・再開するためにはappendオプションをつけておけ、みたいな記事を見かけたので何も考えずにつけたのですが、このappendオプションが悪さをしていたみたいです。
manコマンドでappendオプションの意味を調べてみます。
$ man rsync ... --append append data onto shorter files ...
今まで試したrsyncの挙動と一緒に考えると、どうやら転送先ファイルの方がサイズが小さい場合に、サイズの違い分の差分のみを転送先ファイルに追加しようとするようです。
つまり今回のファイルが壊れるケースだと、ファイルサイズの差分分の末尾のee
だけ転送しようとしたようです。しかし、実際には末尾ee
以外にも差分があったため、実行結果が2種類のファイルの内容が混ざったようなおかしなことになったようです。
なので、
- 転送元ファイルよりも転送先ファイルの方がサイズが小さい場合 → ファイルを転送しない
- 転送元ファイルと転送先ファイルにサイズの違い分以上の差分がある場合 → 転送元と転送先ファイル内容が混ざる
といった状態になるみたいです。
コメント