RDS for Oracle の Read Replicaからデータをエクスポートしてみた

# 1. はじめに
2023/8/2に[Amazon RDS for Oracle がシングルテナントインスタンスのレプリカをサポートする](https://aws.amazon.com/jp/about-aws/whats-new/2023/08/amazon-rds-oracle-replicas-single-tenant-instances/)という発表がありました。
RDS for Oracleがシングルテナントインスタンス（CDB構成）をサポートするようになったのはつい最近（2023/6/2）でしたが、[いくつかの制限事項がありました](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Oracle.Concepts.limitations.html#Oracle.Concepts.single-tenant-limitations)。その制限事項の一つに、Oracle Data Guardが入っていましたが、この発表で制限から除外されることになりました。（なお、8/10時点では[日本語のマニュアル](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Oracle.Concepts.limitations.html#Oracle.Concepts.single-tenant-limitations)は未アップデートです）

シングルテナントインスタンス（CDB構成）のData Guardが可能となったため、内部でData Guardの機能を利用しているRDS for OracleのRead Replicaも利用できるようになりました。（なお、非CDB構成のRead Replicaは以前から可能でした）

今回は、RDS for OracleのRead Replica(内部的にはActive Data GuardによるRead OnlyモードでのスタンバイデータベースのOPEN)からデータのエクスポートにチャレンジした結果を記載します。

###### Read Replicaとは？

RDS for OracleにおけるRead Replicaは二種類あります。Replicaサイトにて読みとり可能なRead Replicaと読みとりできないMounted Replicaがあります。今回はRead Replicaからデータをエクスポートしたいので、読みとり可能なRead Replicaを利用する必要があります。

|  | Read Replica<br>読みとりが可能 | Mounted Replica<br>読みとりできない |
| ---- | ---- | ---- |
| レプリカ側の起動モード | Read Only | MOUNT |
| プライマリとの同期方式 | 非同期 | 非同期 |
| 必要ライセンス | Enterprise Edition<br>+ Active Data Guard | Enterprise Edition |


また、RDSで実装されているMulti-AZとRead Replicaは以下のように目的が違いますので、ご注意ください。(出典：[Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/amazon-rds-multi-az-db-cluster/))

> - **マルチ AZ 配置**により、高可用性が実現され、自動フェイルオーバーが可能になります。Amazon RDS は、2 番目のアベイラビリティーゾーンにデータベースのストレージレベルのレプリカを作成します。その後、高可用性を実現するために、プライマリ DB インスタンスからスタンバイ DB インスタンスにデータを同期的にレプリケートします。プライマリ DB インスタンスがアプリケーションリクエストを処理しますが、スタンバイ DB インスタンスでは障害発生時に引き継ぐ準備が整っています。Amazon RDS は、障害検出、フェイルオーバー、修復アクションのあらゆる側面を管理し、データベースを使用するアプリケーションの可用性を高めます。
> 
> - **リードレプリカ**を使用すると、アプリケーションは複数のデータベースインスタンスにわたって読み取りオペレーションをスケールできます。データベースエンジンは、リードレプリカにデータを非同期的にレプリケートします。アプリケーションは書き込みリクエスト (INSERT、UPDATE、DELETE) をプライマリデータベースに送信し、読み取りリクエスト (SELECT) は複数のリードレプリカでロードバランスできます。プライマリノードに障害が発生した場合は、リードレプリカを新しいプライマリデータベースに手動で昇格させることができます。

# 2. RDS for Oracle の Read Replicaからデータをエクスポートしてみた

では、本題に入ります。
RDS for OracleのRead Replicaを作成し、そのRead Replicaからデータエクスポートができるか、確認してみます。エクスポートのイメージは次のような形です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/5a9b3648-fc5a-67f3-961f-a23153463de2.png)



## 2.1. RDS for OracleのRead Replicaを作成する
まずは、RDS for Oracleの読みとり可能な Read Replica を作成します。
ソースとなるRDS(testdb01)を選択し、アクションから「レプリカを作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/d1a840ac-51cd-79fe-7e79-8fa9a91d2f4a.png)

レプリカモードを選択できるため「読み取り専用」を選択し、作成先のリージョン・AZ等を選び「レプリカの作成」をクリックするとリードレプリカが作成されます。ちなみに、作成先のリージョンによってはリードレプリカのMulti-AZ化等が行えない場合があります(2023/8/10時点ではOsakaだとNG)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/0b2cc732-055e-5c20-5cef-129abe69fef2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/ac56df8a-e417-c343-9546-ea69b37e19e6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/bef76ab2-99c1-0765-ed20-d9f41892deaa.png)



## 2.2. RDS for OracleのRead Replicaからエクスポートしてみる
作成されたRead Replica(testdb01-rep)からexpdpを実行してみます。残念ながら「ORA-31633: unable to create master table "ADMIN.SYS_EXPORT_TABLE_xx"」というエラーが出て失敗しました。expdpではソースDB(testdb01-rep)上に管理表を一時的に作成するため、Read OnlyのRead Replicaからはexpdpが行えないようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/805373ef-75f3-1688-2f1d-967fafdff918.png)


```SQL:Read Replicaに対するexpdpの実行
$ expdp admin/xxxxxxxx@testdb01-rep.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:1521/testdb01 tables=testusr.testtbl dumpfile=dump_test01.dmp log=dump_test01.log directory=DPDIR_EFS

Export: Release 21.0.0.0.0 - Production on Thu Aug 6 07:29:33 2023
Version 21.8.0.0.0

Copyright (c) 1982, 2022, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
ORA-31626: job does not exist
ORA-31633: unable to create master table "ADMIN.SYS_EXPORT_TABLE_05"
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 95
ORA-06512: at "SYS.KUPV$FT", line 1163
ORA-16000: database or pluggable database open for read-only access
ORA-06512: at "SYS.KUPV$FT", line 1056
ORA-06512: at "SYS.KUPV$FT", line 1044
```

## 2.3. DMLリダイレクションの機能を利用してみる
調べてみると、Read Replicaを提供している機能、Active Data Guardは19cから[DMLリダイレクション](https://www.ashisuto.co.jp/db_blog/article/20191224_ADG_REDIRECT_DML.html)という新機能が導入されており、スタンバイ(Read Replica)側へのDMLをプライマリ側にリダイレクションしてくれる機能があるので、これを使えばできるかな？と思いましたが、前述のとおりexpdpではCreate文(DDL)が実行されているため、こちらでは実現できないようです。
また、RDS for OracleでのRead ReplicaではそもそもDMLリダイレクションを有効にするための設定(初期化パラメータ: ADG_REDIRECT_DML)を有効化できませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/e407fb62-e0f3-d452-74c7-f56439b717c6.png)

## 2.4. Snapshot Standbyの機能を利用してみる
さらに調べてみると、英語ですが [DataPump Export from Data Guard](https://dohdatabase.com/2021/04/22/datapump-export-from-data-guard/) というそのものズバリの機能があり、Read Replica(スタンバイ)側をSnapshot Standbyモードに一時的に変更することで、expdpが可能との記載がありました。
ただ、こちらも残念ながらRDS for OracleではRead ReplicaをSnapshot Standby モードに変更できないため、本環境では実現できませんでした。。

## 2.5. DB Proxy経由でエクスポートしてみる
結果としては難しいのかな、と思っていたところ、先ほどのblog([DataPump Export from Data Guard](https://dohdatabase.com/2021/04/22/datapump-export-from-data-guard/))の最後に、「How To Use DataPump Export (EXPDP) To Export From Physical Standby Database (Doc ID 1356592.1)」という方法について言及されていました。
確認すると、DB Proxyを経由することでエクスポートができるようになる、というものでした。DB Proxyの利用というのは、以下のようなイメージになります。(RDS for OracleがS3にエクスポートできるようになる前のエクスポート手法をイメージしてください)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/c5c567b0-42bc-7352-c41a-cc33bed52ed8.png)

testdb02というDB Proxyを作成し、testdb02からtestdb01のRead Replicaであるtestdb01-repへDB*LINKを作成します。

```SQL:DB*LINK作成
SQL> create database link replicarodb connect to admin identified by xxxxxxxx using 'testdb01-rep.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:1521/testdb01';

Database link created.
```

DB Proxy(DB*LINK)経由でエクスポートを実行すると、無事エクスポートができました。

```SQL:DB Proxy経由でのエクスポート
$ expdp admin/xxxxxxxx@testdb02.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:1521/testdb02 tables=testusr.testtbl dumpfile=stb2dump_test02.dmp log=stb2dump_test02.log network_link=replicarodb directory=DPDIR_EFS

Export: Release 21.0.0.0.0 - Production on Mon Aug 7 01:21:18 2023
Version 21.8.0.0.0

Copyright (c) 1982, 2022, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production
Legacy Mode Active due to the following parameters:
Legacy Mode Parameter: "log=stb2dump_test02.log" Location: Command Line, Replaced with: "logfile=stb2dump_test02.log"
Legacy Mode has set reuse_dumpfiles=true parameter.
Starting "ADMIN"."SYS_EXPORT_TABLE_01":  admin/xxxxxxxx@testdb02.xxxxxxxxxxxxcap-northeast-1.rds.amazonaws.com:1521/testdb02 tables=testusr.testtbl dumpfile=stb2dump_test02.dmp logfile=stb2dump_test02.log network_link=replicarodb directory=DPDIR_EFS reuse_dumpfiles=true
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
Processing object type TABLE_EXPORT/TABLE/TABLE
. . exported "TESTUSR"."TESTTBL"                         6.179 KB       1 rows
Master table "ADMIN"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for ADMIN.SYS_EXPORT_TABLE_01 is:
  /rdsefs-fs-xxxxxxxxxxxxxxxx/datapump/stb2dump_test02.dmp
Job "ADMIN"."SYS_EXPORT_TABLE_01" successfully completed at Mon Aug 7 10:22:29 2023 elapsed 0 00:00:54
```

# まとめ
一筋縄ではいきませんでしたが、無事RDS for OracleのRead Replicaからデータをエクスポートすることができました。プライマリ側に負荷をかけずにReplica側からデータを取得したい、というニーズは確実にあると思いますので、ちょっと手間はかかりますが必要な場合にはこのような形でエクスポートを行うことが可能です。ProxyはSE2でもOKですので、Liscense Include方式で一時的な利用を行うことも可能です。
必要な場合にはお試し下さい。

#### おまけ
実は従来型のexpツールの場合には、ソースDB(testdb01-rep)への管理表の作成等が行われないため、以下の形での実行が可能です。23cで従来型expはサポートアウトされてしまいましたが、使いやすいツールではありますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2313926/7676fc97-4430-05bb-7301-10299185e411.png)

```SQL:従来型exp
$ exp admin/xxxxxxxx@testdb01-rep.xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:1521/testdb01 tables=testusr.testtbl file=testexp.dmp log=testexp.log

Export: Release 21.0.0.0.0 - Production on Fri Aug 4 11:58:42 2023
Version 21.8.0.0.0

Copyright (c) 1982, 2022, Oracle and/or its affiliates.  All rights reserved.


Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.19.0.0.0
Export done in US7ASCII character set and AL16UTF16 NCHAR character set
server uses JA16SJISTILDE character set (possible charset conversion)

About to export specified tables via Conventional Path ...
Current user changed to TESTUSR
. . exporting table                        TESTTBL          1 rows exported
Export terminated successfully without warnings.
```