[OCI] 定期的にMySQL DBシステムのmysqldumpを取得して別リージョンのObject Storageに保管してみた

# はじめに
OCIのMySQL DSには便利な自動バックアップの機能がありますが、バックアップを別のリージョンに転送することができません。（2020年10月現在）

そこで、ComputeインスタンスにMySQL ClientとOCI CLIをインストールし、自動的に毎日mysqldumpで取得したダンプファイルを別のリージョンのObject Storageに転送する簡易DR構成を構築してみました。

# 作業の流れ
1. オブジェクト・ライフサイクル・ポリシーを利用するためのポリシー設定
2. オブジェクト・ストレージ・バケットの作成
3. ライフサイクル・ポリシーの作成
4. Computeインスタンスの作成
5. タイムゾーン/ロケールの設定
6. MySQLクライアントのインストールと設定
7. OCI CLIのインストールと設定
8. シェルスクリプトの作成
9. crontabへの登録

# 1. オブジェクト・ライフサイクル・ポリシーを利用するためのポリシー設定
オブジェクト・ライフサイクル・ポリシーを利用するためには、以下のようなポリシーをrootコンパートメントに割り当てる必要があります。

```
Allow service objectstorage-<region_identifier> to manage object-family in compartment <compartment_name>
Allow service objectstorage-<region_identifier> to manage object-family in tenancy
```
例えば、Osakaリージョンでテナント全体でオブジェクト・ライフサイクル・ポリシーを利用する場合は、以下のようなポリシー・ステートメントになります。

```
Allow service objectstorage-ap-osaka-1 to manage object-family in tenancy
```

以下の手順で、ポリシーをrootコンパートメントに割り当てます。

*「コンソールメニュー」　→ 「アイデンディディ」　→ 「ポリシー」*

「**ポリシーの作成**」をクリック
　名前：**ObjectStoragePolicy**
　説明：**Policy for Object Life Cycle Policy in Osaka**
　コンパートメント：**root（ルート）**
　ポリシービルダー：
　　**「カスタマイズ」をクリック**
　　　以下を入力
　　　**Allow service objectstorage-ap-osaka-1 to manage object-family in tenancy**
　「**作成」をクリック**

# 2. オブジェクト・ストレージ・バケットの作成
以下の手順で、dumpファイル保存用のバケットを作成します。
*「コンソールメニュー」　→ 「オブジェクト・ストレージ」　→ 「オブジェクト・ストレージ」*

**「バケットの作成」をクリック**
　バケット名：**MySQLdump**
　ストレージ層：**「標準」を選択**
　オブジェクト・イベントの出力：**チェックをオン**
　暗号化：**「ORACLE管理キーを使用した暗号化」を選択**
　**「バケットの作成」をクリック**

# 3. ライフサイクル・ポリシーの作成
以下の手順で、オブジェクト・ストレージ・バケットのライフサイクル・ポリシーを作成します。
こちらの例では、バケット内に作成されたオブジェクトは8日後にアーカイブされ、30日後に削除されるポリシーを設定しています。

*「コンソールメニュー」　→ 「オブジェクト・ストレージ」　→ 「オブジェクト・ストレージ」*

**バケット名「MySQLdump」をクリック**
左下のリソース欄の「**ライフサイクル・ポリシー・ルール」をクリック**
**「ルールの作成」をクリック**
　名前：**Archive Rule for Backup**
　ターゲット：**「オブジェクト」を選択**
　ライフサイクル・アクション：**「アーカイブ」を選択**
　日数：**8**
　**「作成」をクリック**
**「ルールの作成」をクリック**
　名前：**Delete Rule for Backup**
　ターゲット：**「オブジェクト」を選択**
　ライフサイクル・アクション：**「削除」を選択**
　日数：**30**
　**「作成」をクリック**

# 4. Computeインスタンスの作成

こちらの記事のネットワーク構成を前提とします。

[OCIのネットワークを構成する際に手戻りの少ない手順を考えてみる（初心者向け）](https://qiita.com/500InternalServerError/items/ce8aaf7d1c249126d345)

*「コンソールメニュー」　→　「コンピュート」　→ 「インスタンス」*

**「インスタンスの作成」をクリック**
　・名前：**AP1**
　・コンパートメントに作成：任意のコンパートメントを選択

　・配置とハードウェアの構成
　　・可用性ドメイン：任意のADを選択
　　・イメージ：**「Oracle Linux 7.8」を選択**
　　・シェイプ：任意のシェイプを選択

　・ネットワーキングの構成　
　　・ネットワーク：**「既存の仮想クラウド・ネットワークを選択」を選択し、「VCN1」を選択**
　　・サブネット：**「既存のサブネット」を選択し、「Subnet 1」を選択**
　　・ネットワーク・セキュリティ・グループを使用してトラフィックを制御：**チェックをオン**
　　・ネットワーク・セキュリティ・グループ：**「Network Security Group for AP」を選択**
　　・パブリックIPアドレス：**「パブリックIPアドレスの割当て」を選択**
　
　SSHキーの追加
　・**「公開キー・ファイルの選択」を選択し、「または場所を参照します」をクリックして公開キー・ファイルをアップロードします**
　
　ブートボリュームの構成
　・全てデフォルトのまま

 ・**「作成」をクリック**

# 5. タイムゾーン/ロケールの設定

```
sudo timedatectl set-timezone Asia/Tokyo
sudo localectl set-locale LANG=ja_JP.utf8
```

# 6. MySQLクライアントのインストールと設定

```
sudo yum install -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
sudo yum install -y mysql-community-client
```
MySQLクライアントの設定（接続情報）ファイルを作成します。
ここでは、MySQL DBシステムの接続情報が以下であると仮定します。

|||
|:---|:---:|
|ホスト名|mysql1.subnet2.vcn1.oraclevcn.com|
|ユーザ名|admin|
|パスワード|Demo#1Demo#1|

```
vi .my.cnf
```
```/home/opc/.my.cnf
[client]
user=admin
password="Demo#1Demo#1"
host="mysql1.subnet2.vcn1.oraclevcn.com"
```

# 7. OCI CLIのインストールと設定
こちらのドキュメントを参考に、 OCI CLIをインストールします。
[Oracle Cloud Infrastructure ドキュメント：コマンドライン・インタフェース クイックスタート](https://docs.cloud.oracle.com/ja-jp/iaas/Content/API/SDKDocs/cliinstall.htm#PromptsInstall)

# 8. cron実行用のシェルスクリプトの作成
mysqldumpの出力先となるdumpディレクトリを作成し、そこにcron実行用のシェルスクリプトを作成します。

```
mkdir dump
vi /home/opc/dump/daily_dump.sh
```
```/home/opc/dump/daily_dump.sh
echo 
echo "START:"`date`
FILE="/home/opc/dump/dump"`date "+%Y%m%d_%H%M%S"`".dmp"

echo "Filename:"$FILE
mysqldump --set-gtid-purged=OFF testdb > $FILE
echo "mysqldump to" $FILE "finished successfully."

/home/opc/bin/oci os object put -ns nrhnlrqdttaw -bn MySQLdump --file $FILE
echo $FILE "was uploaded to Object Storage successfully."

rm $FILE
echo $FILE "was deleted successfully."
echo "END:"`date`
```
作成したシェルスクリプトのパーミッションを変更します。

```
chmod +x /home/opc/dump/daily_dump.sh
```

作成したシェルスクリプトをcrontabに登録します。
以下の例では、5分毎にスクリプトを実行します。

```
crontab -e
```
```php:crontab
*/5 * * * * /home/opc/dump/daily_dump.sh >> /tmp/daily_dump.log 2>&1
```

正常実行時のログファイルの内容は以下のようになります。

```/tmp/daily_dump.log
START:Tue Oct 27 23:10:01 JST 2020
Filename:/home/opc/dump/dump20201027_231001.dmp
mysqldump to /home/opc/dump/dump20201027_231001.dmp finished successfully.
Uploading object
{
  "etag": "a2a48c0f-e93f-4a8d-9f5b-aa5f472b8b7a",
  "last-modified": "Tue, 27 Oct 2020 14:10:08 GMT",
  "opc-content-md5": "rYFQSKQvKu1a9S55Zt4+Sg=="
}
/home/opc/dump/dump20201027_231001.dmp was uploaded to Object Storage successfully.
/home/opc/dump/dump20201027_231001.dmp was deleted successfully.
END:Tue Oct 27 23:10:09 JST 2020

START:Tue Oct 27 23:15:01 JST 2020
Filename:/home/opc/dump/dump20201027_231501.dmp
mysqldump to /home/opc/dump/dump20201027_231501.dmp finished successfully.
Uploading object
{
  "etag": "44389267-d657-4bf2-97c2-c137f723115b",
  "last-modified": "Tue, 27 Oct 2020 14:15:08 GMT",
  "opc-content-md5": "G5aa3pt9yybDKfDnveyy2w=="
}
/home/opc/dump/dump20201027_231501.dmp was uploaded to Object Storage successfully.
/home/opc/dump/dump20201027_231501.dmp was deleted successfully.
END:Tue Oct 27 23:15:09 JST 2020
                                .
                                .
                                .
```

コンソールから正常にdmpファイルがオブジェクト・ストレージに保存されていることを確認します。
![スクリーンショット 2020-10-27 23.41.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/f19c95d4-1e50-ebdb-b8ec-53dcf7385af2.png)