すでにテラバイト単位のファイルを でコピーしましたが、ファイルの特殊な属性を保持するためにrsync
を使用するのを忘れました。--archive
rsync
今回、再度実行してみました--archive
が、予想よりもずっと遅かったです。メタデータを再帰的にコピーするだけで、これをより速く行う簡単な方法はありますか?
答え1
--reference
パラメータを使用してchown
、所有者、グループ、権限、タイムスタンプをコピーできますchmod
。touch
これを行うためのスクリプトは次のとおりです。
#!/bin/bash
# Filename: cp-metadata
myecho=echo
src_path="$1"
dst_path="$2"
find "$src_path" |
while read src_file; do
dst_file="$dst_path${src_file#$src_path}"
$myecho chmod --reference="$src_file" "$dst_file"
$myecho chown --reference="$src_file" "$dst_file"
$myecho touch --reference="$src_file" "$dst_file"
done
(chown を許可するため) と 2 つのパラメータ (ソース ディレクトリと宛先ディレクトリ) を指定して実行する必要があります。スクリプトは実行する内容のみをエコーします。満足できる場合は、でsudo
行を変更します。myecho=echo
myecho=
答え2
「rsync にはコピーするメタデータしかないのに、なぜこんなに遅いのか、どうすればもっと速くできるのか」という質問を扱うと、次のようになります。
rsync
通常、 は、変更されていないファイルを検出してスキップするためのヒューリスティックとして、等しい mtimes を使用します。 なし--archive
(具体的には なし--times
) の場合、宛先ファイルの mtimes は rsync を実行した時間に設定されたままになりますが、ソース ファイルの mtimes は変更されません (ユーザーによる手動のトリックは無視されます)。ソース ファイルの内容が変更されていないという外部保証がない場合、rsync は変更されている可能性があると想定する必要があり、そのためチェックサムを計算したり、宛先に再度コピーしたりする必要があります。これと、--whole-file
ローカル -> ローカル同期の場合に が暗黙的に適用されるという事実により、rsync
なし はローカル同期の場合--times
とほぼ同等になりますcp
。
宛先ファイルの内容の更新が許容される場合、またはソース ファイルが元のコピー以降変更されていない場合は、rsync --archive --size-only
単純な rsync よりも高速になるはずです。
rsync
何のコピーに時間がかかっているのか疑問に思う場合は、rsync --archive --dry-run --itemize-changes ...
簡潔ではありますが詳細を徹底的に説明します。
答え3
警告: 特別な回避策がなければ、cp --attributes-only
少なくとも Precise では、GNU は宛先ファイルを切り捨てます。以下の編集を参照してください。
オリジナル:
このような状況では、おそらく GNU cp の--attributes-only
オプションを と一緒に使用する必要があります--archive
。これは、試行錯誤されたコードであり、ファイルシステムに依存しないすべての属性を実行し、シンボリック リンクをたどりません (シンボリック リンクをたどると問題が発生する可能性があります)。
cp --archive --attributes-only /source/of/failed/backup/. /destination/
ファイルと同様に、cp
拡張属性が追加されます。ソースと宛先の両方に拡張属性がある場合は、追加ソースの拡張属性を宛先にコピーします (最初に宛先の xattrs をすべて削除するのではなく)。これは、cp
ファイルを既存のツリーにコピーする場合の動作を反映していますが、期待どおりにならない可能性があります。
また、最初にハードリンクを保存しなかったがrsync
、今保存したい場合は、cp
しません修正してください。rsync
正しいオプションで再度実行したほうが良いでしょう(私のその他の回答) と忍耐力が必要です。
もしあなたがこの質問を見つけたのなら故意にメタデータ/ファイルコンテンツを分離して再結合したい場合は、メタストアUbuntu リポジトリにあります。
追加編集:
cp
GNU coreutils
>= 8.17 以降では説明どおりに動作しますが、coreutils <= 8.16 ではメタデータを復元するときにファイルが切り捨てられます。疑わしい場合は、cp
この状況ではrsync
使用しないでください。正しい選択肢そして/または忍耐強くいてください。
自分が何をしているのかを完全に理解していない限り、これをお勧めしませんが、以前のGNUではcp
、LD_PRELOAD トリック:
/*
* File: no_trunc.c
* Author: D.J. Capelis with minor changes by Zak Wilcox
*
* Compile:
* gcc -fPIC -c -o no_trunc.o no_trunc.c
* gcc -shared -o no_trunc.so no_trunc.o -ldl
*
* Use:
* LD_PRELOAD="./no_trunc.so" cp --archive --attributes-only <src...> <dest>
*/
#define _GNU_SOURCE
#include <dlfcn.h>
#define _FCNTL_H
#include <bits/fcntl.h>
extern int errorno;
int (*_open)(const char *pathname, int flags, ...);
int (*_open64)(const char *pathname, int flags, ...);
int open(const char *pathname, int flags, mode_t mode) {
_open = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open");
flags &= ~(O_TRUNC);
return _open(pathname, flags, mode);
}
int open64(const char *pathname, int flags, mode_t mode) {
_open64 = (int (*)(const char *pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64");
flags &= ~(O_TRUNC);
return _open64(pathname, flags, mode);
}
答え4
ローカル転送では、ソースと宛先がローカルにマウントされたファイルシステム上にある場合、rsync
常にファイルの内容全体がコピーされます。これを回避するには、
rsync -a --no-whole-file source dest