Oracle Cloud Infrastructureブロック・ボリューム・バックアップDeep Dive

この記事は[**「Oracle Cloud Infrastructure Advent Calendar 2019」**](https://adventar.org/calendars/4516)の12月22日の記事として書かれています。

# 1. はじめに

Oracle Cloud Infrastructure Computeでバックアップ／リカバリしたことがあるだろうか？　とくに本番システムでは重要なのに、紹介している記事があまり見当たらない。あっても、マニュアルと大差ないものが多いように感じる。

そこで今回は、Oracle Cloud Infrastructure Computeにおけるバックアップ／リカバリ方法について書いてみようと思う。なお、内部構造は公開されていないので、一部推測で書いている。また、Oracleデータベースのバックアップは複雑なので今回は触れない。

### 1-1. TL;DR

* バックアップは重要なのにQiitaを含め紹介記事が少ない
* オンプレミスとクラウドではバックアップ手法が異なる
* ブロック・ボリュームのバックアップ方法が複数ある
* バックアップの仕組みを理解していないと、期待したバックアップを取得できない可能性がある

### 1-2. 使用環境

* Oracle Cloud Infrastructure Compute（AWSでも通用する部分は多いはず）
* Oracle Linux 9 / CentOS 9
* Oracle Linux 8 / CentOS 8
* Oracle Linux 7 / CentOS 7
* Oracle Linux 6 / CentOS 6
* Windows Server 2016 Standard

上記以外のオペレーティングシステムでも本記事の内容は有効だ。しかし、DenseIOシェイプのLocal NVMeはバックアップ機能の対象外（ブート・ボリュームは対象）。

### 1-3. 参考情報

**日本語マニュアル**

* [ブロック・ボリューム・バックアップの概要](https://docs.cloud.oracle.com/ja-jp/iaas/Content/Block/Concepts/blockvolumebackups.htm)
* [ブート・ボリューム・バックアップの概要](https://docs.cloud.oracle.com/ja-jp/iaas/Content/Block/Concepts/bootvolumebackups.htm)

**英語マニュアル**

* [Overview of Block Volume Backups](https://docs.cloud.oracle.com/en-us/iaas/Content/Block/Concepts/blockvolumebackups.htm)
* [Overview of Boot Volume Backups](https://docs.cloud.oracle.com/en-us/iaas/Content/Block/Concepts/bootvolumebackups.htm)

**その他**

* [Compute FAQ](https://www.oracle.com/cloud/compute/faq.html)
* [Block Volume FAQ](https://www.oracle.com/cloud/storage/block-volumes-faq.html)
* [Amazon EBS black belt](https://www.slideshare.net/AmazonWebServicesJapan/20190320-aws-black-belt-online-seminar-amazon-ebs)


# 2. ブロック・ボリューム・バックアップの基本

Oracle Cloud Infrastructureのブロック・ボリュームには、AWSのEBS Snapshotに類似したバックアップ機能がある。このバックアップ機能を利用すると、簡単にストレージをバックアップできる。
![blockvol_backup07.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/20ae2f97-2097-d374-8bd1-4ac04f455c74.png)

### 2-1. バックアップ機能の特徴

おもな特徴は以下のとおり。基本的なことは、冒頭の参考情報で紹介した「Oracle Cloud Infrastructureマニュアル」や「Block Volume FAQ」を読んでもらうとして、今回は<font color="blue">**青文字**</font>の項目を説明する。

* <font color="blue">バックアップ開始時点のポイント・イン・タイム・バックアップ</font>
* <font color="blue">クラッシュ・コンシステントなバックアップなので静止点を取ることを推奨</font>
* ブート・ボリュームとブロック・ボリュームが対象
* 暗号化されてオブジェクト・ストレージに格納
* <font color="blue">フルバックアップと増分バックアップ</font>
* <font color="blue">ボリューム・グループを使用すると、複数ボリュームにわたった一貫性のあるバックアップを取得できる</font>
* バックアップは別リージョンにコピーできる
* <font color="blue">手動実行とポリシーベースの自動実行</font>
* 保存期間や世代は無制限
* <font color="blue">リストアするときは、バックアップを元に新規ボリュームとして作成</font>

# 3. ポイント・イン・タイム・バックアップを理解する

ブロック・ボリュームのバックアップは、ポイント・イン・タイムで取得される。どのような仕組みになっているのか理解することは重要だ。

### 3-1. バックアップのアーキテクチャー
下記の図はバックアップの内部アーキテクチャーを表したものだ（推測モード）。

管理コンソールやREST API等でバックアップを指示したあと、ステータスが「REQUEST_RECIEVED」になった時点のバックアップを取得できる。特定の一時点であることから**ポイント・イン・タイム**と呼ばれている。
![blockvol_backup04.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/1480ebba-7097-88ec-5285-4a3faa7aa3b2.png)
またオブジェクト・ストレージへのバックアップはバックグラウンドで実行される。[FAQ](https://www.oracle.com/cloud/storage/block-volumes-faq.html)によると、バックアップが完全に終了するまでの目安は2TBで約30分とのこと。

### 3-2. 静止点の確保
バックアップで気になるのは静止点だろう。Oracle Cloud Infrastructureでは、下図のように一時的に書き込みを禁止することで静止点を確保している。
![blockvol_backup05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/110631bc-c9b4-0c9c-c4ef-eed7bedeac94.png)
この仕組みのうまいところは、バックアップを2つのフェーズに分けることで、システムへの影響を最小限に抑えていることだ。

* **第1フェーズ**：静止点を維持してる間は物理ディスクに対する書き込みを停止
* **第2フェーズ**：静止点を取ったあとに、オブジェクト・ストレージへのバックアップを開始

<font color="red">試しに静止点を維持している間にO_DIRECTでファイルシステムに書き込んだところ、I/O待ちにならなかった。手順が悪いのか、瞬間で気付かないのか、それとも仮想サーバーなどのキャッシュが使われていたのだろうか。</font>

```
dd if=/dev/zero of=＜ファイル＞ bs=1M count=＜回数＞ ofrag=direct
```

### 3-3. スナップショット or バックアップ

Oracle Cloud Infrastructureのブロック・ボリューム・バックアップは、AWSのEBS Snapshotと、ほぼ同じ仕組みだと思われる。そしてスナップショットと聞くと「スナップショットはバックアップではない」という人もいるかもしれない。そのあたりの仕組みを説明する。

NetAppなどのストレージが持つ[「スナップショット機能」](https://www.networld.co.jp/product/netapp/pro_info/software/soft/data_protection/)は巧妙に差分情報を取っている。そのためバックアップ時間やディスク容量を劇的に削減できる。ただし差分しか持っていないので、元となるディスクが破損するとリカバリーできない。

それに対してOCIのブロック・ボリューム・バックアップは、スナップショットとバックアップ両方の利点を活用し、次のように実装していると思われる。当然推測モード。

* **第1フェーズ**：「ストレージへの書き込み禁止」と「KVMのライブスナップショット機能」でストレージレベルで静止点のあるスナップショットを短時間に作成する
* **第2フェーズ**：取得したスナップショットを元に、そのスナップショットが参照する実データをオブジェクト・ストレージへコピーする

### 3-4. まとめ

* **<font color="blue">ブロック・ボリューム・バックアップはポイント・イン・タイムで取得される</font>**
* **<font color="blue">バックアップは2つのフェーズで構成され、静止点を取ったあとは、バックグラウンドで実行される</font>**

# 4. クラッシュ・コンシステントを理解する

静止点を取っていても安心してはいけない。マニュアルにはBest Practicesとして次のように書いてある。

> Before creating a backup, you should ensure that the data is consistent: Sync the file system, unmount the file system if possible, and save your application data. Only the data on the disk will be backed up. 

可能ならば、ファイルシステムをsyncもしくはアンマウントしてデータの一貫性を確保すべきだと。

### 4-1. クラッシュ・コンシステントとは

実は、ブロック・ストレージのバックアップはクラッシュ・コンシステント（クラッシュ整合性）という状態だ。わかりやすく言い換えると**<font color="red">「電源強制切断」状態</font>**である。

このようになる理由は、バックアップ機能の仕組みに起因している。下図のような仮想サーバー環境では、ディスクイメージをバックアップしていることをゲストOSは認識できない。そのためゲストOS内で開いているファイルや変更されたキャッシュなど、メモリだけに存在するデータはバックアップに含まれない。
![blockvol_backup06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/4a64f7ee-55c0-851a-bfc6-54c4a3ff35bc.png)

### 4-2. バックアップの整合性レベル

バックアップ（スナップショット）の整合性は、おもに以下の3つのレベルがある。これを見ると、マニュアルにsyncやアンマウントと書かれている理由がわかるだろう。詳しくは下記資料を参照のこと。

<dl>
  <dt>クラッシュ・コンシステント（クラッシュ整合性）</dt>
    <dd>電源強制切断と同じ。近年のファイルシステムはジャーナリング機能があるので修復できないほどは壊れないが、一部のデータはリカバリー処理で損失する可能性がある。</dd>
  <dt>ファイルシステム・コンシステント（ファイルシステム整合性）</dt>
    <dd>ファイルシステム全体で一貫性があること。キャッシュをsyncして、メモリ上の変更がディスクに反映している状態。一般的なデータの損失はない。しかしDBなどは、つねに書き込み、独自の整合性機能を持っているので、この整合性では不十分なことがある。</dd>
  <dt>アプリケーション・コンシステント（アプリケーション整合性）</dt>
    <dd>アプリケーションの特性まで考えた一貫性。OSやアプリケーションの機能を利用した、完全に一貫性のあるバックアップ。</dd>
</dl>

**参考資料：**

* [FlashCopy(Snapshot)のお作法について(Windows編)](https://www.ibm.com/developerworks/community/blogs/951f1ead-225e-4ec9-85b9-c237894c2d57/entry/FlashCopy_Snapshot_%E3%81%AE%E3%81%8A%E4%BD%9C%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6_Windows%E7%B7%A8?lang=en)
* [仮想マシンの整合性のあるバックアップ方法](https://www.climb.co.jp/blog_veeam/veeam-backup-10345)
* [Azure VM バックアップの概要](https://docs.microsoft.com/ja-jp/azure/backup/backup-azure-vms-introduction)

実は、このあたりの機能はWindowsの[VSS（Volume Shadow Copy Service）](https://blogs.technet.microsoft.com/askcorejp/2018/08/15/aboutvss/)が優れている。簡単に一貫性のあるバックアップを取得できるだけでなく、スクリプトを組み合わせてアプリケーション・コンシステントを実現できる。

また仮想サーバー環境ならば、vSphereの**VMware Tools**やKVMの**[qemu-guest-agent](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/virtualization_deployment_and_administration_guide/sect-using_the_qemu_guest_virtual_machine_agent_protocol_cli-libvirt_commands#sect-Using_the_QEMU_guest_virtual_machine_agent_protocol_CLI-Creating_a_guest_virtual_machine_disk_backup)**を利用すると、Linuxでもファイルシステム・コンシステントを実現できる（ただしVSSほど賢くない）。しかし、Oracle Cloud Infrastructureのバックアップ機能は対応していない。AWSのEBS Snapshotも似たような状況なので問題があるのか。

### 4-3. クラッシュ・コンシステントの対策

クラッシュ・コンシステントを理解したところで対策を考えてみよう。整合性を高めるには以下の方法がある。なお、アプリケーション・コンシステントは利用しているソフトウェアに依存する。そのため、今回は考慮外にする。

1. ファイルシステムをアンマウントする
2. ファイルシステムをリードオンリーとしてリマウントする
3. `fsfreeze`や`xfs_freeze`コマンドでファイルシステムへのI/Oを停止する
4. `sync`でキャッシュの内容をディスクに書き出す
5. カーネルパラメータをチューニングする

この中で1～3は強力だが、制限事項やデメリットもある。それぞれについて説明する。なお、独断と偏見の評価は次のとおり。

| 対策 | ルート・ファイルシステム | 整合性 | 可用性※ | 備考 |
|:-:|:-:|:-:|:-:|:-:|
| アンマウント/リマウント  | 非対応 | 高い | 影響あり | 使用しているファイルがあると失敗する |
| fsfreeze/xfs_freeze  | 非対応 | 高い | 影響あり|   |
| sync  | 対応 | 完全ではない | 影響なし |   |
| カーネルパラメータ | 対応 | 気休め | 影響なし |  |

※ 「影響あり」は、ブロック・ボリューム・バックアップが静止点を取っているあいだ、ディスクI/O停止もしくはサービスを停止する必要がある。

**ブート・ボリュームの対策は？**
ブート・ボリュームは抜本的な対策ができないのと、数分前に戻るくらいの損失は許容できることも多いので、積極的に対策しない考えもある（こっちの方が多いハズ）。

どうしても高い整合性が必要ならば、ブロック・ボリュームを追加して、整合性が必要なデータを配置すべきだろう。


#### 4-3-1. アンマウント／リマウント

ファイルシステムを**アンマウント（umount）**もしくはリードオンリーで**リマウント（remount）**すると、完全に一貫性を持った状態になる。ただし、ルート・ファイルシステムは対象外で、また対象ファイルシステムを利用しているプロセスやユーザーがいると失敗する。

次のようにブロック・ボリューム`/dev/oracleoci/oraclevdb1`を`/mnt/vol01`にマウントしている環境で考える。

```shell-session
# findmnt -s
TARGET     SOURCE                                    FSTYPE OPTIONS
/          UUID=e5a0d6d8-6141-4c6d-a2f7-ebe65eb7513a xfs    defaults,_netdev,_netdev
/boot/efi  UUID=A2CF-0CCB                            vfat   defaults,uid=0,gid=0,umask=0077,shortname=winnt,_netdev
swap       UUID=ffa35d76-0947-49fe-b030-3bf270640b7a swap   defaults,_netdev,x-initrd.mount
/mnt/vol01 /dev/oracleoci/oraclevdb1                 xfs    defaults,_netdev,nofail
```

この方法を利用した手順は次のようになる。

```shell-session
# ファイルシステムをリードオンリーでリマウント
mount -o remount,ro /mnt/vol01

# ★ここでブロック・ボリューム・バックアップを取得する

# CLIのレスポンスが戻ってくる、もしくはステータスがCREATINGになったら
# ファイルシステムをリードライトでリマウント
mount -o remount,rw /mnt/vol01
```

ただし`/mnt/vol01`上のファイルをつかんでいるプロセスがあると、次のエラーでリマウントできない。

```shell-session
# mount -o remount,ro /mnt/vol01
mount: /mnt/vol01 is busy
```

このようなエラーが発生したときは`fuser`や`lsof`でプロセスを特定して対処する。`fuser`がインストールされていないときは`psmisc`パッケージをインストールしよう。

```shell-session:PID=12187のプロセスがつかんでいる
# fuser -m /mnt/vol01
/mnt/vol01:          12187
```

`umount -f`や`umount -l`を使えば強制アンマウントできる可能性はある。しかし整合性を保つことが目的なので、やらない方がいいだろう。


#### 4-3-2. fsfreeze/xfs_freeze

`fsfreeze`/`xfs_freeze`はファイルシステムのI/Oを一時停止する機能だ。ルート・ファイルシステムは対象外だが、アンマウント／リマウントとは異なり、つかんでいるプロセスに邪魔されることはない。

`fsfreeze`と`xfs_freeze`は、いずれもext3/ext4/XFSファイルシステムに対して実行可能だ。

* [RHEL7マニュアル: ストレージ管理ガイド](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html-single/storage_administration_guide/index)

```shell-session:fsfreezとxfs_freezeは同じ文法
fsfreeze -f ＜マウントポイント＞　# 書き込み停止
fsfreeze -u ＜マウントポイント＞　# 書き込み再開

xfs_freeze -f ＜マウントポイント＞　# 書き込み停止
xfs_freeze -u ＜マウントポイント＞　# 書き込み再開
```

`fsfreeze`を使ってスクリプトを組むと次のようになるだろうか。

```shell-session
# manを読むと不要っぽいが、念のためキャッシュ書き込み
sync

# ファイルシステムのI/Oを一時停止
fsfreeze -f マウントポイント

# ★ここでブロック・ボリューム・バックアップを実行

# CLIのレスポンスが戻ってくる、もしくはステータスがCREATINGになったら
# 一時停止を解除
fsfreeze -u マウントポイント
```

#### 4-3-3. カーネルパラメータのチューニング

対応策としては弱いが、ダーティーなキャッシュを減らすようにカーネルパラメータを設定する方法もある。チューニングするのは次のパラメーターだ。

| パラメータ | 説明 |
|:---|:---|
| vm.dirty_ratio | ダーティーなページの割合が指定した割合を超えると、優先度の高いフォアグラウンドでページを書き出す。デフォルトは20 |
| vm.dirty_background_ratio | ダーティーなページの割合が指定した割合を超えると、優先度の低いバックグラウンドでページを書き出す。デフォルトは10  |


* [RHEL7「パフォーマンスチューニングガイド」7.5. システムメモリー容量の設定](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/performance_tuning_guide/sect-red_hat_enterprise_linux-performance_tuning_guide-configuration_tools-configuring_system_memory_capacity)
* [RHEL6「パフォーマンスチューニングガイド」5.5. 仮想メモリのチューニング](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/performance_tuning_guide/s-memory-tunables)
* [Linuxページキャッシュの設定を変更してWrite I/Oをチューニングしたメモ](https://yomon.hatenablog.com/entry/2017/04/01/131732)

あまり小さな値に設定するとパフォーマンスに影響するが、RHEL6のマニュアルではDBワークロードに<font color="blue">「dirty_ratio=15, dirty_background_ratio=3」</font>を推奨していた。ここでは少し攻めて<font color="blue">「dirty_ratio=10, dirty_background_ratio=3」</font>にしてみよう。

1. 現在の値を確認する。

```shell-session
# sysctl -a | grep vm.dirty
vm.dirty_background_bytes = 0
vm.dirty_background_ratio = 10　★
vm.dirty_bytes = 0
vm.dirty_expire_centisecs = 3000
vm.dirty_ratio = 20 ★
vm.dirty_writeback_centisecs = 500
vm.dirtytime_expire_seconds = 43200
```

2.`/etc/sysctl.conf`に追記して有効化する。なお、Oracle Linux 7以降では`/etc/sysctl.d/99-sysctl.conf`も導入されているが、`/etc/sysctl.conf`のシンボリックリンクなので、どちらを修正しても問題ない。

```shell-session
cat << _EOL_ >> /etc/sysctl.conf
vm.dirty_ratio = 10
vm.dirty_background_ratio = 3
_EOL_

sysctl -p
```

<font color="red">**注意：tunedに気を付ける**</font>
`tuned`はLinuxのOSパラメータをチューニングするデーモンだ。`tuned`で同じパラメータを設定しているとsysctlの設定が上書きされる。

**パラメータの優先順位：**
　`ソース ＜ /etc/sysctl.confなど ＜ tuned`

* [RHEL7「パフォーマンスチューニングガイド」第3章 TUNED](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/performance_tuning_guide/chap-red_hat_enterprise_linux-performance_tuning_guide-tuned)

1. `tuned`を確認するとサービスが有効になっている。

```shell-session
# systemctl is-active tuned
active
```

2.Oracle Cloud Infrastructure Computeでは次のプロファイルが有効になっている。

```shell-session
# tuned-adm active
Current active profile: oci-rps-xps oci-busy-polling oci-cpu-power
```

3.プロファイルの設定値は`/usr/lib/tuned/*`のファイルで確認できる。いずれのプロファイルもdirty_ratioとdirty_background_ratioを使っていないので影響はない。

4.以下のように他のプロファイルでは使っていることもあるので要注意。なお、プロファイルには継承機能があるので、念のため該当の`tuned.conf`を確認したほうがいいだろう。

```shell-session
# find /usr/lib/tuned -name "*.conf" |xargs grep -e vm.dirty.*ratio
/usr/lib/tuned/latency-performance/tuned.conf:vm.dirty_ratio=10
/usr/lib/tuned/latency-performance/tuned.conf:vm.dirty_background_ratio=3
/usr/lib/tuned/throughput-performance/tuned.conf:vm.dirty_ratio = 40
/usr/lib/tuned/throughput-performance/tuned.conf:vm.dirty_background_ratio = 10
/usr/lib/tuned/virtual-guest/tuned.conf:vm.dirty_ratio = 30
/usr/lib/tuned/virtual-host/tuned.conf:vm.dirty_background_ratio = 5
```

#### 4-3-4. sync

`sync`は、キャッシュだけで変更されたブロックを強制的にディスクに書き込むコマンドだ。シングルユーザー利用でサービス／デーモン系プログラムが無いならば有効性は高い。しかし、それ以外の環境で大きな期待は禁物だ。

Windowsには無い機能だと思ったら、[Windows Internals - Sync](https://docs.microsoft.com/ja-jp/sysinternals/downloads/sync)で公開されていた。WindowsにはVSSがあるので必要性は微妙だが。

#### 4-4. まとめ

* **<font color="blue">現時点のOCIのバックアップ機能では、強制電源切断と同じクラッシュ・コンシステントな状態でバックアップされる</font>**
* **<font color="blue">クラッシュ・コンシステントでは、最新データが反映されていない可能性がある</font>**
* **<font color="blue">より整合性を高めるには、ファイルシステムのアンマウントやfsfreezeで静止点を取るなどの対策が必要になる</font>**
* **<font color="blue">データベースなど常時書き込みがあるソフトウェアでは「まったく別の手法」や「複数の手法の組み合わせ」を考える必要がある</font>** 

# 5. フルバックアップと増分バックアップ
Oracle Cloud Infrastructureのブロック・ボリューム・バックアップでは、「フルバックアップ」と「増分バックアップ」ができる。オンプレミスとは異なる挙動もあるので、十分理解する必要がある。

### 5-1. バックアップの種類と特性

ブロック・ボリュームのバックアップには**「フル」**と**「増分」**がある。それぞれの違いは次のとおり。

<dl>
  <dt>フル（Full）</dt>
    <dd>ボリュームを作成してからのすべての変更が含まれる</dd>
  <dt>増分（Incremental）</dt>
    <dd>前回のバックアップ以降の変更が含まれる</dd>
</dl>

ここで重要なことは**フルバックアップ**の<font color="blue">「ボリュームを作成してからのすべての変更」</font>という記述である。

たとえば「16TBのブート・ボリュームを作成して、40GB変更したときは、フルバックアップのサイズは40GBになる」。<font color="blue">フルバックアップでも、バックアップに必要なのは使用している領域だけだ。</font>

下図は**フルバックアップ**と**増分バックアップ**の実行例だ。フルバックアップしていなくても増分バックアップを実行できるが、そのときには同じバックアップ内容になる。
![blockvol_backup08.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/ecc89310-95a1-1d40-2f9a-aefcc06966da.png)
ブロック・ボリュームのバックアップには不思議な特性がある。下図のようにフルバックアップと増分バックアップを組み合わせたとき、「フル1」が無くなるとリカバリーできなくなるのが一般的だ。ところが「フル1」を削除しても「増分1」～「増分3」のポイントにリカバリーできる。
![blockvol_backup09.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/eb1c976b-a0dd-8315-2b47-6f9f0b1410c5.png)
[EBS black belt](https://www.slideshare.net/AmazonWebServicesJapan/20190320-aws-black-belt-online-seminar-amazon-ebs)を読むと、「フル1」を削除しても「増分1」が内部的にフルバックアップの情報を保持しているらしい。また実際にテストすると、途中の増分が無くなっても、その前後のポイントにはリカバリーできる。

### 5-2. まとめ 

* **<font color="blue">バックアップには「フル」と「増分」がある</font>**
* **<font color="blue">フルバックアップに必要なサイズは実際に使用している領域で、ブロック・ボリュームのサイズは関係しない</font>**
* **<font color="blue">増分バックアップには、前回バックアップ以降の変更が含まれる</font>**
* **<font color="blue">途中の「フル」や「増分」を削除しても、他のバックアップには影響しない</font>**

# 6. バックアップのリストア

オンプレミスのリストアでは、元の領域を上書きして戻すことが多い。それに対してクラウドでは、クラウド側に十分なディスクがあり、バックアップ手順も簡単なため、別のディスクとして作成する仕組みになっている。

### 6-1. リストアの基本

下図はリストア手順を表している。バックアップは直接利用できないので、バックアップから新規ブロック・ボリュームを作成して利用する。

![blockvol_backup10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/a23bf3bc-d2aa-04d3-a132-434d7e2d9be5.png)

#### 6-1-1. ブロック・ボリュームのリストア手順

バックアップしたボリュームを使うには、次の手順が必要になる。

1. バックアップから新規ブロック・ボリュームを作成
2. アタッチしていたブロック・ボリュームをデタッチ
3. 新しく作成したブロック・ボリュームをインスタンスにアタッチ
4. ファイルシステムをマウント
5. 古いブロック・ボリュームは不要ならば削除。障害解析などの目的で他のインスタンスにアタッチしてもOK

**リストア時の補足事項**

* リストアするときには、元のブロック・ボリュームより大きいサイズを指定できる（リストア後パーティション拡張が必要）
* リストアしたブロック・ボリュームを同じインスタンスにアタッチするときは、パーティションIDを変更する必要がある（Linuxのみ）

#### 6-1-2. ブート・ボリュームのリストア手順

ブート・ボリュームも基本的には同じ手順だ。ただしブート・ボリュームのバックアップからブロック・ボリュームを作成したときは、起動用のボリュームとして使えない。起動用のボリュームとして使うときは、バックアップから新規インスタンスを作成する。

### 6-2. 同じIDのボリュームをマウントする

リストアしたブロック・ボリュームを使うには、次のどちらかの操作が一般的だ。

* 元のブロック・ボリュームと置き換える
* 他のインスタンスにアタッチする

しかしファイルの内容を比較したいなどの理由で、元のブロック・ボリュームをマウントしたまま、リストアしたボリュームをマウントしたいことがある。Windowsならば問題ないが、Linuxではエラーが発生してマウントできない。
![blockvol05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/c4afc590-018c-ccec-81c6-83fb25343803.png)
`mount`コマンドを実行すると次のエラーメッセージが表示される。

```shell-sesson
mount: wrong fs type, bad option, bad superblock on /dev/sdc1,
       missing codepage or helper program, or other error

       In some cases useful info is found in syslog - try
       dmesg | tail or so.
```

#### 6-2-1. マウントに失敗する理由

原因は「元のボリューム」と「リストアしたボリューム」の**UUID**が同じだからだ。確認すると`sdb1`と`sdc1`が同じ**UUID**になっている。

```shell-session
# lsblk -o +UUID
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT UUID
sda      8:16   0 46.6G  0 disk
├─sda2   8:18   0    8G  0 part [SWAP]     2b8d2b93-1d28-4fe9-a756-c0d465698bfd
├─sda3   8:19   0 38.4G  0 part /          85536b94-5d7b-45a2-88b7-5ff5242aae26
└─sda1   8:17   0  200M  0 part /boot/efi  B8DB-0DE3
sdb      8:0    0  200G  0 disk
└─sdb1   8:1    0  100G  0 part /mnt/vol01 e796d24d-60b6-4273-ad2a-4f92862c82e2
sdc      8:32   0  200G  0 disk
└─sdc1   8:33   0  100G  0 part            e796d24d-60b6-4273-ad2a-4f92862c82e2
```

#### 6-2-2. UUIDを変更する

対応策は、リストアしたボリュームのUUIDを変更することだ。UUIDは`xfs_admin`もしくは`tune2fs`で変更できる。文法は以下のとおり。`uuidgen`を囲っているのはバッククォートなので注意。

```
XFSのとき
  xfs_admin -U `uuidgen`  <デバイス名>

ext3/ext4のとき
  tune2fs -U `uuidgen`  <デバイス名>
```

実際に実行すると以下のように表示される。UUIDを変更すればマウントできるようになる。

```shell-session
# xfs_admin -U `uuidgen` /dev/oracleoci/oraclevdc1
Clearing log and setting UUID
writing all SBs
new UUID = 23b63c30-a5c4-4aff-9bc1-b844bdbeb2ec
```
<font color="blue">**ヒント**</font>
<font color="blue">永続的に使用するならば前記のようにUUIDを変更したほうが好ましい。しかし暫定的に同じUUIDのボリュームをマウントする方法としては`mount -o nouuid`オプションを使用する方法もある。</font>


### 6-3. ファイルシステムのメタデータ破損を修復する

リストアしたボリュームは、通常問題なくマウントできる。しかしバックアップは「クラッシュ・コンシステント」なので、まれにファイルシステム破損でマウントできないことがある。

ファイルシステム破損でマウントできないときは修復する必要がある。次のメッセージは、XFSファイルシステムの修復が必要でマウントできないときのものだ。

```shell-session
ERROR: The filesystem has valuable metadata changes in a log which needs to
be replayed.  Mount the filesystem to replay the log, and unmount it before
re-running xfs_admin.  If you are unable to mount the filesystem, then use
the xfs_repair -L option to destroy the log and attempt a repair.
Note that destroying the log may cause corruption -- please attempt a mount
of the filesystem before doing this.
```

ファイルシステムを修復するには、XFSでは`xfs_repair`、ext3/ext4では`fsck`/`e2fsck`を使用する。文法は次のとおり。

```
XFSのとき
  xfs_repair -L  <デバイス名>

ext3/ext4のとき
  e2fsck -V <デバイス名>
```

次の画面は、実際にXFSを修復したときの出力だ。

```shell-session
# xfs_repair -L /dev/oracleoci/oraclevdd1
Phase 1 - find and verify superblock...
Phase 2 - using internal log
        - zero log...
ALERT: The filesystem has valuable metadata changes in a log which is being
destroyed because the -L option was used.
        - scan filesystem freespace and inode maps...
sb_fdblocks 26167264, counted 26175456
        - found root inode chunk
★以下省略
```

次のマニュアルはブート・ボリュームが破損したときの修復手順だが、ブロック・ボリュームでも一部の内容は流用できる。

* [Linuxベースのインスタンスの破損したブート・ボリュームのリカバリ](https://docs.oracle.com/cd/E97706_01/Content/Compute/Tasks/recoveringlinuxbootvolume.htm)
* [Windowsインスタンスの破損したブート・ボリュームのリカバリ](https://docs.oracle.com/cd/E97706_01/Content/Compute/Tasks/recoveringwindowsbootvolume.htm)

### 6-4. まとめ

* **<font color="blue">バックアップをリストアするときは、新規ブロック・ボリュームとして作成する</font>**
* **<font color="blue">ブート・ボリュームのバックアップは、新規ブロック・ボリュームとして作成できるだけでなく、新規インスタンスとしても作成できる</font>**
* **<font color="blue">バックアップはクラッシュ・コンシステントなので、リストアしたボリュームが破損してマウントできないことがある。そのときにはファイルシステムの復旧を試みる</font>**

# 7. バックアップ機能、その他もろもろ

ここでは、1つの章にするほどの文章量が無いことをいくつか紹介する。

### 7.1. クローンとの違い

Oracle Cloud Infrastructureには**クローン**というボリュームを複製する機能がある。バックアップと似ているが、用途が違うことを理解する必要がある。

マニュアルに**disk-to-disk deep copy**と書いてあるように、ボリュームの完全な複製である。他の仮想化プロダクトにおける**フル・クローン**であり、**リンク・クローン**ではない。インスタンスを複製したいときに利用する。

* [ボリュームのクローニング](https://docs.oracle.com/cd/E97706_01/Content/Block/Tasks/cloningavolume.htm)
* [Cloning a Volume](https://docs.cloud.oracle.com/en-us/iaas/Content/Block/Tasks/cloningavolume.htm)

### 7.2. カスタム・イメージ

カスタマイズしたオペレーティング・システムをテンプレート化できる**カスタム・イメージ**という機能がある（AWSのカスタムAMIに相当）。

ある程度固定化した構成のときは、バックアップではなく、カスタム・イメージで対応する方法もある。ただしカスタム・イメージの最大数は「Monthly Flex：100、PAYG：25」と限られているので、運用にマッチするか検討する必要はある（[サービス・リミットの最大値](https://docs.cloud.oracle.com/iaas/Content/General/Concepts/servicelimits.htm)）。

* [カスタム・イメージの管理](https://docs.oracle.com/cd/E97706_01/Content/Compute/Tasks/managingcustomimages.htm)
* [Managing Custom Images](https://docs.cloud.oracle.com/en-us/iaas/Content/Compute/Tasks/managingcustomimages.htm)

### 7.3. ボリューム・グループ

これまで**単一ボリューム**のバックアップにおける「ポイント・イン・タイム」と「クラッシュ・コンシステント」を説明した。しかしエンタープライズ・システムの中には、複数ボリュームにわたる一貫性を維持したいことがある。

このようなときに利用できるのが「**ボリューム・グループ**」だ。ボリューム・グループには、ブート・ボリュームとブロック・ボリュームの両方を含められるだけでなく、さらに複数インスタンスや複数コンパートメントのボリュームも含められる。

ボリューム・グループを作成すると、ボリューム・グループ単位で「ポイント・イン・タイム」で「クラッシュ・コンシステント」な**バックアップ**もしくは**クローン**を作成できる。

おもな特性は以下のとおり。少し複雑な部分もあるので、実際に挙動を確認してから使った方がよいだろう。

* 1つのボリューム・グループあたり、最大32ボリューム、最大128TBまで追加できる
* 各ボリュームが属するのは、1つのボリューム・グループに限られる
* ボリューム・グループを削除しても、グループ内のボリュームは削除されない
* ボリュームを削除するときは、属しているボリューム・グループから先に除外して、それから削除する

### 7.4. ポリシーベースのバックアップ

**ポリシーベース**のバックアップを利用すると、自動でバックアップを管理できるようになる。バックアップの作成だけでなく、削除まで自動化できるので便利だ。

また2019/11からは、実行時間や保存期間などのポリシーをカスタマイズできるようになった。

ただし**クラッシュ・コンシステント**であることは変わりないので、より高い整合性が必要なときにはスクリプト化などの検討が必要だ。

AWSやAzureでは、バックアップの前後でスクリプト呼び出しが可能なソリューションを提供している。OCIでも、今後に期待したい。

* [ポリシーベースのバックアップ](https://docs.oracle.com/cd/E97706_01/Content/Block/Tasks/schedulingvolumebackups.htm)
* [Policy-Based Backups](https://docs.cloud.oracle.com/en-us/iaas/Content/Block/Tasks/schedulingvolumebackups.htm)

### 7.5. 透過的なオブジェクト・ストレージへのアクセス

**オブジェクト・ストレージ**にアクセスするには、次の2つの条件を満たす必要がある。

* バケットが作成してあること
* バケットにアクセス権限があること

ブロック・ボリュームのバックアップは、特別なオブジェクト・ストレージ領域に格納される。そのため前記の条件を満たさなくてもバックアップ機能を利用できる。ただし、バックアップ機能を利用するIAMポリシーは必要である。

#8. ほかのバックアップ方法は？

これまでOracle Cloud Infrastructure Computeのバックアップ機能を説明してきた。しかし、他にも多くの選択肢があり、最適なバックアップには全体像の理解が欠かせない。そこで簡単に振り返ってみたい。

### 8-1. バックアップ方法の選択肢
バックアップには多くの選択肢がある。

1. <font color="blue">クラウドのバックアップ機能（ボリューム・バックアップ、クローン、カスタム・イメージ）
2. <font color="blue">[Commvault](https://www.commvault.co.jp/)や[NetBackup](https://www.veritas.com/ja/jp/protection/netbackup)、Oracle Secure Backupなどの商用バックアップソフト
3. <font color="blue">[Bacula](https://www.bacula.org/)や[Amanda](http://www.amanda.org/)
などのOSSバックアップソフト（商用版あり）
4. <font color="blue">cp/tar/cpio/rsyncなどOSコマンド

### 8-2. バックアップ方法ごとのメリット／デメリット

**クラウドの標準機能**

* <font color="blue">「手動／自動」や「フル／増分」などのバックアップが簡単にできる</font>
* <font color="blue">オブジェクト・ストレージへバックアップできる</font>
* <font color="blue">ポイント・イン・タイムなバックアップを短時間に取得できる</font>
* <font color="red">クラッシュ・コンシステントなバックアップなので、その特性を理解して使う必要がある</font>
* <font color="red">高い整合性が必要なときや複雑な要件があるときは、スクリプトやジョブなどを開発する必要がある</font>
* <font color="red">DenseIOシェイプのLocal NMVeはバックアップ機能の対象外</font>

**商用/OSSのバックアップ・ソフトウェア**

* <font color="blue">オンプレミスとクラウドのハイブリッド環境を統合的に管理できる</font>
* <font color="blue">複数リージョン／複数コンパートメントにまたがったデータを統合的にバックアップできる</font>
* <font color="blue">個別のエージェントを使用して、オペレーティング・システムやミドルウェアごとに最適なバックアップができる</font>
* <font color="blue">ファイル単位や更新されたファイルだけ、といった細かな制御ができる</font>
* <font color="blue">クラウド・ストレージに対応した製品はオブジェクト・ストレージを利用できる</font>
* <font color="red">商用製品の場合、ライセンス費やサポート費が必須になる</font>
* <font color="red">競合するマネージドサービスが将来提供される可能性がある</font>

# 9. おわりに

**Advent Calendar**掲載で1回にまとめようと思ったら、大作になってしまった。

日々コツコツと書き続けて3週間近く。画面出力を除いて10,000文字オーバー。当初は「データベースのバックアップ」や「OSSのバックアップ・ソフト」も軽く触れる予定だったけれど、完全にスタミナ切れ。タイムリーな別記事をパラで書いたしね。

「[Just Right!](https://www.justsystems.com/jp/products/justright/)」+「[TC日本語スタイルガイド](https://www.jtca.org/standardization/index.html#23)」+「[共同通信社 記者ハンドブック校正辞書 for Just Right!](https://www.justsystems.com/jp/products/justright/option.html)」にも助けられた。高かったけれど、Qiitaデビューのために買ってよかった。用字は全部従っていないけどね。

また、以前に担当していただいた編集者K氏の教えも大きい。感謝！

<font color="blue">間違っている！ タイポがある！ こんなことを書いてほしい！などあったら、気軽にコメントお願いします。</font>

# 10. まとめ

**理解するべきバックアップの特性**

* **<font color="blue">ブロック・ボリューム・バックアップはポイント・イン・タイムで取得される</font>**
* **<font color="blue">バックアップは2つのフェーズで構成され、静止点を取ったあとは、バックグラウンドで実行される</font>**
* **<font color="blue">現時点のOCIのバックアップ機能では、強制電源切断と同じクラッシュ・コンシステントな状態でバックアップされる</font>**
* **<font color="blue">クラッシュ・コンシステントでは、最新データが反映されていない可能性がある</font>**
* **<font color="blue">より整合性を高めるには、ファイルシステムのアンマウントやfsfreezeで静止点を取るなどの対策が必要になる</font>**
* **<font color="blue">ボリューム・グループを使用すると、複数ボリュームにまたがった「ポイント・イン・タイム」で「クラッシュ・コンシステント」なバックアップもしくはクローンを作成できる</font>** 
* **<font color="blue">データベースなど常時書き込みがあるソフトウェアでは「まったく別の手法」や「複数の手法の組み合わせ」を考える必要がある</font>** 

**フルバックアップ／増分バックアップ***

* **<font color="blue">バックアップには「フル」と「増分」がある</font>**
* **<font color="blue">フルバックアップに必要なサイズは実際に使用している領域で、ブロック・ボリュームのサイズは関係ない</font>**
* **<font color="blue">増分バックアップには、前回バックアップ以降の変更が含まれる</font>**
* **<font color="blue">途中の「フル」や「増分」を削除しても、他のバックアップには影響しない</font>**

**リストア**

* **<font color="blue">バックアップをリストアするときは、新規ブロック・ボリュームとして作成する</font>**
* **<font color="blue">ブート・ボリュームのバックアップは、新規ブロック・ボリュームとして作成できるだけでなく、新規インスタンスとしても作成できる</font>**
* **<font color="blue">バックアップはクラッシュ・コンシステントなので、リストアしたボリュームが破損してマウントできないことがある。そのときにはファイルシステムの復旧を試みる</font>**

**その他**

* **<font color="blue">ポリシーベースのバックアップでは、自動でバックアップを管理できる</font>**
* **<font color="blue">バックアップは「変更領域だけをオブジェクト・ストレージに保存」であるのに対し、クローンは「ブロック・ストレージへのフル・クローン」である</font>**