【Autonomous Database】DBMS_DATAPUMPパッケージを使用したエクスポート/インポート

# はじめに

ADBで [DBMS_DATAPUMPパッケージ](https://docs.oracle.com/cd/F19136_01/arpls/DBMS_DATAPUMP.html#GUID-AEA7ED80-DB4A-4A70-B199-592287206348) を使用してエクスポート/インポートをやってみました。


## 検証環境イメージ図

![検証環境イメージ図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/8b3c644f-c6ff-2556-8b51-87820c95c894.png)

## 前提
今回は、Autonomous Database に付属の Database Actionsの「SQL」を使用しSQL、PL/SQL を実行しています。

![dbactions.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/5fa85af1-86a2-928b-97c8-48be8486795f.png)

## 主な流れ
* １）動的グループ、ポリシー、リソース・プリンシパルを設定
* ２）テスト・ユーザーとテスト・データを作成
* ３）ADB内のディレクトリ・オブジェクトにテスト・データをエクスポート
* ４）ディレクトリ・オブジェクトから Object Storage バケットへダンプ・ファイルをコピー
* ５）テスト・データとディレクトリ・オブジェクト上のダンプ・ファイルを削除
* ６）Object Storage バケットからADBのディレクトリ・オブジェクトへダンプ・ファイルをコピー
* ７）ADBにインポート

# 手順
## １）動的グループ、ポリシー、リソース・プリンシパルを設定
### 動的グループの作成
`アイデンティティとセキュリティ` - `動的グループ` の `動的グループの作成` から動的グループを作成（動的グループの詳細は「[動的グループの管理](https://docs.oracle.com/ja-jp/iaas/Content/Identity/Tasks/managingdynamicgroups.htm)」）

* 設定例
検証環境のためコンパートメント内のすべてのリソースを許可していますが、マニュアルを参照しながら必要なものを設定してください。
![動的グループ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/4ad1f1d0-38ad-cb95-fd83-cbcc280c7b29.png)

### 動的グループにポリシーを付与
`アイデンティティとセキュリティ` - `ポリシー` の `ポリシーの作成` から動的グループにポリシーを付与

* 設定例
先程作成した動的グループを指定し、Object Storage バケットとバケット内のオブジェクトを管理できるようにポリシーを付与しています。

![ポリシー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/c5e02973-bbea-a45e-d357-b6c299530588.png)

```
Allow dynamic-group <先程作成した動的グループ名> to manage buckets in compartment <自身のコンパートメント>
Allow dynamic-group <先程作成した動的グループ名> to manage objects in compartment <自身のコンパートメント>
```

* 注意点
リソース・プリンシパル・トークンは2時間キャッシュされる。したがって、ポリシーまたは動的グループを変更した場合、変更の影響を確認するには2時間待つ必要がある。
    * 詳細はマニュアル「[Autonomous Databaseでリソース・プリンシパルを使用するための前提条件の実行](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/resource-principal-prereq.html#GUID-3CF59CED-F7DF-46AF-B3CF-E703ED0BB3EE)」を参照）


### リソース・プリンシパルの有効化
ADMINユーザーで実行
```sql
EXEC DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL();
```
リソース・プリンシパルが有効化されたか確認
```sql
SELECT owner, credential_name, username ,enabled FROM dba_credentials;
```
出力例
```sql
OWNER CREDENTIAL_NAME        USERNAME                                             ENABLED
----- ---------------------- ---------------------------------------------------- -------
ADMIN OCI$RESOURCE_PRINCIPAL ADMIN                                                TRUE
```

* 設定の詳細は
    * マニュアル：[Autonomous Databaseでリソース・プリンシパルを使用するための前提条件の実行](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/resource-principal-prereq.html#GUID-3CF59CED-F7DF-46AF-B3CF-E703ED0BB3EE)
* ポリシーの詳細
    * 「[ポリシーの仕組み](https://docs.oracle.com/ja-jp/iaas/Content/Identity/Concepts/policies.htm)」
* 動的グループ、ポリシーやリソース・プリンシパルの詳細
    * 「[OCI技術資料 : IDおよびアクセス管理 (IAM) 詳細](https://speakerdeck.com/ocise/ociji-shu-zi-liao-idoyobiakusesuguan-li-iam-xiang-xi)」

### ADBからObject Storageバケットを参照できるか確認（[DBMS_CLOUD.LIST_OBJECTSファンクション](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-52801F96-8280-4FE0-8782-E194F4360E6F)）
```sql
SELECT * FROM DBMS_CLOUD.LIST_OBJECTS('OCI$RESOURCE_PRINCIPAL', 'https://objectstorage.ap-osaka-1.oraclecloud.com/n/orasejapan/b/bucket-dump/o/');
```
出力例
```sql
OBJECT_NAME             BYTES CHECKSUM                 CREATED                  LAST_MODIFIED            
---------------------- ------ ------------------------ ------------------------ ------------------------ 
dumpfile/                   0 1B2M2Y8AsgTpgAmY7PhCfg== 2023-04-28T01:10:34.123Z 2023-04-28T01:10:34.123Z 
test.txt                    1 xMpCOKC5I4INzFCab3WEmw== 2023-04-28T00:43:43.053Z 2023-04-28T00:43:43.053Z 
```

## ２）テスト・ユーザーとテスト・データを作成
### テスト・ユーザーとテスト・データを作成
* `Database Actions` の `データベース・ユーザー「BENEE」`を作成
![DBUser.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449014/f4aa1ce3-864e-a49a-7a45-456d58a06ff0.png)


* `BENEE` にテスト・データを作成
```sql
create table emp(empno number(10), empname varchar2(10));
```
```sql
insert into emp(empno,empname) values(100,'TANAKA');
insert into emp(empno,empname) values(200,'SAITO');
insert into emp(empno,empname) values(300,'YOSHIDA');
```
```sql
commit;
```
```sql
select * from emp;
```
出力例
```sql
EMPNO EMPNAME
----- -------
  100 TANAKA
  200 SAITO
  300 YOSHIDA
```

## ３）ADB内のディレクトリ・オブジェクトにテスト・データをエクスポート
### ディレクトリ・オブジェクトの確認
* Database ActionsにADMINでログインし「SQL」にアクセスしディレクトリ・オブジェクトを確認
```sql
SELECT directory_name, directory_path FROM dba_directories WHERE directory_name = 'DATA_PUMP_DIR';
```
出力例
```sql
DIRECTORY_NAME DIRECTORY_PATH
-------------- ------------------------------------------------------
DATA_PUMP_DIR  /u03/dbfs/F8C*********/data/dpdump
```
※今回は、`DATA_PUMP_DIR` を使用します

* ディレクトリ・オブジェクトの内容を確認（[DBMS_CLOUD.LIST_FILESファンクション](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-78F49B25-C072-45E1-BE83-E306ACC998EE)）
```sql
SELECT * FROM DBMS_CLOUD.LIST_FILES('DATA_PUMP_DIR');
```
出力例
```sql
OBJECT_NAME                        BYTES CHECKSUM CREATED              LAST_MODIFIED
------------------------------- -------- -------- -------------------- --------------------
load_OML4PY_82.log                   358          2023-04-10T00:25:20Z 2023-04-10T00:25:20Z
automl_metamodels.dmp           10297344          2023-04-10T00:25:20Z 2023-04-10T00:25:20Z
OML4PY_IMPORT_84.log                7516          2023-04-10T00:25:27Z 2023-04-10T00:26:00Z
OUT_TRAN_1000MAN02$2_dflt.log          0          2023-04-10T01:26:51Z 2023-04-10T01:26:51Z
OUT_TRAN_1000MAN02$2_dflt.bad          0          2023-04-10T01:26:51Z 2023-04-10T01:26:51Z
OUT_TRAN_1000MAN02$2_198479.log     1649          2023-04-10T01:26:52Z 2023-04-10T01:27:50Z
```
デフォルトでいくつかファイルが入っています

### エクスポート（[DBMS_DATAPUMPパッケージ](https://docs.oracle.com/cd/F19136_01/arpls/DBMS_DATAPUMP.html#GUID-AEA7ED80-DB4A-4A70-B199-592287206348)）
* スキーマ単位でエクスポートをします

サンプルPL/SQL
```sql
DECLARE
  hdnl NUMBER;
    BEGIN
      hdnl := DBMS_DATAPUMP.OPEN(operation => 'EXPORT', job_mode => 'SCHEMA', job_name => null, version => 'COMPATIBLE');
      DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'exp_benee.dmp', directory => 'DATA_PUMP_DIR', filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE);
      DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'exp_benee.log', directory => 'DATA_PUMP_DIR', filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_LOG_FILE);
      DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_EXPR','IN (''BENEE'')');
      DBMS_DATAPUMP.START_JOB(hdnl);
END;
/
```

* ディレクトリ・オブジェクトに出力されたか確認（[DBMS_CLOUD.LIST_FILESファンクション](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-78F49B25-C072-45E1-BE83-E306ACC998EE)）
```sql
SELECT * FROM DBMS_CLOUD.LIST_FILES('DATA_PUMP_DIR') WHERE object_name like 'exp%';
```
出力例
```sql
OBJECT_NAME    BYTES CHECKSUM CREATED              LAST_MODIFIED
------------- ------ -------- -------------------- --------------------
exp_benee.dmp 360448          2023-04-28T01:02:05Z 2023-04-28T01:02:32Z
exp_benee.log   1517          2023-04-28T01:02:06Z 2023-04-28T01:03:37Z
```

## ４）ディレクトリ・オブジェクトから Object Storage バケットへダンプ・ファイルをコピー
[DBMS_CLOUD.PUT_OBJECT](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-716F0DE7-C669-477E-8AB8-EA42E41ACB12)を用い、ADBのディレクトリ・オブジェクトからObject Storageバケットにダンプ・ファイルをコピーします

```sql
BEGIN
    DBMS_CLOUD.PUT_OBJECT(
      credential_name =>  'OCI$RESOURCE_PRINCIPAL',
      object_uri      =>  'https://objectstorage.ap-osaka-1.oraclecloud.com/n/****/b/bucket-dump/o/dumpfile/exp_benee.dmp',
      directory_name  =>  'DATA_PUMP_DIR',
      file_name       =>  'exp_benee.dmp'
    );
END;
/
```
Object Storageにコピーされたか確認します（[DBMS_CLOUD.LIST_OBJECTSファンクション](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-52801F96-8280-4FE0-8782-E194F4360E6F)）
```sql
SELECT * FROM DBMS_CLOUD.LIST_OBJECTS('OCI$RESOURCE_PRINCIPAL', 'https://objectstorage.ap-osaka-1.oraclecloud.com/n/o****/b/bucket-dump/o/dumpfile/') WHERE object_name = 'exp_benee.dmp';
```
出力例
```sql
OBJECT_NAME    BYTES CHECKSUM                 CREATED                  LAST_MODIFIED
------------- ------ ------------------------ ------------------------ ------------------------
exp_benee.dmp 360448 gHmV3IfAC0H78rLivi98Lg== 2023-04-28T01:43:21.376Z 2023-04-28T01:43:21.376Z
```

* 補足
Cloud Object Storageに応じて、転送するオブジェクトのサイズは次のように制限されます（詳細は「[DBMS_CLOUD.PUT_OBJECT](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-716F0DE7-C669-477E-8AB8-EA42E41ACB12)」）

| Cloud Object Storageサービス|オブジェクト転送サイズの制限 | 
|:-----------:|:------------:|
|Oracle Cloud Infrastructure Object Storage|50GB|
|Amazon S3|5GB|
|Azure Blob Storage|256MB|
|Amazon S3互換|オブジェクト・ストア・プロバイダによって設定される。 詳細は、プロバイダ提供の資料を参照。|

## ５）テスト・データとディレクトリ・オブジェクト上のダンプ・ファイルを削除
### テスト・データを削除
ADMINユーザーでテスト・データを削除
```sql
DROP TABLE benee.emp CASCADE CONSTRAINTS PURGE;
```
削除されたか確認
```sql
SELECT object_name FROM DBA_OBJECTS WHERE OWNER = 'BENEE';
```

### ディレクトリ・オブジェクト上のダンプ・ファイルを削除
ディレクトリ・オブジェクトの内容をリスト（[DBMS_CLOUD.LIST_FILESファンクション](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-78F49B25-C072-45E1-BE83-E306ACC998EE)）
```sql
SELECT * FROM DBMS_CLOUD.LIST_FILES('DATA_PUMP_DIR') WHERE object_name like 'exp%';
```
出力例
```sql
OBJECT_NAME    BYTES CHECKSUM CREATED              LAST_MODIFIED
------------- ------ -------- -------------------- --------------------
exp_benee.dmp 360448          2023-04-28T01:02:05Z 2023-04-28T01:02:32Z
exp_benee.log   1517          2023-04-28T01:02:06Z 2023-04-28T01:03:37Z
```

ディレクトリ・オブジェクト内のファイルを削除（[DBMS_CLOUD.DELETE_FILEプロシージャ](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-930632E1-B7BF-4ECA-8F78-5E5A205C0865)）
```sql
BEGIN
  DBMS_CLOUD.DELETE_FILE(
    directory_name  =>  'DATA_PUMP_DIR',
    file_name       => 'exp_benee.dmp'
  );
END;
/
```
ディレクトリ・オブジェクトの内容をリスト（[DBMS_CLOUD.LIST_FILESファンクション](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-78F49B25-C072-45E1-BE83-E306ACC998EE)）
```sql
SELECT * FROM DBMS_CLOUD.LIST_FILES('DATA_PUMP_DIR') WHERE object_name like 'exp%';
```

## ６）Object Storage バケットからADBのディレクトリ・オブジェクトへダンプ・ファイルをコピー
Object Storageのダンプ・ファイル確認（[DBMS_CLOUD.LIST_OBJECTSファンクション](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-52801F96-8280-4FE0-8782-E194F4360E6F)）
```sql
SELECT * FROM DBMS_CLOUD.LIST_OBJECTS('OCI$RESOURCE_PRINCIPAL', 'https://objectstorage.ap-osaka-1.oraclecloud.com/n/orasejapan/b/bucket-dump/o/dumpfile/') WHERE object_name = 'exp_benee.dmp';
```
出力例
```sql
OBJECT_NAME    BYTES CHECKSUM                 CREATED                  LAST_MODIFIED
------------- ------ ------------------------ ------------------------ ------------------------
exp_benee.dmp 360448 gHmV3IfAC0H78rLivi98Lg== 2023-04-28T01:43:21.376Z 2023-04-28T01:43:21.376Z
```
Object StorageバケットからADBのディレクトリ・オブジェクトへダンプ・ファイルをコピー（[DBMS_CLOUD.GET_OBJECTプロシージャおよびファンクション](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-3DB888C9-18C7-4A26-8DA8-EDFB260E2B14)）

```sql
BEGIN
  DBMS_CLOUD.GET_OBJECT(
    credential_name => 'OCI$RESOURCE_PRINCIPAL',
    object_uri      => 'https://objectstorage.ap-osaka-1.oraclecloud.com/n/****/b/bucket-dump/o/dumpfile/exp_benee.dmp',
    directory_name  => 'DATA_PUMP_DIR',
    file_name       => 'exp_benee.dmp'
  );
END;
/
```
ディレクトリ・オブジェクトにコピーされたことを確認（[DBMS_CLOUD.LIST_FILESファンクション](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbms-cloud-subprograms.html#GUID-78F49B25-C072-45E1-BE83-E306ACC998EE)）
```sql
SELECT * FROM DBMS_CLOUD.LIST_FILES('DATA_PUMP_DIR') WHERE object_name like 'exp%';
```
出力例
```sql
OBJECT_NAME    BYTES CHECKSUM CREATED              LAST_MODIFIED
------------- ------ -------- -------------------- --------------------
exp_benee.dmp 360448          2023-04-28T02:03:30Z 2023-04-28T02:03:31Z
```

## ７）ADBにインポート（[DBMS_DATAPUMPパッケージ](https://docs.oracle.com/cd/F19136_01/arpls/DBMS_DATAPUMP.html#GUID-AEA7ED80-DB4A-4A70-B199-592287206348)）
スキーマ単位でインポート
```sql
DECLARE
  hdnl NUMBER;
    BEGIN
      hdnl := DBMS_DATAPUMP.OPEN(operation => 'IMPORT', job_mode => 'SCHEMA', job_name => null, version => 'COMPATIBLE');
      DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'exp_benee.dmp', directory => 'DATA_PUMP_DIR', filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE);
      DBMS_DATAPUMP.ADD_FILE( handle => hdnl, filename => 'imp_benee.log', directory => 'DATA_PUMP_DIR', filetype => DBMS_DATAPUMP.KU$_FILE_TYPE_LOG_FILE);
      DBMS_DATAPUMP.METADATA_FILTER(hdnl,'SCHEMA_EXPR','IN (''BENEE'')');
      DBMS_DATAPUMP.START_JOB(hdnl);
END;
/
```

テスト・データの確認
```sql
SELECT * FROM benee.emp;
```
出力例
```sql
EMPNO EMPNAME
----- -------
  100 TANAKA
  200 SAITO
  300 YOSHIDA

```
インポートの確認ができました
# 参考情報
* [Autonomous Database - Database Actions 機能概要](https://speakerdeck.com/oracle4engineer/autonomous-database-database-actions-ji-neng-gai-yao)
* [Oracle Autonomous Database on Shared Exadata Infrastructureの使用](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/index.html)（[英語版](https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/connect-database-actions.html#GUID-102845D9-6855-4944-8937-5C688939610F)）
    * [10 Autonomous Databaseでのディレクトリの作成および管理](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/create-manage-directory.html#GUID-5EC418F4-2084-4884-8D1E-BACA56F143F9)
    * [A Autonomous Databaseで提供されるパッケージのリファレンス](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/adbsa/dbmscloud-reference.html#GUID-52C9974C-D95E-4E41-AFBD-0FC4065C029A)
* Oracle Database 19c
    * PL/SQLパッケージおよびタイプ・リファレンス「[49 DBMS_DATAPUMP](https://docs.oracle.com/cd/F19136_01/arpls/DBMS_DATAPUMP.html#GUID-AEA7ED80-DB4A-4A70-B199-592287206348)」
    * データベース・リファレンス「[4.222 DBA_CREDENTIALS](https://docs.oracle.com/cd/F19136_01/refrn/DBA_CREDENTIALS.html#GUID-70AC7576-A1C9-4661-899B-8FDAC48DA54F)」
* Oracle Cloud Infrastructureドキュメント[ポリシーの仕組み](https://docs.oracle.com/ja-jp/iaas/Content/Identity/Concepts/policies.htm)
* Speakerdeck「[OCI技術資料 : IDおよびアクセス管理 (IAM) 詳細](https://speakerdeck.com/ocise/ociji-shu-zi-liao-idoyobiakusesuguan-li-iam-xiang-xi)」