NASのバックアップ対象ディレクトリをinotifyで監視して更新されたディレクトリのみをrsyncでミラーリング

2020. 4. 21 (火) | NASのバックアップ対象ディレクトリをinotifyで監視して更新されたディレクトリのみをrsyncでミラーリング はコメントを受け付けていません
タグ: , , ,
前回書いたミラーリングと世代管理バックアップの2系統のスクリプトのうち、ミラーリングのほうのスクリプトについてパフォーマンスアップの修正を行ないました。

前回のスクリプトでは大まかな流れとしてduコマンドの結果を元に更新対象ディレクトリを絞り込んでrsyncに渡すという動作を行なっていましたが、監視対象内のサブディレクトリ数が多くなるとduコマンドの実行時間もそれなりにかかるようになるので、この部分をinotifywaitコマンドでの監視に置き換えています。

inotifywaitを使えるよう準備

inotify-toolsがインストールされていない場合inotifywaitコマンドも使えませんので、その場合はまずinotify-toolsをインストールします。

inotify-toolsをインストール(Debian系の場合)

$ sudo apt install inotify-tools

inotifywaitで監視可能な対象数はデフォルトで8192になっているかと思いますが、NAS全体を監視対象にしようとするとサブディレクトリ数も多くなり8192では不足する場合もままありますので、環境に合わせてこの設定を増やしておきます。

設定値の確認

$ cat /proc/sys/fs/inotify/max_user_watches

この設定は再起動すると初期値に戻ってしまいますので、起動時に自動で設定されるようにしておきます。
いくつか方法はありますが、私はrc.localに追記しました。

$ sudo nano /etc/rc.local

以下を追記

sysctl fs.inotify.max_user_watches=262144

以降は前回と同じ方法でmirroring.phpの実行設定をすれば完了です。

スクリプト

ディレクトリの更新監視にinotifywaitを利用してはいますが、更新があった場合に自動的にmirroring.phpが実行されるわけではなくmirroring.phpはこれまで通りcronで定期的に実行し、スクリプト内でinotifywaitのログを参照することでその間に更新のあった監視対象内のサブディレクトリを取得してrsyncに渡すという動作になっています。

ここまで書いておいて何ですが、inotifyで監視してrsyncで同期という流れはLsyncdと似たようなことをしているわけなので、人によっては素直にLsyncdを導入したほうが楽かもしれません。

NASのバックアップ対象ディレクトリをinotifyで監視して更新されたディレクトリのみをrsyncでミラーリング はコメントを受け付けていません
PC, ソフトウェア by あけび

 rsyncでNASのバックアップ(ミラーリングと世代管理バックアップ分離版)

2020. 4. 7 (火) | rsyncでNASのバックアップ(ミラーリングと世代管理バックアップ分離版) はコメントを受け付けていません

今回もまた前回と同じような内容ですが、しばらく使っていると “こうしたほうが使いやすそう” と感じる部分もいくつか見えてくるのでその都度反映させていたりします。

LinuxディストリビューションとSambaで構築したNASにネットワーク共有用とバックアップ用それぞれ独立したHDDを載せて、以下のような構成で運用しているものに対してミラーリング及び世代管理バックアップを行う前提で記述しています。

NAS用ドライブ
ルート直下に
/data/ … ネットワークドライブ用
というディレクトリを作成。
これをマウントポイント
/home/nas/
にマウントしてあり、
/home/nas/data/
をsambaで共有ディレクトリに設定することでNASのネットワークドライブとして使用。
バックアップ用ドライブ
ルート直下に
/data/ … ミラーリング用
/generation/ … 世代管理バックアップ用
というディレクトリを作成。
これをマウントポイント
/home/nas_backup/
にマウントすることで、
/home/nas_backup/data/
を/home/nas/data/のミラーリング先、
/home/nas_backup/generation/
を/home/nas_backup/data/の世代バックアップ先としています。
 

図にするとこんなイメージになります。

 

mirroring.php
NAS共有ディレクトリをバックアップ元として、バックアップ先ドライブに対してrsyncの--deleteオプションを使用したミラーリングを行うスクリプトです。

バックアップ元ディスク容量が前回実行時から変化していなければrsyncは行わず終了するようにしてありますので頻繁に実行しても極端に負荷が高くなることは無いとは思いますが、その辺りは環境に合わせて加減してください。
容量チェックはdfコマンドを使用したものでファイル名の変更や小サイズの変更などブロックサイズの変化しない更新は察知できませんので、前回実行から1時間以上経過していたらバックアップ元ディスク容量が変化していなくてもrsyncを実行するようにしています。

主な設定項目
// ミラーリング元ディレクトリ
define(‘SOURCE_DIR’, ‘/home/nas/data/’);

ミラーリング元となるディレクトリを指定。

// ミラーリング先ディレクトリ
define(‘BACKUP_DIR’, ‘/home/nas_backup/data/’);

ミラーリング先となるディレクトリを指定。
こちらは先頭に「ユーザーアカウント@ホスト名:」等を含めたリモートでの指定も可能ですが、cronでの自動実行時にはリモートへのログイン時にパスワード入力待ちが発生しないようパスワード無しでの鍵認証ログインができるよう適宜設定しておく必要があります。

 

generation.php
ミラーリングされたディレクトリを元に、世代管理用ディレクトリに対してrsyncの--link-destオプションを使用したバックアップを行うスクリプトです。
バックアップ用ドライブがNAS本体とは別のリモートにある場合はこのスクリプトもリモート側へ設置します。

実行日時を名前としたディレクトリを作成し、その中にその時点のバックアップを残していきます。
rsyncの–link-destオプションを使うことで新規追加や変化のあったファイルのみが実体として保存され、それ以外のファイルはハードリンクが追加されるだけですので、ディスク容量消費や処理時間は増分バックアップと同程度でありながら作成されるバックアップはそれぞれがフルバックアップ相当になるという特徴があります。
1日以上経過したバックアップはその日の最終版のみ残して削除、1か月以上経過したバックアップはその月の最終版を残して削除、THRESHOLDで指定したディスク使用量に達した場合は下回るまで古いバックアップから削除といった処理もこちらのスクリプトで行なっています。

ハードリンクを有効に活用するため–link-destには1世代前のバックアップを指定するのが一般的ですが、今回の場合$sourceDir自身が既にミラーリングされたバックアップの一部なのでこちらを–link-destに指定しています。
こうすることで、容量の節約と同時に処理速度の短縮も図れます。

主な設定項目
// バックアップ元ディレクトリ
define(‘SOURCE_DIR’, ‘/home/nas_backup/data/’);

mirroring.phpでミラーリング先となったディレクトリを指定します。

// バックアップ先ディレクトリ
define(‘BACKUP_DIR’, ‘/home/nas_backup/generation/’);

世代管理バックアップ保存先を指定します。
このディレクトリの下に
YYYY-MM-DD_HHMM
形式でディレクトリが作成され、その中に各世代のバックアップが保存されていきます。
rsyncの--link-destオプションを使用し変更のないファイルは実体ではなくハードリンクが作成されますので、必要以上にディスク容量を消費しません。

// バックアップ世代数
define(‘BACKUP_GENERATION’, 200);

保存したい世代数を指定します。
世代バックアップ数がこの値を超えたら古いバックアップから削除されますが、間引き処理やディスク容量による削除処理の兼ね合いで、ここで指定した数に達する前に削除が行なわれる場合もあります。

// 古いバックアップを削除するディスク容量閾値(%)
// 0の場合はディスク容量のチェックは行いません
define(‘THRESHOLD’, 95);

dfコマンドでバックアップ先のディスク使用量(%)をチェックし、この値に達していたら値を下回るまで古いバックアップから順に削除を行います。
0では削除処理を行わなくなりますが、バックアップ先の空き容量が無くてもrsyncの実行を抑制する等の処理は行いません。

crontab設定例

# rsync mirroring
* * * * * php /スクリプト設置パス/mirroring.php &> /dev/null
* * * * * sleep 30; php /スクリプト設置パス/mirroring.php &> /dev/null
# rsync generation backup
0 */6 * * * php /スクリプト設置パス/generation.php &> /dev/null

上記の例では前半ブロックで30秒ごとのミラーリングを、後半ブロックで6時間ごとに世代管理バックアップを行なっています。

rsyncでNASのバックアップ(ミラーリングと世代管理バックアップ分離版) はコメントを受け付けていません
PC, ソフトウェア by あけび

 rsyncで世代バックアップ及びミラーリング

2020. 3. 30 (月) | rsyncで世代バックアップ及びミラーリング はコメントを受け付けていません

rsyncで世代バックアップやミラーリングを行うためのPHPスクリプトです。
こちらで作成したものと基本的に同内容ですが、各処理ごとに分けていたスクリプトを個人的に扱いやすいよう1つにまとめたものです。

■スクリプト

backup.php

backup_config.php

■backup_config.phpの設定

 // バックアップ元ディレクトリ
 define(‘SOURCE_DIR’, ‘/mnt/nas/’);

バックアップ元のディレクトリをフルパスで指定します。
リモートには非対応です。

 // バックアップ先ディレクトリ
 define(‘BACKUP_DIR’, ‘/mnt/nas_backup/’);

バックアップ元のディレクトリをフルパスで指定します。
リモートには非対応です。
このディレクトリ以下に、バックアップ日時を名前としたサブディレクトリとともにバックアップが行なわれます。

 // バックアップ世代数
 define(‘BACKUP_GENERATION’, 200);

世代バックアップを行いたい場合、残したい世代数を2以上の値を指定します。
1以下にすると世代バックアップはせずに最新のバックアップに対するミラーリングとなります。
後述するバックアップ先容量監視での削除や間引き処理もありますので、この世代数に達していなくても削除が行なわれる場合があります。

間引き処理は以下のものがあります。
1日以上経過したバックアップはその日の最終のもののみ残し、それ以外を削除
1か月以上経過したバックアップはその月の最終のもののみ残し、それ以外を削除

 // 世代バックアップ間隔(分)
 // 0の場合は1日間隔
 define(‘GENERATION_BACKUP_INTERVAL’, 360);

世代バックアップを行う間隔を分単位で指定します。
360で6時間間隔、720で12時間間隔になります。

 // ミラーリング時にバックアップ先となったディレクトリ名の更新(0:更新しない 1:更新する)
 define(‘MIRRORING_DIR_NAME_UPDATE’, 0);

ミラーリング時は既に存在する最新のバックアップに対してミラーリングを行いますが、ミラーリング先としたディレクトリ名を処理完了日時に合わせて変更するかを指定します。

 // 古いバックアップを削除するディスク容量閾値(%)
 // 0の場合はディスク容量のチェックは行いません
 define(‘THRESHOLD’, 95);

バックアップ先のディスクに対して古いバックアップの削除を開始する容量の閾値を%で指定します。
指定した値に達したら、それを下回るまで古いバックアップから順に削除されます。

■設置と実行スケジューリング

backup.phpとbackup_config.phpを同一ディレクトリへ保存し、crontabにて以下の設定を行います。

 * * * * * php /スクリプト設置パス/backup.php &> /dev/null

上記の例では毎分ごとにスクリプトが実行されます。
バックアップ元のディスク使用量に変化が無ければ処理を行わず終了し、排他処理も行い同一プロセスが複数同時に走らないようにもしていますので必要以上の負担はかからないかと思いますが、気になるようでしたら実行間隔を広げてください。
逆に、もっと間隔を短くしたい場合は以下のような指定方法もあります。

 * * * * * php /スクリプト設置パス/backup.php &> /dev/null
 * * * * * sleep 30; php /スクリプト設置パス/backup.php &> /dev/null

上記の例では毎分0秒と30秒に処理が実行されます。

実行した時の挙動は初回はフルバックアップ、GENERATION_BACKUP_INTERVAL で指定した間隔ごとに世代バックアップ、それ以外は最新バックアップに対するミラーリングとなります。

rsyncで世代バックアップ及びミラーリング はコメントを受け付けていません
PC, ソフトウェア by あけび

 rsyncでの–link-destオプション使用時の挙動概要

2020. 2. 24 (月) | rsyncでの–link-destオプション使用時の挙動概要 はコメントを受け付けていません

rsyncで--link-destオプションを使って差分履歴バックアップを取るときの挙動概要
バックアップ元(sourceディレクトリ内)にfile1~3のファイルがあるものとします。

1回目のバックアップを取ってみます。
(各パスは実際には正確に指定するものとします)

rsync -va --link-dest=../dest ./source/ ./backup1
初回バックアップ
backup1

file1
file2
file3

すべてのファイルがバックアップされます。
--link-destオプションにdestディレクトリを指定していますが、存在しないディレクトリなので無視されます。

バックアップ元のファイルを一切更新せず、1回目のバックアップをlink-destの対象として2回目のバックアップを取ってみます。

rsync -va --link-dest=../backup1 ./source/ ./backup2
バックアップ2回目
backup1

file1
file2
file3

backup2

バックアップ元のファイルは更新されていないので(backup1の中の各ファイルと同一)、全てのファイルに対してハードリンクのみが作成されます。
ハードリンクはファイルパス(ディレクトリエントリ)は複数存在しますがファイルの実体とiノードは同一のものを指している状態になります。
例えとして適切かは分かりませんが、電車のドア(ディレクトリエントリ)が複数あっても車内(iノード、実体)は同一と考えると分かりやすいかもしれません。
この状態で例えば backup1/file1 を書き換えると、backup2/file1 も同じiノードを指しているため backup2/file1 の内容も同じように変わりますが、backup1/file1 を削除しても backup1/file1 のディレクトリエントリが削除されるのみで、backup2/file1 は残ります。

バックアップ元のfile1を更新してから、2回目のバックアップをlink-destの対象として3回目のバックアップを取ってみます。

echo test >> ./source/file1
rsync -va --link-dest=../backup2 ./source/ ./backup3
バックアップ3回目
backup1

file1
file2
file3

backup2
backup3

file1(new)

バックアップ元のfile1が更新されているのでfile1のみ新たな実体ファイルとしてコピーされ、残りのファイルは引き続きハードリンクのみが作成されます。
「file1(new)」と書いていますが内容が更新されているという意味で、ファイル名に「(new)」が付加されているということではありません。

バックアップ元からfile2を削除、新たにfile4を作成したあとで、3回目のバックアップをlink-destの対象として4回目のバックアップを取ってみます。

rm ./source/file2
touch ./source/file4
rsync -va --link-dest=../backup3 ./source/ ./backup4
バックアップ4回目
backup1

file1
file2
file3

backup2
backup3

file1(new)

backup4

file4

file2は作成されず、3回目のバックアップには無かったfile4がバックアップ元からコピーされ、残りのファイルはハードリンクのみが作成されます。

ここで、1回目のバックアップを削除してみます。

1回目のバックアップ削除
rm -r ./backup1
backup2

file1
file2
file3

backup3

file1(new)

backup4

file4

backup1にあったfile1~3のハードリンクは削除されましたが、他のbackupディレクトリのファイルはこれまで通り残っています。

3回目のバックアップを削除してみます。

rm -r ./backup3
3回目のバックアップ削除
backup2

file1
file2
file3

backup4

file1(new)
file4

backup3のfile1(new)、file2、file3のハードリンクが削除されました。
他のbackupディレクトリのファイルはこれまで通り残っています。

2回目のバックアップを削除してみます。

rm -r ./backup2
2回目のバックアップ削除
backup4

file1(new)
file3
file4

backup2内のfile1、file2の実体と、file3のハードリンクが削除されました。
backup4ディレクトリのファイルはこれまで通り残っています。

バックアップ元のfile3を更新して、4回目のバックアップをlink-destの対象として5回目のバックアップを取ってみます。

echo test >> ./source/file3
rsync -va --link-dest=../backup4 ./source/ ./backup5
バックアップ5回目
backup4

file1(new)
file3
file4

backup5

file3(new)

file1(new)とfile4はハードリンクが作成され、file3(new)が新たにコピーされました。

これらの動作から、一番古いバックアップを削除し、最新のバックアップをlink-destの対象としてrsyncでバックアップすることで、上手い具合にローテーションさせつつ差分履歴バックアップが取れることがわかります。
ハードリンクの特徴をうまく利用した機能だと思います。

rsyncでの–link-destオプション使用時の挙動概要 はコメントを受け付けていません
internet, ソフトウェア by あけび

 XubuntuとSambaでのNAS構築メモ

2020. 2. 22 (土) | XubuntuとSambaでのNAS構築メモ はコメントを受け付けていません

Xubuntuのインストールまでは済んでいる前提です。

Xubuntu側ターミナルエミュレーターでの操作

・リモートアクセス時にわかりやすいようホスト名を変更(ここでは xubuntu-nas とします)
$ sudo nano /etc/hostname
1行だけホスト名が書かれているので xubuntu-nas に変更して保存

・SSHインストール
$ sudo apt install ssh

・再起動
$ sudo reboot

**** 再起動後 ****

WindowsPCからリモートで操作する場合はコマンドプロンプトから
> ssh Xubuntuユーザー名@xubuntu-nas
あるいは
> ssh Xubuntuユーザー名@xubuntu-nas.local
とすればパスワード入力後リモートでアクセスできます。
駄目だったら、Xubuntu側のコンソールで
$ ip a

$ ifconfig
でIPアドレスを確認して
> ssh Xubuntuユーザー名@IPアドレス
でアクセス。

・nas用共有ディレクトリ作成(ここでは /home/nas とします)
$ sudo mkdir /home/nas

・作成したディレクトリのパーミッションを変更
$ sudo chmod 0777 /home/nas

・Sambaインストール
$ sudo apt install samba

・NAS用ユーザーを作成(ここでは nasuser とします。Xubuntuの管理者ユーザー名を使う場合は不要)
$ sudo adduser nasuser
パスワードを聞いてくるので決める(2回目は確認)
ユーザー情報は全て未入力で[ENTER]でOK

・Samba用ユーザーを作成(ここでは nasuser とします。Xubuntuの管理者ユーザー名を流用する場合は同名で作成)
$ sudo pdbedit -a nasuser
パスワードを聞いてくるので決める(2回目は確認)

・smb.confを編集
$ sudo nano /etc/samba/smb.conf

行末に以下を追加

・Samba再起動
$ sudo systemctl restart smbd nmbd

********

Windows側操作

・PC(マイコンピュータ)アイコンを右クリック、「ネットワークドライブの割り当て」を選択
ドライブ: 空いている好きなドライブレターを選択
フォルダー: \\XUBUNTU-NAS\nas (参照ボタンから辿っても可)
「サインイン時に再接続する」にチェックして[完了]ボタン

「ネットワーク資格情報の入力」ダイアログが出たら、
ユーザー名: nasuser
パスワード: Samba用ユーザー作成時に決定したパスワード
を入力。
(Windowsのユーザー名、パスワードと一致している場合は出ません)

エクスプローラが表示されたらファイルやフォルダの読み書きができるか確認。
コピー、作成、編集、削除などできれば完了。

Windows側で作成したファイルをXubuntu側で見ると、ファイルの所有者が nasuser になっていると思います。
これをXubuntuの管理者ユーザを所有者としたい場合は、Samba用ユーザを管理者ユーザと同名で作成して smb.conf の valid users にそのユーザー名を指定すれば大丈夫です。
(「ネットワークドライブの割り当て」で別ユーザー名で割り当てたドライブ名が残っている場合は「ネットワークドライブの切断」で一旦切断してあらためて接続し直す必要があります)

********

USBハードディスク等、外付けドライブをNASのシェア対象にしたい場合

Xubuntu(Ubuntu)の場合はNTFSも読み書きできるようですが、ここではXubuntuでもデフォルトで使われているext4にしてみます。

まずUSBドライブを接続します。
接続すると大抵自動的に /media/ユーザー名/ 以下にマウントされますので、それを頼りにdfコマンドでデバイス名を調べます。
$ df
該当する位置にマウントされているデバイス名を控えておきます。
例: /dev/sdb1
環境によって変動しますので実際に確認してください。

マウントされていないようだったら、blkidコマンドで調べてください。
$ sudo blkid

・アンマウントします
$ sudo umount /dev/sdb1

・mkfsコマンドでラベル「USB-HDD」を付けてext4にフォーマット
$ sudo mkfs -t ext4 -L USB-HDD /dev/sdb1

・フォーマット完了したUSBドライブのUUIDを調べます
$ sudo blkid
フォーマット時に付けたラベルが LABEL=”USB-HDD” のように表示されていますので、そのデバイスのUUIDを控えておきます。
例: 89999481-ced4-480b-9e5f-20278bf543db

・外付けドライブ用のマウントポイントを作成します。
ここでは「/home/usb1」としておきます。

ディレクトリ作成
$ sudo mkdir /home/usb1

パーミッション変更
$ sudo chmod 0777 /home/usb1

・/etc/fstabに追記
$ sudo nano /etc/fstab

最終行に以下を追記します。
UUID=控えておいたUUID マウントポイント ファイルシステム nofail,noatime 0 0

/etc/fstab に書き込んでおくと再起動時やmount -aコマンド実行時に、指定されたマウントポイントにマウントされます。
取り外されることもあるデバイスですのでnofailを指定しています。
nofailではデバイスが見つかればマウントし、見つからなければその時点では無視されますが、無視された場合でも該当デバイスが接続されたタイミングでマウントされます。
noatimeはファイルを読み込むたびにアクセス日時のタイムスタンプが更新されるのを無効にします。

・再マウント
$ sudo mount -a

・マウントされたか確認
$ df

・マウントされたのを確認したら再度パーミッション変更(マウントポイントではなく外付けHDD側のパーミッション変更になります)
$ sudo chmod 0777 /home/usb1

・smb.confを編集
$ sudo nano /etc/samba/smb.conf

行末に以下を追加

・Samba再起動
$ sudo systemctl restart smbd nmbd

以降、同じようにWindows側からネットワークドライブとしてアクセスできます。

・PC(マイコンピュータ)アイコンを右クリック、「ネットワークドライブの割り当て」を選択
ドライブ: 空いている好きなドライブレターを選択
フォルダー: \\XUBUNTU-NAS\nas-usb
「サインイン時に再接続する」にチェック

NASとして使用しているPCでブート順位がUSBドライブ優先になっていると、USBドライブを繋いだまま再起動させた場合システムが立ち上がらない場合もありますので起動優先順位を変更しておいてください。

ここに記載した内容をもとに、システム(内蔵ドライブ)、データ(外付けドライブ)、バックアップ(外付けドライブ)と分けて構築し直した際の記事をnoteへ書いています。

XubuntuとSambaでのNAS構築メモ はコメントを受け付けていません
PC by あけび