RHEL7ストレージ管理ガイドのP.129 参照

・バックアップ取得前にプリスナップショット、取得後にポストスナップショットをペアで取得するすることによって、あとで下記のコマンドを実行することによってスナップショットペアの変更を追跡できるようになる。

 snapper status:2 つのスナップショットの間で作成、編集、または削除されたファイルおよび            ディレクトリ一覧を表示

 snapper diff:1 つ以上の変更が検出された場合に status コマンドが出力する 2 つのスナ

         ップ ショットの間に変更されたファイルおよびディレクトリーの差異を表示

 snapper dadiff:2 つのスナップショットの間にファイルまたはディレクトリーの拡張属性がど

          のように変更されたかを比較

・スケジューリングして日時とか1時間あととかに実行できる。

 

 

使い方

# snapper -c lvm_config create-config -f "lvm(xfs)" /lvm_mount

※/lvm_mount でマウントされている LVM2 サブボリューム上に xfs ファイルシステ ムで 

lvm_config という設定ファイルを作成する場合

 

・プリスナップショット取得

# snapper -c SnapperExample create -t pre -p

 

・ポストスナップショット取得

# snapper -c lvm_config create -t post --pre-num 1 -p

 

 

■nfsサーバがexportしてるファイルシステムへのクライアントからの書き込みが完了するのを待ってファイルシステムの書き込みをロックする方法

【要件】

nfsクライアントが書き込み中のデータは書き込みが完了するまで待ってから、nfsクライアントによるnfsへの書き込みを停止する方法を考える

・ポイント:クライアント側にどんな応答が返るか

 

0.初期状態

server# exportfs
/testlv         192.168.0.0/16

client# mount | grep testlv
192.168.101.1:/testlv on /nfs type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.101.201,local_lock=none,addr=192.168.101.1)

client# ll /dst/hoge
-rw-r--r--. 1 root root 10485760002 Sep 23 04:26 /dst/hoge

1.exportしてるファイルシステムをnfsサーバ側でro remountする方法

nfsクライアント側で完了までに約7秒かかる書き込みジョブを開始直後にnfsサーバ側で下記コマンドを発行。(この時点ではまだexportしてるファイルシステムはread-writeでマウントしている)

server# i=1;while ! mount -o remount,ro /testlv;do echo $i;sleep 1;((i++));done;findmnt /testlv

mount: /testlv is busy
1
mount: /testlv is busy
2
mount: /testlv is busy
3
mount: /testlv is busy
4
mount: /testlv is busy
5
mount: /testlv is busy
6
mount: /testlv is busy
7

TARGET  SOURCE                 FSTYPE OPTIONS
/testlv /dev/mapper/src-testlv xfs    ro,relatime,seclabel,attr2,inode64,noquota

→クライアントから書き込み中にサーバ側でroにremountしようとするとbusyのエラーになるが、クライアントの書き込み完了後はexportしたままread-onlyにremountできる。

server# exportfs
/testlv         192.168.0.0/16

client# time su nfstest -c "touch /nfs/fuga2"
touch: cannot touch ‘/nfs/fuga2’: Read-only file system
real    0m0.159s
user    0m0.004s
sys     0m0.047s

client# echo $?
1

2.nfsサーバ側でexportfs -uでアンエクスポートする方法

client# time cp /dst/hoge /nfs/hoge2

server# ll /testlv
合計 10972696 

drwxr-xr-x. 25 root    root           4096  9月  7 04:59 1 

-rw-r--r--.  1 nfstest nfstest           2  9月 24 12:02 fuga 

-rw-r--r--.  1 root    root    10485760002  9月 18 13:40 hoge 

-rw-r--r--.  1 nfstest nfstest  1220272128  9月 24 12:11 hoge2
server# exportfs -u 192.168.0.0/16:/testlv
server# echo $?

0

server# exportfs;echo $?
0

server# ll /testlv/hoge2
-rw-r--r--. 1 nfstest nfstest 1289084928  9月 24 12:11 /testlv/hoge2
server# ll /testlv/hoge2
-rw-r--r--. 1 nfstest nfstest 1289084928  9月 24 12:11 /testlv/hoge2

----(6分間待つ)----

server# exportfs -a
server# exportfs

/testlv         192.168.0.0/16
server# ll /testlv/hoge2
-rw-r--r--. 1 nfstest nfstest 1289084928  9月 24 12:18 /testlv/hoge2
----(10秒待つ)----
server# ll /testlv/hoge2
-rw-r--r--. 1 nfstest nfstest 1313202176  9月 24 12:18 /testlv/hoge2

→書き込みが再開した

 

3.LVM論理ボリュームを非アクティブにする方法

クライアントが書き込み中にサーバ側で下記を実行

server# lvs
  LV            VG  Attr       LSize   Pool          Origin     Data%  Meta%  Move Log Cpy%Sync Convert
  home          cl  -wi-ao---- 173.87g
  root          cl  -wi-ao----  50.00g
  swap          cl  -wi-ao----   7.81g
  1TBthin_snap1 dst Vwi---tz-k   2.00t big_thinpool  dst_thinlv
  big_thinpool  dst twi-aotz--   2.44t                          40.30  20.04
  dst_thinlv    dst Vwi-a-tz--   2.00t big_thinpool             49.20
  testlv_bk     dst -wi-ao---- 200.00g
  test_thinpool src twi-aotz-- 400.00g                          18.09  26.40
  testlv        src -wi-ao---- 200.00g
  thinlv_1      src Vwi-aotz-- 200.00g test_thinpool            35.38

server# lvchange -an src/testlv
  Logical volume src/testlv contains a filesystem in use.
server# echo $?
5

 

4.LVM論理ボリュームをroに変更する方法

クライアントが書き込み中にサーバ側で下記を実行

server# lvchange -pr src/testlv

  Logical volume src/testlv changed.
server# echo $?
0

server# lvs
  LV            VG  Attr       LSize   Pool          Origin     Data%  Meta%  Move Log Cpy%Sync Convert
  home          cl  -wi-ao---- 173.87g
  root          cl  -wi-ao----  50.00g
  swap          cl  -wi-ao----   7.81g
  1TBthin_snap1 dst Vwi---tz-k   2.00t big_thinpool  dst_thinlv
  big_thinpool  dst twi-aotz--   2.44t                          40.30  20.04
  dst_thinlv    dst Vwi-a-tz--   2.00t big_thinpool             49.20
  testlv_bk     dst -wi-ao---- 200.00g
  test_thinpool src twi-aotz-- 400.00g                          18.09  26.40
  testlv        src -ri-ao---- 200.00g
  thinlv_1      src Vwi-aotz-- 200.00g test_thinpool            35.38

server# ll /testlv
合計 12997500
drwxr-xr-x. 25 root    root           4096  9月  7 04:59 1
-rw-r--r--.  1 nfstest nfstest           2  9月 24 12:02 fuga
-rw-r--r--.  1 root    root    10485760002  9月 18 13:40 hoge
-rw-r--r--.  1 nfstest nfstest  2900361216  9月 24 12:34 hoge2

server# ll /testlv
合計 13024124
drwxr-xr-x. 25 root    root           4096  9月  7 04:59 1
-rw-r--r--.  1 nfstest nfstest           2  9月 24 12:02 fuga
-rw-r--r--.  1 root    root    10485760002  9月 18 13:40 hoge
-rw-r--r--.  1 nfstest nfstest  2900361216  9月 24 12:34 hoge2

----(1分待つ)----

server# lvchange -prw src/testlv

  Logical volume src/testlv changed.
server# echo $?
0

server# lvs
  LV            VG  Attr       LSize   Pool          Origin     Data%  Meta%  Move Log Cpy%Sync Convert
  home          cl  -wi-ao---- 173.87g
  root          cl  -wi-ao----  50.00g
  swap          cl  -wi-ao----   7.81g
  1TBthin_snap1 dst Vwi---tz-k   2.00t big_thinpool  dst_thinlv
  big_thinpool  dst twi-aotz--   2.44t                          40.30  20.04
  dst_thinlv    dst Vwi-a-tz--   2.00t big_thinpool             49.20
  testlv_bk     dst -wi-ao---- 200.00g
  test_thinpool src twi-aotz-- 400.00g                          18.09  26.40
  testlv        src -wi-ao---- 200.00g
  thinlv_1      src Vwi-aotz-- 200.00g test_thinpool            35.38

server# ll /testlv
合計 13316272
drwxr-xr-x. 25 root    root           4096  9月  7 04:59 1
-rw-r--r--.  1 nfstest nfstest           2  9月 24 12:02 fuga
-rw-r--r--.  1 root    root    10485760002  9月 18 13:40 hoge
-rw-r--r--.  1 nfstest nfstest  3772776448  9月 24 12:36 hoge2

→バッファ?にたまってたデータがページキャッシュに一気に流れ込んだ?

どこのバッファやねん?

 

【わかったこと】

nfsクライアントが書き込み中にnfsサーバ側OSで実行される各IO停止(中断)を伴う(伴いそうな)コマンドを試みた結果は下記のようになった。

 

1.ro remount→exitコード32で失敗。(nfsクライアント側の書き込み完了後に成功)

2.nfsアンエクスポート→成功。クライアントは書き込みを中断

3.lvm非アクティブ化→exitコード5で失敗

4.lvmをread-onlyにステータス変更→成功。nfsサーバ側のどっかのバッファにクライアントからのデータがため込まれてlvmをread-writeステータスに戻した瞬間にバッファのデータがページキャッシュに反映された

 

よって、1.か3.を0.5秒おきにポーリングしてクライアントからの書き込みが終了したらすかさず書き込み禁止してそのすきにスナップショットを取るのがいいように思われる。

具体的には1.の場合は、

# remountを1秒おきに試みる(もし書き込み中のクライアントがあった場合はbusyエラーが返る)

while ! mount -o remount,ro /testlv;do echo $i;sleep 1;done

# ファイルシステムをフリーズ(nfsクライアントはこの間無限リトライになる)

xfs_freeze -f /testlv

mount -o remount,rw /testlv

# スナップショット取得

----スナップショット取得----

#  ファイルシステムをフリーズ解除

xfs_freeze -u/testlv

 

【課題】

​念のため、ローカルプロセスが書き込み中の場合の1.と3.の挙動も確認しておく

 

けんしょーーーーー!!!!

 

# lvextend -L 400g src/test_thinpool
  Size of logical volume src/test_thinpool_tdata changed from 200.00 GiB (51200 extents) to 400.00 GiB (102400 extents).
  Logical volume src/test_thinpool_tdata successfully resized.

# lvs
  LV            VG  Attr       LSize   Pool          Origin     Data%  Meta%  Move Log Cpy%Sync Convert
  home          cl  -wi-ao---- 173.87g
  root          cl  -wi-ao----  50.00g
  swap          cl  -wi-ao----   7.81g
  1TBthin_snap1 dst Vwi---tz-k   2.00t big_thinpool  dst_thinlv
  big_thinpool  dst twi-aotz--   2.44t                          40.30  20.04
  dst_thinlv    dst Vwi-a-tz--   2.00t big_thinpool             49.20
  testlv_bk     dst -wi-ao---- 200.00g
  test_thinpool src twi-aotz-- 400.00g                          18.09  26.40
  testlv        src -wi-ao---- 200.00g
  thinlv_1      src Vwi-aotz-- 200.00g test_thinpool            35.38
  thinlv_1_snap src Vwi---tz-k 200.00g test_thinpool thinlv_1

# mkdir /thinlv_1_snap
# lvchange -ay -K src/thinlv_1_snap
# mount -o nouuid /dev/src/thinlv_1_snap /thinlv_1_snap/
# ll /thinlv_1_snap/

合計 20480012
drwxr-xr-x. 25 root root        4096  9月 14 20:41 1
-rw-r--r--.  1 root root           4  9月 16 23:08 fuga
-rw-r--r--.  1 root root 10485760000  9月 16 05:57 hoge
-rw-r--r--.  1 root root 10485760000  9月 16 06:27 hoge2

# time rsync -auvh /thinlv_1_snap/ /testlv_bk > /tmp/hoge
real    18m59.469s
user    5m22.939s
sys     2m0.275s

# umount /thinlv_1_snap/
# lvremove src/thinlv_1_snap
Do you really want to remove active logical volume src/thinlv_1_snap? [y/n]: y
  Logical volume "thinlv_1_snap" successfully removed
# ll /thinlv_1
合計 20480012
drwxr-xr-x. 25 root root        4096  9月 14 20:41 1
-rw-r--r--.  1 root root           4  9月 16 23:08 fuga
-rw-r--r--.  1 root root 10485760000  9月 16 05:57 hoge
-rw-r--r--.  1 root root 10485760000  9月 16 06:27 hoge2

 

・ソースボリューム内の4バイトのファイルにささいな変更を加えて「おかわり差分バックアップ」を取得する。

# echo 1 >> /thinlv_1/fuga
# time rsync -auvh /thinlv_1/ /testlv_bk/        ←②バックアップ元をソースボリュームとする第1回差分バックアップ取得
sending incremental file list
fuga

sent 5.21M bytes  received 24.16K bytes  67.57K bytes/sec
total size is 65.71G  speedup is 12,548.16
real    1m17.163s
user    0m1.483s
sys     0m4.704s

# time rsync -auvh /thinlv_1/ /testlv_bk/          ←③バックアップ元をソースボリュームとする第2回差分バックアップ取得
sending incremental file list

sent 5.21M bytes  received 24.11K bytes  3.49M bytes/sec
total size is 65.71G  speedup is 12,548.43
real    0m1.109s
user    0m0.557s
sys     0m0.665s

# free -h
                total        used        free      shared  buff/cache   available
Mem:            15G        442M        7.1G        8.9M        7.9G         14G
Swap:          7.8G         48K        7.8G

→ページキャッシュにソースボリューム上のファイルが多少乗った。あえてフラッシュしない。

# umount /testlv_bk/
# mount /dev/dst/testlv_bk /testlv_bk
# ll /testlv_bk

合計 20480008
drwxr-xr-x. 25 root root        4096  9月 14 20:41 1
-rw-r--r--.  1 root root           6  9月 18 14:17 fuga
-rw-r--r--.  1 root root 10485760000  9月 16 05:57 hoge
-rw-r--r--.  1 root root 10485760000  9月 16 06:27 hoge2

# lvs
  LV            VG  Attr       LSize   Pool          Origin     Data%  Meta%  Move Log Cpy%Sync Convert
  home          cl  -wi-ao---- 173.87g
  root          cl  -wi-ao----  50.00g
  swap          cl  -wi-ao----   7.81g
  1TBthin_snap1 dst Vwi---tz-k   2.00t big_thinpool  dst_thinlv
  big_thinpool  dst twi-aotz--   2.44t                          40.30  20.04
  dst_thinlv    dst Vwi-a-tz--   2.00t big_thinpool             49.20
  testlv_bk     dst -wi-ao---- 200.00g
  test_thinpool src twi-aotz-- 400.00g                          18.09  26.40
  testlv        src -wi-ao---- 200.00g
  thinlv_1      src Vwi-aotz-- 200.00g test_thinpool            35.38

# ll /testlv_bk
合計 20480008
drwxr-xr-x. 25 root root        4096  9月 14 20:41 1
-rw-r--r--.  1 root root           6  9月 18 14:17 fuga
-rw-r--r--.  1 root root 10485760000  9月 16 05:57 hoge
-rw-r--r--.  1 root root 10485760000  9月 16 06:27 hoge2

# rm -rf /testlv_bk/*
# ll /tmp

合計 3517212
-rw-r--r--. 1 root root   15360299  9月 18 14:13 hoge
-rw-r--r--. 1 root root 3586257564  9月  7 10:36 oracle-database-ee-18c-1.0-1.x86_64.rpm
[root@localhost ~]# wc -l /tmp/hoge
208306 /tmp/hoge

# time rsync -auvh /thinlv_1/ /testlv_bk/ > /tmp/hoge2     ←①スナップショットをソースとする初回フルバックアップ取得
real    19m29.920s
user    5m24.677s
sys     1m59.071s

 

下記の3つの所要時間を比較した。

①スナップショットがソースのrsyncフルバックアップ(約62GB)

②上記のソースに含まれる6バイトのファイル一個だけを変更したソースボリュームがソースのおかわり差分バックアップ

③上記のソースに変更を加えずにソースボリュームがソースのおかわりのおかわり差分バックアップ

 

結果は、

①→19m30s

②→ 1m17s

③→1s


おかわり差分バックアップ②はフルバックアップ①の約15分の1の時間で完了した。

さらに、②の直後に行ったおかわりのおかわりバックアップ③は約1秒で完了した。

 

【考察】

スナップショットをソースとしたバックアップ直後にソースボリュームをソースとした差分バックアップはフルバックアップよりもかなり短時間で完了するが、瞬間的って言うほど速くはない。一方、おかわりバックアップを一回取った直後に、ソースボリュームをソースとしたおかわりのおかわり差分バックアップの取得時間はほぼ瞬間的に終わる。

なので、下記のような疑似静止点付きバックアップは有効と思われる。

 

【疑似静止点付きバックアップのアルゴリズム(案)】

スナップショット取得→スナップショットをソースとした初回バックアップ→スナップショットを削除→ソースボリュームをソースとした前日との差分バックアップ(rsync標準出力から前日との差分があったファイルのリストをファイルにリダイレクト。この差分リストを「差分リスト0」とする)

→差分リスト0のすべてのファイルのチェックサムを計算してファイルにリダイレクト。この出力を「チェックサムリスト0」とする

→㋐ソースボリュームをソースとした第1回差分バックアップ(rsync標準出力から初回バックアップと第1回差分バックアップで差分があったファイルのリストをファイルにリダイレクト。この差分リストを「差分リスト1」とする

→第1回差分バックアップのすべてのファイルのチェックサムを計算してファイルにリダイレクト。この出力を「チェックサムリスト1」とする

→㋑下記の判定を行う

「チェックサムリスト0とチェックサムリスト1が一致」

、かつ「差分ファイルリスト1のファイル一覧の中に差分ファイルリスト0に含まれるファイル以外のファイルが居ない」

もし、上記の判定結果が真だった場合は初回バックアップ取得後~第1回差分バックアップ取得完了までの間に更新がないとみなし、第1回差分バックアップは疑似静止点が取られているとみなす。

もし、上記の判定結果が偽だった場合は上記の㋐~㋑を判定基準が真になるまで繰り返す。(差分回数番号はインクリメントする)

 

※おかわり差分バックアップ(第i回差分バックアップ)開始直前にsyncかxfs_freezeを発行するとDirtyキャッシュがディスクに反映されるのでやった方がいいかもしれない。ただしxfs_freezeの場合はバックアップ取得中のソースボリュームへのwriteがブロックされる。

syncの場合は、バックアップ取得開始直前に実施してもその時刻のDirtyキャッシュがフラッシュされるだけでバックアップ取得時間がもし長引けばバックアップ取得時刻に書き込み中だったファイルに関しては破損する可能性がある。細かい配慮だが、iが少ないうちはsyncで差分バックアップ取得時間が短くなってから(おそらく次が最後の差分バックアップと見込まれてから)、xfs_freezeで決めるとか。

 

【オンラインファイルバックアップをLVMスナップショットを使って取得する際のアイデアのひとつ】

前日分バックアップと当日ソースとの差分が膨大だった場合、初回バックアップ所要時間が膨大になる可能性がある。この場合、スナップショットを使って初回バックアップ取得が完了する前にソースボリュームへの膨大な量の書き込みが発生した場合、スナップショットが存在していることが原因でソースボリュームへのwrite時間が遅延する可能性がある。さらに初回バックアップ取得が朝の業務開始時刻までに間に合わなかった場合、業務時間中のソースディスクへのwrite時間が遅延する可能性がある。さらに、初回バックアップ取得未完了時点では文字通りバックアップが存在していない状態なので可用性要件やバックアップ要件を一時的に違反している。(有事の際にリカバリできない!)

上記を総合して考えた場合、仮に初回バックアップ取得が完了する前に業務開始時刻に達してしまった場合でも、スナップショットが存在することにより、ディスク障害を除いた場合に限りスナップショットをバックアップの代わりにリカバリすることができる。

ソースボリュームがリニア論理ボリュームだった場合はスナップショットが存在していた場合のディスクへのwrite時間は5~10倍くらい遅延するのに対し、ソースボリュームがシンプロビジョニング論理ボリュームだった場合は2倍未満の遅延で済むので、上記のようにスナップショットをバックアップの代わりにする場合は、ソースボリュームはリニア論理ボリュームで作っておくよりシンプロビジョニング論理ボリュームで作っておいた方が有利となる。