※ タイトルはネタです、ゴジラとはなんの関連もございません。
※ 第1~3形態は本人の努力と苦労の作業の彼方に消え去りました。
rysnc
コマンドとは
Unix/Linuxで広く利用されているファイル転送ユーティリティです。ローカル・リモートを問わず、ディレクトリ構造を保ちつつファイル同期を行えます。ファイル内の差分のみを転送するデルタ転送機能があり、帯域の有効活用が可能です。SSHなどを介したセキュアな転送や、圧縮転送、帯域制限、進捗表示などの機能を備えています。バックアップ運用や大容量データのレプリケーションに適しています。豊富なオプションと柔軟性の高さから、ファイル操作に携わるエンジニアに広く活用されています。(Claude3の回答より)
コマンドを使用した背景
- サーバーAで稼働しているWebサイトのディレクトリをまるっとサーバーBに移したい
- サイト全体の容量が100GBを超えるので、不要なディレクトリを多数排除して移したい
- 動作テストから本番切り替えの間もサーバーAは本番環境として稼働中
- 動作テストを行なった後、本番切り替えとなるため複数回の同じ作業が見込まれる
- 動作テスト中、サーバーBでは稼働させるための独自の修正を加える必要がある
今回使用したrsync
rsync -rltDvz -n --progress --partial --bwlimit=3000 --log-file=/home/user/log/rsync-`date +"%Y%m%d-%H%M"`.log --log-file-format="%o %f (%M) %l %b" --exclude='exexclude-a' --exclude='exclude/aaa' -e "ssh -p 9999 -i key-file" ssh-user@192.168.XX.XX:/srv/www/the-directory/ /srv/www/the-directory/ | tee /home/user/log/tee/rsync-tee-`date +"%Y%m%d-%H%M"`.log
オプションなどを解説
-rltDvz
-r : ディレクトリの内容も再帰的にコピーする
-l : シンボリックリンクをコピーする(リンク先そのものではなく、リンクファイルをコピー)
-t : 時間情報を保持する
-D :デバイスファイルとスペシャルファイルを転送する
-v : 詳細モード(転送状況を表示)
-z : 圧縮して転送する
-n --progress --partial
-n : 実際の転送は行わず、転送対象を確認するためのドライランモード
--progress : 進捗状況を表示する
--partial : 中断されたファイルの転送を再開できるようにする
--bwlimit=3000
転送帯域幅を3000kbpsに制限する
--log-file=/home/user/log/rsync-`date +"%Y%m%d-%H%M"`.log
--log-file-format="%o %f (%M) %l %b"
--log-file : ログファイルのパスを指定
--log-file-format : ログファイルの出力フォーマットを指定
%o : 送信元のパス
%f : 転送したファイル名
%M : ファイルの最終更新日時
%l : ファイルの長さ(バイト数)
%b : 転送したファイルのバイト数
--exclude='exclude-a' --exclude='exclude/aaa'
除外するファイル/ディレクトリのパターンを指定
-e "ssh -p 9999 -i key-file"
-e : rsyncがリモートシェルを呼び出すときのコマンドを指定
sshを使ってリモートサーバーに接続し、ポート9999、指定の秘密鍵ファイルを使用
ssh-user@192.168.XX.XX:/srv/www/the-directory/
リモートサーバーのユーザー名、IPアドレス、転送元ディレクトリのパスを指定
/srv/www/the-directory/
ローカルサーバー側の転送先ディレクトリを指定
| tee /home/user/log/tee/rsync-tee-`date +"%Y%m%d-%H%M"`.log
rsyncの標準出力をログファイルに書き出す
ハマりポイント
-
-rltDvz
の代わりに-a
を使って実行していたがサーバーAとサーバーBで所有者情報などが異なるため、2回目の実行時に所有者情報などが上書きされてしまった。 - 2回目実行する際、
-n
でDryRunした際のログから更新されるファイルを特定しバックアップを作成していたが、実際の実行ではログに出力されたファイル以外も更新され、バックアップしていないファイルも更新されてしまった - sshを使用してサーバーAに接続して実行しようとしていたが、ポートがデフォルトのポートとは違う番号に設定されていたため実行しても失敗していた。ポート番号の指定が必要なことに気づき
-e
オプションを使用して解決した。 - サーバーAは本番稼働中なので稼働に影響の出ない通信負荷を調査し、
3000kbps
と設定することで稼働に影響なく実行することができた。 - ディレクトリ指定に
/
をつけずに実行した際、指定したディレクトリまでサーバーBに作成されてしまった。/a → /a/a
という形に。