Oracle Cloud の永久無料枠で ATP : Autonomous Transaction Processing を作ってみた

この記事は「[株式会社オープンストリーム Advent Calendar 2019](https://qiita.com/advent-calendar/2019/opst)」の9日目の記事です。

はじめまして、mkrydik と申します。最近業務で __Oracle Cloud__ をよく触っているので、今回はそんな Oracle Cloud を個人でも楽しめる初歩の初歩として、 __Autonomous Transaction Processing__ という自立型 DB を作ってみます。

# Oracle Cloud Infrastructure の永久無料枠

Oracle が提供するクラウドサービス __Oracle Cloud Infrastructure (OCI)__ は、2019年9月に「永久無料枠 (Always Free)」プランが追加されました。無料で作成できるリソースは以下のようなものがあります。

- 最大2つの Compute Instance
- 最大2つの __Autonomous Database__
- 最大1つの Load Balancer
- 最大1つの Public IP

それぞれのスペックはかなり抑えられているものの、VM と DB が2つずつ借りられるのは太っ腹です。個人でちょっとした Web アプリを公開する程度であれば事足りてしまうかもしれません。

- 参考 : [Oracle 日本 - オラクル、「Autonomous Database」と「Oracle Cloud Infrastructure」を無期限で無料提供](https://www.oracle.com/jp/corporate/pressrelease/jp20190917-5.html)

(ただ、永久無料枠の中だけでは Public IP が1つしかもらえないので、Load Balancer に Public IP を割り当てた場合は Compute Instance に Public IP を割り当てられず、SSH 接続したりするのが困難になります。一方、Compute Instance に Public IP を割り当てると、Public IP を持つ Load Balancer が作れなくなるので、2台の Compute Instance を活かした Web アプリは公開しづらくなります。実際のところ、無料枠だけでリッチなサービス稼動は難しいです)

今回取り上げる Autonomous Transaction Processing は、この内の「Autonomous Database」に当たります。

# Autonomous Transaction Processing とは

__Autonomous Transaction Processing (ATP)__ は、「自己稼働」「自己保護」「自己修復」を行える Oracle Autonomous Database の一種です。「自立型 DB」とも表現されます。インフラ管理やチューニングが自動的に行われ、可用性とセキュリティを担保するために自動的に動いてくれるそうです。表面的には普通の Oracle DB として利用でき、利用者は手動でチューニングすることなく、機械学習によって自動的に性能向上が見込めるというわけです。

- 参考 : [Speaker Deck - Autonomous Database Cloud 技術詳細](https://speakerdeck.com/oracle4engineer/autonomous-database-cloud-ji-shu-xiang-xi)
- 参考 : [マイナビニュース - オラクル、自律型DBの特徴と今後の提供機能を説明](https://news.mynavi.jp/article/20181203-734972/)

同じく自立型 DB の一つに、 __Autonomous Data Warehouse (ADW)__ というものも存在します。ATP が一般用途向けであるのに対して、ADW はデータウェアハウス向けに構成されています。

先程「最大2つの Autonomous Database」が永久無料枠で作成できる、と紹介しましたが、ATP を1台、ADW を1台、計2台を永久無料枠内で作成することも可能ですので、試しに2台作り、データの特性に応じて使い分けみても良いでしょう。

- 参考 : [コーソル DatabaseエンジニアのBlog - ADWとATPの比較 / Autonomous Databaseへの接続と事前定義サービス](http://cosol.jp/techdb/2019/04/autonomous-database-comparison-adw-and-atp-predefined-services.html)

# OCI に登録する

それでは、まずは OCI のアカウントを作成します。以下のページより、「Start for free」もしくは「今すぐ始める (無償)」ボタンを押下して、登録を開始します。

- [Oracle 日本 - Oracle Cloud無償ティア](https://www.oracle.com/jp/cloud/free/)

登録フォームの中に、「Home Region (ホーム・リージョン)」の選択画面があります。OCI の永久無料枠は、「ホーム・リージョン」に設定したリージョンでのみリソース作成が可能になります。せっかくなら日本リージョン (「Japan East (Tokyo)」) を選択し、地理的に近い日本のデータセンターの恩恵を受けたいところですが、日本リージョンの永久無料枠はかなり少ないので、「US East (Ashburn)」や「US West (Phoenix)」を選択した方が、スムーズに永久無料枠のリソースを作成できるかもしれません。永久無料枠以外を使う予定があるかどうかで考えてみましょう。

SMS 認証の他、クレジットカード情報の入力も必要ですが、無料枠に含まれる300ドル分のクレジットを使い果たした後も、ユーザが明示的にプラン切り替えを行わない限り、課金は始まらないのでご安心を。

アカウントの作成が終わり、「OCI 管理コンソール」画面に遷移できたら登録完了です。

# ATP に接続するための Compute Instance を作成する

続いて、ATP に接続するための Compute Instance (VM) を作成します。ATP を作成する前段階の話なので、今回は大幅に説明を端折りながら進めていきます。

## 1. VCN (Virtual Cloud Network) を作る

まずは __VCN__ と呼ばれる、仮想ネットワークを作ります。この後作成する Compute Instance は、VCN の中に配置します。

1. OCI 管理コンソール左上のハンバーガーメニュー → 「Networking」メニュー → 「Virtual Cloud Networks」と選択する
2. 「Create Virtual Cloud Network」ボタンを押下する
3. リソース名、CIDR Block、DNS ラベルを任意で入力し、「Create Virtual Cloud Network」ボタンを押下する

VCN が作成できたら、VCN の詳細画面より以下を確認します。

1. 「Internet Gateway」が作成されていること
2. デフォルトで作成されている「Route Table」に「Internet Gateway」が割り当てられていること
    - VCN 内のリソース (Compute Instance) がインターネットと接続できるようにするために必要です
3. デフォルトで作成されている「Security List」の「Ingress Rules」にて、インターネットから22番ポートへの通信が許可されていること
4. デフォルトで作成されている「Security List」の「Egress Rules」にて、インターネットへの全ての通信が許可されていること
    - セキュリティ・リストは、AWS でいう「セキュリティ・グループ」と同じ、ファイアウォールのルール設定です。通信が許可されている状態にします。今回は簡単にするため、あまりセキュアでない設定にしています

恐らくデフォルトの設定のままで問題ないかと思いますので、次に進みましょう。

## 2. VCN 内に Subnet を作成する

作成した VCN の中に、Subnet を作成します。先程「Compute Instance は VCN の中に配備する」と記載しましたが、より正確には「Subnet の中に配備」します。リソースごとに Subnet を区切ることで、適切なトラフィックコントロールが可能になります。

1. VCN 詳細画面にて「Create Subnet」ボタンを押下する
2. リソース名、CIDR Block、DNS ラベルを任意で入力する
3. 「Subnet Access」欄は「Public Subnet」を選ぶ
4. Route Table、DHCP Options、Security Lists はデフォルトのリソースを選択し、「Create Subnet」ボタンを押下する

## 3. SSH 鍵ペアを作成する

Compute Instance に SSH 接続するため、SSH 鍵ペアを作成しておきます。

Windows の場合は「Git for Windows」、macOS の場合は「ターミナル.app」などを使い、以下のようなコマンドで SSH 鍵ペアを作成しておきましょう。

```sh
$ ssh-keygen -t rsa -b 4096 -C 'my-oci' -f ~/.ssh/my-oci
```

このようにすると、

- `~/.ssh/my-oci` (秘密鍵)
- `~/.ssh/my-oci.pub` (公開鍵)

の2ファイルが作成されます。

## 4. Compute Instance を作成する

ようやく Compute Instance の作成です。

1. OCI 管理コンソール左上のハンバーガーメニュー → 「Compute」メニュー → 「Instances」を選択する
2. 「Create Instance」ボタンを押下する
3. 「Choose an operating system or image source」欄で OS イメージを選択できる
    - Ubuntu や CentOS が永久無料枠内で選択できますが、RedHat Enterprise Linux ベースの Oracle Linux が良いでしょう。デフォルトでは Oracle Linux が選択されているかと思います
4. 「Availability Domain」「Instance Type」欄は「Always Free Eligible」ラベルの付いているものを選択する
5. 「Instance Shape」欄は「VM.Standard.E2.1.Micro」を選択する
    - これが永久無料枠で作れるシェイプです
6. 「Configure networking」欄は作成した VCN や Subnet を選択する
    - 後で Public IP を付与するので、ここでは「Do not assign a public IP address」を選択しておきます
7. 「Add SSH key」欄で、SSH 接続するための SSH 公開鍵ファイルをアップロードする
    - 先程作成した `~/.ssh/my-oci.pub` ファイルをアップロードします
8. 「Create」ボタンを押下する

これで Compute Instance が作成されます。数分で VM が起動し、利用可能な状態になります。

なお、「Create」ボタン押下時、「Out of host capacity.」というエラーメッセージが表示された場合は、当該リージョンで永久無料枠のリソースが作れない状態になります。永久無料枠分のサーバが増強されるまで気長に待つしかありません。どうも毎月月初はリソースが作成しやすい傾向にありますので、月初を狙ってみましょう。また、永久無料枠をはみ出しますが、他のシェイプを選択すると、こちらはすぐに VM が作成できます。空きができるまで待てない方は、無料クレジット300ドル以内で作成できる、他のシェイプを選択しても良いでしょう。

## 5. Reserved Public IP を作成する

Compute Instance に割り当てる Public IP を生成します。「予約済み Public IP」と呼ばれる Public IP を発行しておくと、Compute Instance を破棄したりしても同じ Public IP を使い続けられます。

1. OCI 管理コンソール左上のハンバーガーメニュー → 「Networking」メニュー → 「Public IPs」を選択する
2. 「Create Reserved Public IP」ボタンを押下する
3. リソース名を任意で入力し、「Create Reserved Public IP」ボタンを押下する

## 6. Compute Instance に Reserved Public IP を割り当てる

ようやく Compute Instance の下準備が完了です。長いですね…。

1. OCI 管理コンソール左上のハンバーガーメニュー → 「Compute」メニュー → 「Instances」を選択する
2. 作成した Compute Instance を選択する
3. 左側の「Attached VNICs」メニューを選択し、VNIC 名リンクを押下する
4. 左側の「IP Addresses」メニューを選択し、作成済の IP Address リソース右側の3点リーダアイコン (「…」) より「Edit」メニューを選択する
5. 「Public IP Address」欄で「Reserved Public IP」を選択し、先程作成した Reserved Public IP を選択し「Update」ボタンを押下する

これで、Compute Instance に Public IP が割り当てられました。ターミナルで次のようなコマンドを作り、SSH 接続できるかどうか試してみます。

```sh
$ ssh -i ~/.ssh/my-oci opc@【Public IP】
```

Compute Instance のデフォルトユーザは `opc` というユーザ名ですので、これを指定します。SSH 接続ができたら、ひとまず作業完了です。

# ATP を作成する

いよいよ本命、ATP を作成していきます。

1. OCI 管理コンソール左上のハンバーガーメニュー → 「Autonomous Transaction Processing」メニューを選択する
2. 「Create Autonomous Database」ボタンを押下する
3. 「Choose a workload type」欄で「Transaction Processing」を選択する
    - ADW を作ってみたい場合はここで「Data Warehouse」を選択します
4. 「Choose a deployment type」欄で「Serverless」を選択する
    - 無料枠で作成するにはこちらを選択する必要があります
5. 「Configure the database」欄の「Always Free」にチェックを入れる
    - 無料枠で作成できるスペックが自動的に選択されます
6. 「Create administrator credentials」で DB 接続用のパスワードを入力する
    - 初期状態で作成される DB ユーザ名は「ADMIN」で固定されていますので、そのパスワードを設定します
7. 「Create Autonomous Database」ボタンを押下する

これで ATP が作成できます。

# ウォレットをダウンロードする

ATP が作成できたら、 __「ウォレット」__ と呼ばれる DB 接続用の資格証明ファイルをダウンロードします。

1. 作成した ATP 名のリンクを押下し、詳細画面に移動する
2. 「DB Connection」ボタンを押下し、「Download Wallet」ボタンを押下する
3. DB 作成時に入力したパスワードを入力し、「Download」ボタンを押下する

すると `Wallet_【DB 名】.zip` というファイルがダウンロードできます。

# SQL*Plus をダウンロードする

DB との接続に使用する、SQL*Plus をダウンロードしておきます。

- [Oracle Instant Client Downloads](https://www.oracle.com/database/technologies/instant-client/downloads.html)

上のページより、「Instant Client for Linux x86-64」リンクを押下し次のページに進みます。

遷移先のページで、以下の2ファイルをダウンロードします。

1. Basic Package (RPM)
    - 本稿執筆時点では `oracle-instantclient19.5-basic-19.5.0.0.0-1.x86_64.rpm` というファイル
2. SQL*Plus Package (RPM)
    - 本稿執筆時点では `oracle-instantclient19.5-sqlplus-19.5.0.0.0-1.x86_64.rpm` というファイル

# Compute Instance に必要なファイルをアップロードする

ファイルをダウンロードしたら、先程ダウンロードしたウォレットとともに、Compute Instance にアップロードします。

```sh
$ scp -i ~/.ssh/my-oci ./Wallet_【DB 名】.zip opc@【Public IP】:/home/opc
$ scp -i ~/.ssh/my-oci ./oracle-instantclient19.5-basic-19.5.0.0.0-1.x86_64.rpm opc@【Public IP】:/home/opc
$ scp -i ~/.ssh/my-oci ./oracle-instantclient19.5-sqlplus-19.5.0.0.0-1.x86_64.rpm opc@【Public IP】:/home/opc
```

# Compute Instance で SQL*Plus を設定する

Compute Instance に SSH 接続します。

```sh
$ ssh -i ~/.ssh/my-oci opc@【Public IP】
```

`opc` ユーザでログイン後のユーザホーム `/home/opc` 配下に、 `scp` でアップした3つのファイルが存在することを確認してください。

ファイルが存在したら、まずは2つの `.rpm` ファイルを使用して `sqlplus` コマンドをインストールします。

```sh
$ sudo rpm -ivh ./oracle-instantclient19.5-basic-19.5.0.0.0-1.x86_64.rpm
$ sudo rpm -ivh ./oracle-instantclient19.5-sqlplus-19.5.0.0.0-1.x86_64.rpm
```

インストール後、 `sqlplus` コマンドが動作することを確認してください。

続いて、ウォレットファイルを `unzip` で解凍し、 `/home/opc/wallet` ディレクトリ配下に配置できるようにします。

```sh
$ mkdir /home/opc/wallet
$ mv ./Wallet_【DB 名】.zip /home/opc/wallet

$ cd /home/opc/wallet

$ unzip ./Wallet_【DB 名】.zip
```

ウォレットファイルを解凍すると、中に `sqlnet.ora` というファイルが存在するかと思いますこれを `vi` コマンドで開きます。中は次のように記載されているかと思います。

```
WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY="?/network/admin")))
SSL_SERVER_DN_MATCH=yes
```

このうち、 `DIRECTORY="?/network/admin"` 部分を、このウォレットファイルが格納されているディレクトリのパスに書き換えます。次のような内容になります。

```
WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY="/home/opc/wallet")))
SSL_SERVER_DN_MATCH=yes
```

さらに、 `/home/opc/.bash_profile` を開き、次のように環境変数を設定します。

```sh
# ~/.bash_profile

export TNS_ADMIN='/home/opc/wallet'
```

これでウォレットファイルのディレクトリを参照するよう設定ができました。

# ATP に接続する

ATP への接続文字列は、ウォレットファイル中の `tnsnames.ora` を参照すると確認できます。 `tnsnames.ora` の中身は次のようになっています。

```
example_tpurgent = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.ap-tokyo-1.oraclecloud.com))(connect_data=(service_name=xxxxxxxxxxxxxxx_example_tpurgent.atp.oraclecloud.com))(security=(ssl_server_cert_dn="CN=adb.ap-tokyo-1.oraclecloud.com,OU=Oracle ADB TOKYO,O=Oracle Corporation,L=Redwood City,ST=California,C=US")))
example_tp       = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.ap-tokyo-1.oraclecloud.com))(connect_data=(service_name=xxxxxxxxxxxxxxx_example_tp.atp.oraclecloud.com))(security=(ssl_server_cert_dn="CN=adb.ap-tokyo-1.oraclecloud.com,OU=Oracle ADB TOKYO,O=Oracle Corporation,L=Redwood City,ST=California,C=US")))
example_high     = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.ap-tokyo-1.oraclecloud.com))(connect_data=(service_name=xxxxxxxxxxxxxxx_example_high.atp.oraclecloud.com))(security=(ssl_server_cert_dn="CN=adb.ap-tokyo-1.oraclecloud.com,OU=Oracle ADB TOKYO,O=Oracle Corporation,L=Redwood City,ST=California,C=US")))
example_low      = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.ap-tokyo-1.oraclecloud.com))(connect_data=(service_name=xxxxxxxxxxxxxxx_example_low.atp.oraclecloud.com))(security=(ssl_server_cert_dn="CN=adb.ap-tokyo-1.oraclecloud.com,OU=Oracle ADB TOKYO,O=Oracle Corporation,L=Redwood City,ST=California,C=US")))
example_medium   = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.ap-tokyo-1.oraclecloud.com))(connect_data=(service_name=xxxxxxxxxxxxxxx_example_medium.atp.oraclecloud.com))(security=(ssl_server_cert_dn="CN=adb.ap-tokyo-1.oraclecloud.com,OU=Oracle ADB TOKYO,O=Oracle Corporation,L=Redwood City,ST=California,C=US")))
```

各行のイコール記号 `=` より手前の文字列を指定すれば ATP に接続できます。この接続文字列のことは「接続サービス」と表現しますが、複数の接続サービスがあるのは何なのでしょうか。次のページをご覧になるとよく分かるかと思います。

- 参考 : [Oracle オラクルエンジニア通信 - Autonomous Databaseの接続サービスとシェアについて](https://blogs.oracle.com/oracle4engineer/adb-services-shares-201905)

ATP では5種類の接続サービスがあり、それぞれで「パラレル実行の可否」「同時接続セッション数」「CPU リソースの割り当て (優先度)」が決まっているようです。本来は行いたい処理に応じて接続サービスを使い分けると良いでしょうが、今回はとりあえず「HIGH」で接続してみます。

`tnsnames.ora` で確認した接続サービス名に従って、次のようにコマンドを実行します。

```sh
$ sqlplus 'ADMIN/【パスワード】@example_high'
```

このようにすると、SQL*Plus を通じて ATP に接続できました。 `SQL>` というプロンプトに変わっているかと思いますので、まずはどんな DB なのか確認してみると良いでしょう。

```sql
SQL> SELECT * FROM v$instance;
SQL> SELECT * FROM v%pdbs;
```

# おわりに

以上のとおり、Oracle Cloud の永久無料枠で ATP を作ってみました。

ATP は機械学習により自動的に索引が作成されたり、便利な機能が盛り沢山です。それでいて通常の使用感はこれまでの Oracle DB そのままなので、利用者は特に気にしなくて良いのが特徴です。自動チューニングの結果はレポートが確認できますので、ぜひとも ATP や ADW を使い込んで、その効果を確認してみてください。