【Oracle Cloud】OCI GoldenGateを使ってAutonomous DatabaseからMySQL HeatWaveへのデータ連携を試してみた

# はじめに
Oracle Cloudで提供されているOracle GoldenGateのマネージドサービス OCI GoldenGate はリリース当初Oracle Databaseしか対応していませんでしたが、2022年10月に**MySQL(AWS RDS/Aurora MySQLやAzure Database for MySQLと言ったOracle Cloud以外のフルマネージドのMySQLデータベースサービスも含む)やオブジェクトストレージ**にも対応しました。
自分はChange Data Capture(CDC)製品の類は専らQlik Replicateを使ってきてOracle GoldenGateは触ったことがなかったこともあり、この度初めてOCI GoldenGateを使った備忘録を兼ね”とりあえず触ってみた”的な記事を書いてみた次第です。
# Oracle Cloud Infrastructure GoldenGateとは
Oracle Cloud Infrastructure GoldenGate(以下OCI GoldenGate)とは、Oracle Cloudで提供されるデータ連携サービスの一つで、Oracle GoldenGateがPaaS提供されます。
OCI GoldenGateのサービス概要については、@ora-777さんの記事 [[Oracle Cloud] OCI GoldenGateとは？](https://qiita.com/ora-777/items/a753c0f4c783e8343dc3) が大変分かりやすいですのでご参照ください。
こちらの記事にもありますが、従来からオンプレミス用としてソフトウェアでGoldenGateが提供されているためデータ移行のプロジェクトでOracle GoldenGateを利用した事がある方もいらっしゃると思いますが、OCI GoldenGateはフルマネージドなPaaSとして提供されますので、Oracle GoldenGateのインストールやサーバの構成・管理も不要となり、おまけに負荷状況に応じたリソースのオートスケールにも対応しています。
また、OCI GoldenGateはエージェントレスで構成可能であるため、OS領域にログインが許可されないフルマネージドなPaaSのデータベースサービスをデータのソースやターゲットとして利用する事が出来ます。このようなデータ連携クラウドサービスではAWS Data Migration Service(AWS DMS)が有名ですが、OCI GoldenGateの登場でOracle Cloudでも同じようなサービスが利用できるようになったと理解しても良いでしょう。
# データ連携のソースとターゲットの準備
ここからは実際にOCI GoldenGateを触ってみたいと思います。ベースとした手順はOCI GoldenGate公式ガイドの[Replicate data from OCI MySQL Database to Autonomous Data Warehouse](https://docs.oracle.com/en/cloud/paas/goldengate-service/amyql/index.html#AMYQL-GUID-AED023AE-DFB8-4325-AE0F-2AA875787EF1)となります。
触ってみたいと思うのですが、データ連携にはソースとターゲットとなるデータベースが必要なので検証用のデータベースも作成します。
OCI GoldenGateのエージェントレスの特性を活かすためソースもターゲットもフルマネージドのPaaS提供されるデータベースサービスを利用したいと思うのですが、手間をかけず簡単に準備出来るとなるとやはりOracle Cloudで提供されるデータベースサービスになるので今回は以下のサービスを利用します。
**<font color=#6699CC>ソースデータベース</font>：Oracle Cloud Autonomous Transaction Processing(Oracle Database 19c 19.17.0.1.0)**
**<font color=#6699CC>ターゲットデータベース</font>：Oracle Cloud MySQL HeatWave(MySQL 8.0.31)**
## ターゲットデータベースの準備
ターゲットとなるデータベースには**MySQL HeatWave**を利用します。MySQL HeatWaveをまだご存じない方は[**こちら**](https://www.oracle.com/jp/mysql/heatwave/)をご参照ください。
MySQL HeatWaveはMySQLのクエリアクセラレーター的な拡張機能で、RAPIDと呼ばれる列指向型のインメモリストレージエンジンがMySQL HeatWave専用クラスタ上に展開され、インメモリのテーブルに超並列処理を実行する事により非常に高速な検索性能を実現しています。
従来のMySQLはトランザクション処理処理が得意な一方で大規模なテーブルへのスキャンが必要な分析処理は苦手とされてきましたが、MySQL HeatWaveの登場によりこの弱点を克服したと言えるでしょう。
なお、OCI GoldenGateはMySQL HeatWaveのRAPIDストレージエンジンのテーブルに直接データを同期することはしません。
MySQL Heatwaveでは一つのテーブルがInnoDBストレージエンジンとRAPIDストレージエンジンの双方に存在し、テーブルに対するデータの変更はInnoDBテーブルに実行(データの永続性もInnoDBの役割)され、その変更はインメモリのRAPIDテーブルにリアルタイムで自動同期されます。
今回の検証におけるデータ連携の流れを雑に示すと以下のようなになります。
【Oracle Database】-->【OCI GoldenGate(Extract)】-->【OCI GoldenGate(Replicat)】--> 【MySQL(InnoDB) -(内部で自動同期)-> MySQL HeatWave(RAPID)】
### MySQL HeatWaveの作成
まずターゲットとなるMySQL HeatWaveの作成します。MySQL HeatWaveの作成方法は日本オラクルさん公式の
 **[OCIチュートリアル その10 - MySQLで高速分析を体験する](https://oracle-japan.github.io/ocitutorials/beginners/creating-HeatWave/)**
がとても分かりやすいため、このチュートリアルを参照して作成してください。
こちらのチュートリアルの前提条件にもありますが、仮想ネットワーク、MySQLクライアントをインストールする仮想インスタンス、セキュリティリストの設定などが必要です。Oracle Cloud独自の用語はありますが、AWS等を利用した経験のある方でしたら概念は同じなのでOCIチュートリアルに則り実施すれば難しい事はありません。
### MySQL HeatWaveにデータ連携用のテーブルを作成
MySQL HeatWaveに検証で使用するデータ連携用のテーブルを作成します。
こちらもオラクルさんが提供してくれるSQLスクリプトを利用しましょう。
SQLスクリプトは **[こちら](https://objectstorage.us-ashburn-1.oraclecloud.com/p/VEKec7t0mGwBkJX92Jn0nMptuXIlEpJ5XJA-A6C9PymRgY2LhKbjWqHeB5rVBbaV/n/c4u04/b/livelabsfiles/o/data-management-library-files/seedSRCOCIGGL_MySQL.sql)** からダウンロードできます。
ダウンロードしたSQLスクリプトには大量のinsert文が記載されていますが、<font color=#FF3333>**実行しない**</font>でください。データ連携のターゲットであるMySQL HeatWaveはデータをソースのATPから受け取るためテーブルは空の状態にしておきます。
MySQLクライアントからMySQL HeatWaveに接続してSQLスクリプトに記載されている通り**SRC_OCIGGLLデータベースを作成**、SRC_OCIGGLLデータベース内に以下の**6つの空テーブル**を作成します。
・SRC_CITY
・SRC_CUSTOMER
・SRC_ORDERS
・SRC_ORDER_LINES
・SRC_PRODUCT
・SRC_REGION

作成したテーブルは空であることも確認しておきましょう。
```sql:
mysql> select * from SRC_CITY;
--------------
select * from SRC_CITY
--------------

Empty set (0.00 sec)

```
MySQL HeatWaveで使用するテーブルにはプライマリキーが必要になるため、以下のコマンドを実行して各テーブルにプライマリキーを追加します。
```sql:
mysql> alter table SRC_OCIGGLL.SRC_CITY add primary key (CITY_ID); 
mysql> alter table SRC_OCIGGLL.SRC_CUSTOMER add primary key (CUSTID);
mysql> alter table SRC_OCIGGLL.SRC_ORDERS add primary key (ORDER_ID);
mysql> alter table SRC_OCIGGLL.SRC_ORDER_LINES add primary key (LORDER_ID, ORDER_ID); 
mysql> alter table SRC_OCIGGLL.SRC_PRODUCT add primary key (PRODUCT_ID);
mysql> alter table SRC_OCIGGLL.SRC_REGION add primary key (REGION_ID);
```
以下のコマンドを実行して対象テーブルにMySQL HeatWaveを使用する設定をします。
因みに先ほどから出てくるRAPIDとはMySQL HeatWaveの開発コードでその名残がコマンドやシステム変数等にあります。
```sql:
mysql> alter table SRC_OCIGGLL.SRC_CITY secondary_engine RAPID;
mysql> alter table SRC_OCIGGLL.SRC_REGION secondary_engine RAPID;
mysql> alter table SRC_OCIGGLL.SRC_CUSTOMER secondary_engine RAPID;
mysql> alter table SRC_OCIGGLL.SRC_ORDERS secondary_engine RAPID;
mysql> alter table SRC_OCIGGLL.SRC_ORDER_LINES secondary_engine RAPID;
mysql> alter table SRC_OCIGGLL.SRC_PRODUCT secondary_engine RAPID;
```
以下のコマンドを実行してSRC_OCIGGLLデータベースのテーブルのデータをMySQL HeatWaveにロードします。
と言っても現時点ではデータは入っていないのですぐ終わります。
```sql:
mysql> CALL sys.heatwave_load(JSON_ARRAY("SRC_OCIGGLL"),NULL);
```
この後は手動でデータをロードしなくても対象のInnoDBテーブルにデータの挿入や変更、削除と言ったトランザクション処理が実行されると自動でMySQL HeatWave上RAPIDのテーブルへ変更が反映されていきます。ETLやジョブでのデータロードが不要なアーキテクチャは便利ですよね。

最後にOCI GoldenGateがMySQL HeatWaveに接続する際に使用するユーザーggadminを作成して権限を付与しておきます。
```sql:
mysql> create user 'ggadmin' identified by 'パスワード';
mysql> grant select, replication slave, replication client, create,create view, event, insert, update, drop,execute, delete on *.* to 'ggadmin';
```
## ソースデータベースの準備
ソースのデータベースにはOracle Cloudの自律型データベースサービスである**Oracle Autonomous Transaction Processing(以下ATP)** を利用します。
ATPと言ってもOracle Cloudを利用していない方には馴染みがないかもしれませんが、OLTPに最適化されたフルマネージドなOracle DatabaseのPaaSと理解してください。因みにATPはOracle Exadataで稼働しているそうです。
### Oracle Autonomous Transaction Processingの作成
ATPの作成方法も日本オラクルさん公式の
[**OCIチュートリアル 101: ADBインスタンスを作成してみよう**](https://oracle-japan.github.io/ocitutorials/database/adb101-provisioning/)
が分かりやすいのでこちらを参考にして作成してください。ATPはPluggable Databaseなのであっという間にデプロイが完了します。
SQLを用いたATPへの操作はコンソールの**Database Actions**から操作できます。SQL*Plusの方が使いやすいと言う方はMySQLクライアントと同じ仮想インスタンスにインストールしてATPに接続しましょう。
### GGADMINユーザの有効化
ATPが使用可能になったらOCI GoldenGateで使用するOracle Databaseのユーザを作成するのですが、さすがオラクル社のサービスと言う事もあり標準でGoldenGateで使用するユーザ**GGADMIN**が作成されています。ただ、GGADMINはアカウントがロックされているのでそれを外す必要があります。
簡単な方法はATPのコンソールから**データベース・アクション**をクリックしてDatabase Actionsを起動します。
Database Actionsのコンソールが起動したら**管理**のカテゴリにある**データベース・ユーザー**をクリックしましょう。
![ATP_DA01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/8b8a5d5d-3c8c-39db-7fab-736229f40256.jpeg)
表示されたGGADMINはロックされているためアイコンが黄色です。編集してロックを外します。
![ATP_DA02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/c747a54e-9153-e371-2010-ee4babb9b419.jpeg)
アカウントのロックを外し、任意のパスワードを設定したら変更を適用します。
![ATP_DA03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/fd4a7505-b7a8-2510-db75-25df1a1722ff.jpeg)
黄色だったGGADMINのアイコンが**緑色**に変わっていれば完了です。
### ATPのサプリメンタル・ロギングの有効化
ATPのデータベースのサプリメンタル・ロギングも忘れずに有効化しておきましょう。
OCI GoldenGateのようにChange Data Captureと呼ばれるデータの差分更新を利用するデータ連携サービスではおまじないみたいなものです。
サプリメンタル・ロギングの有効化には、Database ActionsかSQLPlusでATPに接続して以下のコマンドを実行します。
```sql:
SQL>  alter pluggable database add supplemental log data;

Pluggable database altered.
```
### Oracle Autonomous Transaction Processingにデータ連携用のテーブルとデータを作成
ATPに検証で使用するデータ連携用のテーブルとデータを作成します。
ここでもまたまたオラクルさんが用意してくれているSQLスクリプトを利用させてもらいましょう。
[**こちら**](https://objectstorage.us-ashburn-1.oraclecloud.com/p/VEKec7t0mGwBkJX92Jn0nMptuXIlEpJ5XJA-A6C9PymRgY2LhKbjWqHeB5rVBbaV/n/c4u04/b/livelabsfiles/o/data-management-library-files/Archive.zip) から**Archive.zip**をダウンロードします。
解凍すると4つのファイルが展開されますが、利用するのは**OCIGGLL_OCIGGS_SETUP_USERS_ATP.sql**と**OCIGGLL_OCIGGS_SRC_USER_SEED_DATA.sql**の2つです。
まずOCIGGLL_OCIGGS_SETUP_USERS_ATP.sqlを実行(中身のSQL文をコピペして実行して良いです)してSRC_OCIGGLLユーザを作成します。
次にOCIGGLL_OCIGGS_SRC_USER_SEED_DATA.sqlも同様に実行してSRC_OCIGGLLスキーマに以下のテーブル(とその索引とプライマリキー制約)を作成してデータを挿入します。
MySQL HeatWaveでの作業と同じく6つのテーブルが作成され、これらがOCI GoldenGateでの伝播対象テーブルとなります。
# OCI GoldenGate デプロイメントの作成
ようやく本題のOCI GoldenGateの作成です。
OCI GoldenGateは、Oracle Cloudコンソールのハンバーガーメニューを展開して、Oracle Databaseの中にあるGoldenGateから到達できます(ATPの右隣の方にあります)。
GoldenGateのコンソールに遷移したら早速[**デプロイメントの作成**]をクリックしてOCI GoldenGateデプロイメントを作成しましょう。
今回の検証ではATPのOracle Database用OCI GoldenGateデプロイメントとMySQL HeatWaveのMySQL用OCI GoldenGateデプロイメントをそれぞれ一つずつ作成します。
### Oracle Database用OCI GoldenGateデプロイメントの作成
一つ目はATPに接続するOCI GoldenGateデプロイメントを作成していきます。
まず一般情報の項目を入力していきます。
1. <font color=#6699CC>**名前**</font>：デプロイメントの名前を入力します。この記事ではGGOracleATPとします
1. <font color=#6699CC>**コンパートメント**</font>：ご自身が使用しているコンパートメントを選択します。この記事ではheatwaveコンパートメントを利用しています
1. <font color=#6699CC>**OCPU数**</font>：OCI GoldenGateに割り当てるCPU数です。検証なので1で十分です。自動スケーリングも同じ理由で無効とします
1. <font color=#6699CC>**サブネット**</font>：OCI GoldenGateをデプロイするネットワークサブネットを指定します。ご自身の使用している環境に合わせてください。この記事では検証目的なのでパブリック・サブネットを利用します
1. <font color=#6699CC>**ライセンス・タイプの選択**</font>：ご自身の事情に合わせて選択してください
最後に今回は手元環境のブラウザからGoldenGateのコンソールに接続したいので、拡張オプションの表示させ<font color=#6699CC>**パブリック・エンドポイントの作成**</font>にチェックを入れてから次へ進みます。
![OCIGG01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/0a17b407-1596-6c2f-f37b-ec16f12a5172.jpeg)

次に**Goldengateの詳細**の項目を入力します。
1. <font color=#6699CC>**テクノロジの選択**</font>：<font color=red>**Oracle Database**</font>を選択します
1. <font color=#6699CC>**GoldenGateのインスタンス名**</font>：GoldenGateのインスタンス名を入力します。この記事ではGGinstOracleATPとします
1. <font color=#6699CC>**管理者ユーザー名**</font>：GoldenGateの管理者ユーザー名を入力します。この記事ではoggadminとします
1. <font color=#6699CC>**管理者パスワード**</font>：管理者のパスワードを入力します
![OCIGG02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/3906b53f-3f74-a9fc-78d2-4e2e7444005f.jpeg)
最後に**作成**をクリックします。5分ほど待つとOCI GoldenGateのデプロイメントが作成されます。
## MySQL用のOCI GoldenGateデプロイメントの作成
MySQL HeatWave用のOCI GoldenGateデプロイメントも同様の手順で作成します。
手順はOracle Databaseと同じなので省略しますが、Goldengateの詳細の<font color=#6699CC>**テクノロジの選択**</font>は<font color=red>**MySQL**</font>を選択してください。
また、この記事ではデプロイメントの名前はGGMySQLHW、GoldenGateのインスタンス名とGGinstMySQLHWしています。
![OCIGG03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/5ea9656d-e97c-902a-27a4-bbe597ea254d.jpeg)
## 接続の作成
ソース/ターゲットのデータベースにアクセスするためには接続オブジェクトを作成しOCI GoldenGateデプロイメントに割り当てる必要があります。
### ATPへの接続を作成
GoldenGateのコンソールで[**接続**]をクリックしてATPへの接続を作成していきます。
接続作成に必要な**一般情報**の項目を入力します。
1. <font color=#6699CC>**名前**</font>：接続名を入力します。この記事ではsrcoracleatpとします
1. <font color=#6699CC>**コンパートメント**</font>：ご自身が使用しているコンパートメントを選択します。この記事ではheatwaveコンパートメントを利用します
1. <font color=#6699CC>**タイプ**</font>：この接続はATP用なのでリストから<font color=red>**OCI自律型データベース**</font>を選択します
入力内容に問題がなければ次へ進みます。
![OCIGGSES01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/a7f00549-38f7-e27c-8b09-f272779fa2db.jpeg)

続いて**接続詳細**を入力します。
1. <font color=#6699CC>**データベース詳細**</font>：**データベースの選択**を選択します。データベースの選択にすると接続情報のウォレットのアップロードが不要になります
1. <font color=#6699CC>**${コンパートメント名}のデータベース**</font>：コンパートメント内の有効なAutonomous Databaseがリストになっているので対象データベースを選択します。この記事ではOracleATPSrcを選択します
1. <font color=#6699CC>**データベース・ユーザー名**</font>：タイプでOCI自律型データベースを選択しているとデフォルトで**ggadmin**が入っています(変更できないようです)
1. <font color=#6699CC>**データベース・ユーザー・パスワード**</font>：ATPのggadminユーザーのパスワードを入力します
![OCIGGSES02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/9167191c-b647-f4db-15d8-1d61a24a7656.jpeg)
入力値に問題がなければこちらで接続を作成します。
### デプロイメントの割当て
作成した接続がアクティブになったら[**デプロイメントの割当て**]をクリックします。
割当て対象のOCI GoldenGateのデプロイメントを選択して[**デプロイメントの割当て**]をクリックします。なお、Oracle Database用の接続にはOracle Database用のOCI GoldenGateデプロイメント(GGOracleATP)だけが表示されます。
![OCIGGSES03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/24212287-6703-0162-8af1-fc22c82c552c.jpeg)
### MySQL HeatWaveへの接続の作成
つづいてMySQL HeatWaveへの接続も作成します。
手順はATPへの接続の作成と同じなので省略しますが、<font color=#6699CC>**タイプ**</font>は<font color=red>**OCI MySQLデータベース・サービス**</font>を選択してください。また、この記事では接続名をtrgmysqlhwとします。

続いて**接続詳細**では以下を入力します。
1. <font color=#6699CC>**データベース詳細**</font>：**MySQLデータベース・システムの選択**を選択します
1. <font color=#6699CC>**${コンパートメント名}のデータベース・システム**</font>：コンパートメント内の有効なMySQLデータベース・システムがリストになっているので対象データベースを選択します。ターゲットデータベースの準備で作成したMySQL HeatWaveが利用可能なMySQLデータベース・システムを選択しましょう
1. <font color=#6699CC>**データベース名**</font>：データベース名を入力します。この記事ではターゲットデータベースの準備で作成したSRC_OCIGGLLとします
1. <font color=#6699CC>**データベース・ユーザー名**</font>：OCI GoldenGateから接続するMySQLのユーザー名を入力します。この記事ではターゲットデータベースの準備で作成した**ggadmin**をとします
1. <font color=#6699CC>**データベース・ユーザー・パスワード**</font>：OCI GoldenGateから接続するMySQLのユーザーのパスワードを入力します。この記事ではggadminのパスワードを入力します
1. <font color=#6699CC>**SSL詳細**</font>：セキュリティ・プロトコルは検証なのでプレーンかTLSを設定しておきます。TLSを選択した場合はSSLモードが必須か優先を選択します。この記事ではTLS、SSLモード優先を選択します
入力値に問題がなければこちらで接続を作成します。

最後に接続がアクティブになったら[**デプロイメントの割当て**]をクリックします。
割当て対象のOCI GoldenGateのデプロイメントを選択して[**デプロイメントの割当て**]をクリックします。MySQL用の接続にはMySQL用のOCI GoldenGateデプロイメント(GGMySQLHW)だけが表示されます。
# Extractの追加
ここからはOCI GoldenGateにソースデータベースからデータを抽出する**Extract**を追加していきます。
追加するExtractは初期ロード用とその後の差分更新いわゆるChange Data Capture用の2つになります。
まずOracle Database用OCI GoldenGateデプロイメント(GGOracleATP)にて[**コンソールの起動**]をクリックしてデプロイメントコンソールを起動します。
コンソールが起動したらOCI GoldenGateデプロイメントの作成で設定した管理者ユーザー**oggadmin**でログインします。
![extract01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/82951e20-a088-abea-47b0-1bfd480d394d.jpeg)
画面左ナビゲーションメニューの[**構成**]をクリックしてデータベースの資格証明を確認しておきます。割り当てたATP用の接続が表示されています。ここに表示されているドメインと別名は次の手順で使用します。
![extract02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/a5790e47-ccb3-fe70-ddf3-2f2bcbd7221c.jpeg)
管理サービスの[**概要**]から実際にExtractを追加していきます。画面上部にある[**+**]のアイコンをクリックするとExtractの追加画面に遷移します。
抽出タイプは**統合Extract**を選択して次に進みます。
![extract03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/ceec060b-8de2-b90f-4145-b5d71fc7c722.jpeg)
抽出オプションでは以下の項目を入力します。
1. <font color=#6699CC>**プロセス名**</font>：Extractのプロセス名を入力します。この記事ではCDCEXTとします
1. <font color=#6699CC>**トレイル名**</font>：Extractのトレイル名を入力します。この記事ではC1とします
1. <font color=#6699CC>**資格証明ドメイン**</font>：先ほど確認したドメインOracleGoldenGateを選択します
1. <font color=#6699CC>**資格証明別名**</font>：この記事では先ほど確認した別名 srcoracleatp を選択します
入力値に問題がなければ次へを進みます。
![extract04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/95fdfd87-5afe-1203-d128-ae25b7eba3e7.jpeg)
パラメータ・ファイルに以下のパラメータを追記しておきます。抽出対象のテーブルはSRC_OCIGGLLスキーマのテーブルとなります。
```
TABLE SRC_OCIGGLL.*;
```
![extract05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/924d0d20-c11d-a4b0-26ad-3024aa50343a.jpeg)
[**作成および実行**]をクリックするとExtractが追加されます。

続いて初期ロード用のExtractを追加します。
先ほどと同じく管理サービスの[**概要**]からExtractを追加していきます。[**+**]のアイコンをクリックします。
ここでは抽出タイプは**Extractの初期ロード**を選択して次に進みます。
抽出オプションでは以下の項目を入力します。
1. <font color=#6699CC>**プロセス名**</font>：Extractのプロセス名を入力します。この記事ではILEXTとします
トレイル名や資格証明の情報を入力する必要があると思うのですが、なぜか表示されないので次に進みます。
#バグだと思うのですが、OCIの中の方に教えていただきたいところです。
![extract07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/64c157dc-02ef-8ff3-dddc-37bbd6d6c426.jpeg)
パラメータ・ファイルにトレイル名や資格証明情報を含めてパラメータを追記しておきましょう。
```
USERIDALIAS srcoracleatp DOMAIN OracleGoldenGate
EXTFILE I1 ,  PURGE
TABLE SRC_OCIGGLL.*;
```
![extract08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/488aa374-ce67-f774-d97e-3f0a5fdc4e1b.jpeg)
[**作成および実行**]をクリックするとExtractが追加されます。
# 初期ロード用の配布パスを作成
Oracle Database用OCI GoldenGateデプロイメントとMySQL用OCI GoldenGateデプロイメントを連携させるための配布パスを作成していきます。
まずMySQL用OCI GoldenGateデプロイメント(GGMySQLHW)にて[**コンソールの起動**]をクリックしてデプロイメントコンソールを起動します。
![distribution01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/b4aa06f1-0fb8-10fc-20a0-d14d681199c9.jpeg)
### 配布パス用ユーザーの作成
画面左にあるナビゲーションメニューから[**管理者**]をクリック、[**+**]のアイコンをクリックしてユーザーを追加します。
1. <font color=#6699CC>**ユーザー名**</font>：ユーザー名を入力します。この記事ではggsnetとします
1. <font color=#6699CC>**ロール**</font>：ロールはオペレーターを選択します(コンソールが日本語表示の場合では演算子となってしまっていますね)
1. <font color=#6699CC>**タイプ**</font>：パスワードを選択します
1. <font color=#6699CC>**パスワード**</font>：ユーザーのパスワードを入力します
最後に[**発行**]をクリックします。
![distribution03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/a34f2457-bbbc-dcd3-4b82-ea3828547afd.jpeg)
### 資格情報の追加
次にソースのOracle Database用OCI GoldenGate(GGOracleATP)のコンソールで作成した配布パス用ユーザーの資格情報を追加します。
デプロイメントコンソールの画面左にあるナビゲーションメニューの[**構成**]をクリックします。
資格証明の画面で[**+**]のアイコンをクリック、以下の項目を入力して資格証明を追加します。
1. <font color=#6699CC>**資格証明ドメイン**</font>：ドメイン名を入力します。この記事ではGGSNetworkとします
1. <font color=#6699CC>**資格証明別名**</font>：エイリアス名を入力します。この記事ではdpuserとします
1. <font color=#6699CC>**ユーザー名**</font>：上記で作成した配布パスユーザーを指定します。この記事ではggsnetです
1. <font color=#6699CC>**パスワード**</font>：ユーザーのパスワードを入力します。この記事ではggsnetのパスワードです
最後に[**発行**]をクリックします。
![distribution05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/4becb559-1695-4b39-6dc3-c6805b842923.jpeg)
### 初期ロード用の配布パスを作成
Oracle Database用OCI GoldenGate(GGOracleATP)で初期ロード用の配布パスを追加します。
デプロイメントコンソールの[**分散サービス**]で[**+**]のアイコンをクリック、以下の項目を入力して配布パスを追加します。
1. <font color=#6699CC>**パス名**</font>：パス名を入力します。この記事ではdpiextとします
1. <font color=#6699CC>**ターゲット認証方式**</font>：ユーザーID別名を選択します
1. <font color=#6699CC>**ターゲット**</font>：wssを選択します
1. <font color=#6699CC>**ターゲットホスト**</font>：ターゲットのMySQL用OCI GoldenGateデプロイメントコンソールのURL https:// 以降、末尾のスラッシュなしで入力します
1. <font color=#6699CC>**ポート番号**</font>：ポート番号は443とします
1. <font color=#6699CC>**トレイル名**</font>：初期ロードのトレイル。今回の記事ではI1とします
1. <font color=#6699CC>**ドメイン**</font>：上記の資格情報の追加で指定した資格情報ドメインを入力します。この記事ではGGSNetworkとします
1. <font color=#6699CC>**別名**</font>：資格情報の追加で指定したエイリアスを入力。この記事ではdpuserとします
![distribution06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/932a830a-6d9e-6ab4-fce0-0746de4a948f.jpeg)
配布パスが追加されると分散サービスの画面に以下のような構成やステータスが追加されます。
![distribution07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/a784053f-dd98-65fe-c1cd-e8e4201d08a5.jpeg)
# 初期ロード用のReplicatの追加
ターゲットのMySQL用OCI GoldenGateデプロイメント(GGMySQLHW)のコンソールで初期ロード用のReplicatを追加します。
### チェックポイント表の追加
画面左ナビゲーションメニューの[**構成**]をクリックします。資格証明でターゲットとなるMySQL HeatWave(trgmysqlhw)のアクションの中の[**接続**]アイコン(一番左のアイコン)をクリックします。
次に[**チェックポイント**]の[**+**]のアイコンをクリックしてチェックポイント表の追加します。
この記事ではチェックポイント表はSRC_OCIGGLL.CHECKTABLEとします。
![modify_aa.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/1e26611b-7aad-7683-a45c-536c0bc21641.jpeg)
### Replicatを追加
管理サービスの[**概要**]から実際にReplicatを追加していきます。Replicatの画面上部にある[**+**]のアイコンをクリックすると追加画面に遷移します。
今回の検証ではReplicatタイプは**クラシックReplicat**を選択して次に進みます。
![replicat01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/4bfdea8c-ba5e-e42c-30e7-ca8f3c2cef81.jpeg)

### Replicatオプション
Replicatオプションでは以下の項目を入力します。
1. <font color=#6699CC>**プロセス名**</font>：任意の名称を入力します。今回はRILとします
1. <font color=#6699CC>**目的**</font>：Unidirectionalのまま
1. <font color=#6699CC>**資格認証ドメイン**</font>：OracleGoldenGateを選択します
1. <font color=#6699CC>**資格証明別名**</font>：MySQL HeatWave用に作成した接続 trgmysqlhw を選択します
1. <font color=#6699CC>**トレイル名**</font>：ATPの変更データキャプチャで指定したトレイル名I1を入力します
1. <font color=#6699CC>**チェックポイント表**</font>：で作成したチェックポイント表SRC_OCIGGLL.CHECKTABLEを入力します
次へを進みます。
![replicat03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/a1cb1ac3-55b4-aea6-577e-a1d0a878c4d9.jpeg)
### Replicatパラメータの追加
Replicatパラメータでは以下のマッピングを追加します。
```
MAP SRC_OCIGGLL.*, TARGET SRC_OCIGGLL.*;
```
![replicat04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/dda01b5b-a007-63dd-8f23-88a12a75c82b.jpeg)
最後に[**作成および実行**]をクリックします。
### Replicat統計の確認
Replicat(RIL)の統計を確認してみましょう。
ATPに作成した6つのテーブルとMySQL HeatWaveに作成した6つのテーブルがソースとターゲットとしてマッピングされ、ATPでInsert文で挿入したレコード数と同数が**挿入**として検知されていると思います。
今回はレコード数が少ないためすぐに終わってしまいますが、レコード数が多い商用環境の場合は挿入の数が増え続けるため、次の手順を続行する前に初期ロードのレコードがすべてロードされるまでページを更新します。挿入数に変化がなくなったら初期ロードからのすべてのレコードがロードされているためReplicat(RIL)を停止する事ができます。
![replicat05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/bd6b074f-f9d6-fb21-5932-0ecda4501933.jpeg)
### MySQLコンソールで確認してみる
ターゲットのMySQL HeatWaveにログインして各テーブルの状態を確認してみましょう。
SRC_CITYテーブルには51行挿入されていることを確認してください(後続の手順でATPのSRC_CITYテーブルにレコードを追加します)。
```sql:
mysql> select * from SRC_CUSTOMER;
--------------
select * from SRC_CUSTOMER
--------------

+--------+------+-------------+----------------+----------------------+---------+----------------+------+---------------+
| CUSTID | DEAR | LAST_NAME   | FIRST_NAME     | ADDRESS              | CITY_ID | PHONE          | AGE  | SALES_PERS_ID |
+--------+------+-------------+----------------+----------------------+---------+----------------+------+---------------+
|    101 |    0 | Brendt      | Paul           | 10 Jasper Blvd.      |     107 | (212) 555 2146 |   19 |            10 |
|    102 |    0 | McCarthy    | Robin          | 27 Pasadena Drive    |      11 | (214) 555 3075 |   29 |            11 |
|    103 |    0 | Travis      | Peter          | 7835 Hartford Drive  |      12 | (510) 555 4448 |   34 |            12 |
|    104 |    0 | Larson      | Joe            | 87 Carmel Blvd.      |      13 | (213) 555 5095 |   45 |            13 |
                    >>  snip  <<
|    504 |    0 | Makino      | Tatsuo         | 2435 Toyota Ave      |      70 | 34413486       |   45 |            50 |
|    505 |    0 | Mukumoto    | Masayuki       | 59 Yamamoto Blvd     |      73 | 34827691       |   59 |            51 |
|    506 |    0 | Oneda       | Kenji          | 94 Toyota Blvd       |      70 | 51839463       |   68 |            52 |
|    507 |    0 | Okumura     | Isao           | 3 Toyota Ave         |      74 | 48928371       |   74 |            21 |
+--------+------+-------------+----------------+----------------------+---------+----------------+------+---------------+
35 rows in set (0.00 sec)

mysql> select * from SRC_CITY;
--------------
select * from SRC_CITY
--------------

+---------+-----------------+-----------+------------+
| CITY_ID | CITY            | REGION_ID | POPULATION |
+---------+-----------------+-----------+------------+
|      10 | Houston         |        20 |     743113 |
|      11 | Dallas          |        20 |     822416 |
|      12 | San Francisco   |        21 |     157574 |
|      13 | Los Angeles     |        21 |     743878 |
                    >>  snip  <<
|      70 | Tokyo           |        80 |     992823 |
|      71 | Yokohama        |        80 |     725821 |
|      72 | Osaka           |        81 |     501768 |
|      73 | Kyoto           |        81 |      78899 |
|      74 | Kobe            |        81 |      81758 |
|     107 | New York City   |        22 |     124434 |
|     500 | Ecully          |       401 |     160994 |
|     501 | Aix en Provence |       404 |     334847 |
+---------+-----------------+-----------+------------+
51 rows in set (0.00 sec)
```
# 変更データキャプチャ用の配布パスを作成
Oracle Database用OCI GoldenGate(GGOracleATP)で変更データキャプチャ用の配布パスを追加します。
デプロイメントコンソールの[分散サービス]で[+]のアイコンをクリック、以下の項目を入力して配布パスを追加します。
1. <font color=#6699CC>**パス名**</font>：パス名を入力します。この記事ではdpcdcextとします
1. <font color=#6699CC>**ソース**</font>：変更データキャプチャ。今回の記事ではCDCEXTを選択します
1. <font color=#6699CC>**ターゲット認証方式**</font>：ユーザーID別名を選択します
1. <font color=#6699CC>**ターゲット**</font>：wssを選択します
1. <font color=#6699CC>**ターゲットホスト**</font>：ターゲットのMySQL用OCI GoldenGateデプロイメントコンソールのURL https:// 以降、末尾のスラッシュなしで入力します
1. <font color=#6699CC>**ポート番号**</font>：ポート番号は443を入力します
1. <font color=#6699CC>**トレイル名**</font>：変更データキャプチャのトレイル。今回の記事ではC1と入力します
1. <font color=#6699CC>**ドメイン**</font>：資格情報の追加で指定した資格情報ドメインを入力。今回の記事ではGGSNetworkと入力します
1. <font color=#6699CC>**別名**</font>：資格情報の追加で指定したエイリアスを入力。今回の記事ではdpuserとします
次へを進みます。
![cdcdistribute01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/d48064fb-b244-a3a6-e2b1-e4dc5138383e.jpeg)
配布パスが追加されると分散サービスの画面に以下のような構成やステータスが追加されます。
2つの配布パスが表示されていれば完了です。
![cdcdistribute04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/8a8cb7a2-6e03-dc41-44e7-b802c8135fe6.jpeg)
## 変更データキャプチャ用Replicatの追加
ターゲットのMySQL用OCI GoldenGateデプロイメント(GGMySQLHW)のコンソールで変更データキャプチャ用のReplicatを追加します。
管理サービスの[概要]から実際にReplicatを追加していきます。Replicatの画面上部にある[+]のアイコンをクリックすると追加画面に遷移します。
今回の検証ではReplicatタイプはクラシックReplicatを選択して次に進みます。
![cdcrepl01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/3c536f17-d250-c458-7dc3-b3754bcd2376.jpeg)
Replicatオプションでは以下の項目を入力します。
1. <font color=#6699CC>**プロセス名**</font>：任意の名称を入力します。この記事ではRCDCとします
1. <font color=#6699CC>**資格認証ドメイン**</font>：OracleGoldenGateを選択します
1. <font color=#6699CC>**資格証明別名**</font>：この記事ではMySQL HeatWave用に作成した接続 trgmysqlhw を選択します
1. <font color=#6699CC>**トレイル名**</font>：トレイル名を入力します。この記事ではATPの変更データキャプチャで指定したトレイル名C1を入力します
1. <font color=#6699CC>**チェックポイント表**</font>：チェックポイント表名を入力します。この記事ではチェックポイント表の追加で作成したSRC_OCIGGLL.CHECKTABLEとします
次へを進みます。
![cdcrepl02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/5549c814-1374-9a7d-a5f0-cd6720d4287a.jpeg)
Replicatパラメータでは以下のマッピングを追加します。
```
MAP SRC_OCIGGLL.*, TARGET SRC_OCIGGLL.*;
```
![cdcrepl03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/067f7d2d-900a-40b8-4458-1eb99a6807b4.jpeg)
ここでは[**作成**]をクリックしてReplicatを実行せず終了し、[**管理サービス**]の[**概要**]ページに戻ります。
今回の検証ではソースデータベースのレコード数が少ないため初期ロードのReplicat(RIL)は即完了してしまっていますが、本来は初期ロードのReplicat(RIL)の統計で挿入数に変化がない事を確認してから初期ロード用のReplicat(RIL)を停止させます。
その後で変更データキャプチャのReplicat(RCDC)をアクションから[**開始**]を実行します。
![cdcrepl04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/88650339-119e-71e0-1ebf-92e8201d9e2c.jpeg)

## 変更データキャプチャの動作を確認してみる
変更データキャプチャのReplicat(RCDC)を開始したらATPのSRC_CITYテーブルにレコードを追加して、MySQL HeatWaveにその差分が伝播されるか確認してみましょう。

ATPにログインして以下のInsert文を実行します。
```sql:
$ sqlplus ggadmin@oracleatpsrc_high

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.17.0.1.0

SQL> Insert into SRC_OCIGGLL.SRC_CITY (CITY_ID,CITY,REGION_ID,POPULATION) values (1000,'Houston',20,743113);
SQL> Insert into SRC_OCIGGLL.SRC_CITY (CITY_ID,CITY,REGION_ID,POPULATION) values (1001,'Dallas',20,822416);
SQL> Insert into SRC_OCIGGLL.SRC_CITY (CITY_ID,CITY,REGION_ID,POPULATION) values (1002,'San Francisco',21,157574);
SQL> Insert into SRC_OCIGGLL.SRC_CITY (CITY_ID,CITY,REGION_ID,POPULATION) values (1003,'Los Angeles',21,743878);
SQL> Insert into SRC_OCIGGLL.SRC_CITY (CITY_ID,CITY,REGION_ID,POPULATION) values (1004,'San Diego',21,840689);
SQL> Insert into SRC_OCIGGLL.SRC_CITY (CITY_ID,CITY,REGION_ID,POPULATION) values (1005,'Chicago',23,616472);
SQL> Insert into SRC_OCIGGLL.SRC_CITY (CITY_ID,CITY,REGION_ID,POPULATION) values (1006,'Memphis',23,580075);
SQL> Insert into SRC_OCIGGLL.SRC_CITY (CITY_ID,CITY,REGION_ID,POPULATION) values (1007,'New York City',22,124434);
SQL> Insert into SRC_OCIGGLL.SRC_CITY (CITY_ID,CITY,REGION_ID,POPULATION) values (1008,'Boston',22,275581);
SQL> Insert into SRC_OCIGGLL.SRC_CITY (CITY_ID,CITY,REGION_ID,POPULATION) values (1009,'Washington D.C.',22,688002);
SQL> commit;
```
MySQL用OCI GoldengateでReplicat(RCDC)の統計情報も確認してみましょう。
![toukei.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2521797/15f644c1-587b-4aa0-7086-ee2a7c02f282.jpeg)
ソース表のSRC_OCIGGLL.SRC_CITYからターゲット表SRC_OCIGGLL.SRC_CITYへの挿入が10件検知されています。
最後にMySQL HeatWaveのSRC_CITYテーブルも確認してみます。
```sql:
mysql> select * from SRC_CITY;
--------------
select * from SRC_CITY
--------------

+---------+-----------------+-----------+------------+
| CITY_ID | CITY            | REGION_ID | POPULATION |
+---------+-----------------+-----------+------------+
|      10 | Houston         |        20 |     743113 |
|      11 | Dallas          |        20 |     822416 |
|      12 | San Francisco   |        21 |     157574 |
|      13 | Los Angeles     |        21 |     743878 |
                    >>  snip  <<
|      70 | Tokyo           |        80 |     992823 |
|      71 | Yokohama        |        80 |     725821 |
|      72 | Osaka           |        81 |     501768 |
|      73 | Kyoto           |        81 |      78899 |
|      74 | Kobe            |        81 |      81758 |
|     107 | New York City   |        22 |     124434 |
|     500 | Ecully          |       401 |     160994 |
|     501 | Aix en Provence |       404 |     334847 |
|    1000 | Houston         |        20 |     743113 |
|    1001 | Dallas          |        20 |     822416 |
|    1002 | San Francisco   |        21 |     157574 |
|    1003 | Los Angeles     |        21 |     743878 |
|    1004 | San Diego       |        21 |     840689 |
|    1005 | Chicago         |        23 |     616472 |
|    1006 | Memphis         |        23 |     580075 |
|    1007 | New York City   |        22 |     124434 |
|    1008 | Boston          |        22 |     275581 |
|    1009 | Washington D.C. |        22 |     688002 | 
+---------+-----------------+-----------+------------+
61 rows in set (0.00 sec) 
```

ATP側で挿入した10レコードがちゃんとMySQL HeatWaveに伝播されていますね👏
めでたしめでたしと言う事で今回の取り敢えずOCI GoldenGate触ってみようという目的は達成としましょう。

なお、今回の検証ではテーブルのレコード数が少ないためクエリを実行してもMySQLのオプティマイザは「わざわざRAPIDの並列処理を使うまでない」と判断してInnoDBを使って処理してしまいます。
これはMySQL HeatWaveのようなHTAPなデータベースのオプティマイザとして真っ当な動作です。もっとレコード数を多くしたパターンは改めて記事を書きます。スミマセン。
「オイオイ、わざわざMySQL HeatWaveを用意させておいてなんだよ。何が何でもHeatWaveで処理したいぜ」と言う御仁はオプティマイザヒントとして
```
/*+ set_var(use_secondary_engine=forced) */
```
をSQLステートメント内に入れておくと強制的にRAPIDにオフロードしてくれますのでexplainで実行計画を確認してみてください。
## 最後に
競合となるQlik ReplicateやそれをベースにしたAWS DMSと比べるとちょっと癖があるかなと言う印象がありますが、慣れの範疇だと思いますし、従来のエージェントを使用したGoldenGateに比べると導入の敷居は大幅に下がったと言えるでしょう。何と言っても思い立ったらクリック数発で即GoldenGateが使えることは素晴らしいです。
CDCを使った論理レプリケーションを様々なデータベース間のデータ連携と真面目に付き合っていくとターゲット側で文字化けや列の一部に欠損などに遭遇することがあります(この類の現象は論理レプリケーションの宿命と思います。筆者は商用環境でのCDCでのデータ移行プロジェクトで苦い経験が💨)のでOCI GoldenGateにOracle GoldenGate Varidataの機能がインクルードされるとOCI GoldenGateの価値が上がると思います。
#中の人からの「いや、そう言う機能は有るし」等のツッコミいただけると幸いです。