Oracle DBからOCIオブジェクト・ストレージへデータをエクスポートする手順

本ブログは、[オラクル・クラウドの個人ブログ](https://qiita.com/letian/items/10152a4fec813c1b7d98)の1つです。

# 初めに
前回の記事では、オブジェクト・ストレージからOracle DB 19c/21cにデータをロードする方法を紹介しました。
[オブジェクト・ストレージからOracle DB 19c/21cにデータを導入する](https://qiita.com/liu-wei/items/398c91fd79a63eec6e7a)

その記事には、以下の<strong>３部分</strong>の内容を含めています。
- Oracle DBにDBMS_CLOUDをインストールする方法。
- DBMS_CLOUDで、OCIオブジェクト・ストレージからCSVファイルをOracle DBへロードする方法。
- DBMS_CLOUDで、OCIオブジェクト・ストレージからDUMPファイルを<strong>ローカルにコピー</strong>してから、Oracle DBへインポートする方法。

今回は、データ・ポンプ・ファイルをOracle DBから<strong>直接に（ローカルへのコピーは不要）</strong>OCIオブジェクト・ストレージへエクスポートする方法を紹介したいです（インポートの例も含める）。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/dd538fcc-c934-b94c-e8d7-a9c815215783.png" width="500">

__検証環境__
この例では、OCIのDB21c(VM)インスタンスを使用していますが、この方法はOn-PDBとCloud DBの両方を適用します。

DBバージョン：21c Standard Edition (シングル・ノード)
DBシステム・バージョン：<strong>21.4</strong>
リージョン：東京

__ステップ__

* STEP1~STEP9　以前の記事の手順と同様
* [STEP10 - エクスポートのための準備](#step10---エクスポートのための準備)
* [STEP11 - Oracle DBからOCIオブジェクト・ストレージへデータをエクスポート](#step11---oracle-dbcからociオブジェクトストレージへデータをエクスポート)
* [STEP12 - OCIオブジェクト・ストレージからOracle DBへデータをインポート（オプション）](#step12---ociオブジェクトストレージからoracle-dbへデータをインポートオプション)

Oracle DB(On-P/Cloud)の場合、DBMS_CLOUDは<font color=blue>プリインストールされていない</font>ため、使用する前にインストールと設定は必要です。

Autonomous DBの場合、DBMS_CLOUDは既に<strong>インストール済</strong>で、クレデンシャルの作成から実施すればよいです。詳しくは、以下の手順をご参照ください。
[Autonomous DBからOCIオブジェクト・ストレージへデータ・ポンプをエクスポートする手順](https://qiita.com/liu-wei/items/c6117d784b55b210403c)

||Oracle DB 19c<br>|Oracle DB 21c<br>|Autonomous DB|
|--|:--:|:--:|:--:|
|DBシステム・バージョン|19.13|21.4|-|
|DBMS_CLOUDはインストール済<br>であるか|No|No|<font color=blue>Yes</font>|
|<strong>直接</strong>にOCIオブジェクト・<br>ストレージにエクスポート|No|<font color=blue>Yes</font>|<font color=blue>Yes</font>|

__注意__
1. Oracle DB 19.13以下の場合、現時点(2022年1月)まで、まだDUMPファイルをOOS (OCI Object Storage)に<strong>直接</strong>エクスポートすることは<strong>できません</strong>。DUMPファイルをローカル・ディレクトリにエクスポートしてから、OOSにアップロードする必要があります。
2. 上記の情報は、このブログの投稿日である2022年1月現在のものです。

# STEP10 - エクスポートのための準備
__ディレクトリの作成__
DUMPファイル用のディレクトリを作成し、権限を対象ユーザ(USER01)に付与します。
("/u01/app/oracle/dmp"を事前に作成しておきます。)

```sql
SQL> show user;
USER is "SYSTEM"
SQL> CREATE OR REPLACE DIRECTORY TEST_DIR AS '/u01/app/oracle/dmp/';

Directory created.

SQL> GRANT READ, WRITE ON DIRECTORY TEST_DIR TO USER01;

Grant succeeded.

SQL>
```

__テスト用テーブルの準備__

```sql
SQL> desc CHANNELS;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 CHANNEL_ID                                         CHAR(1)
 CHANNEL_DESC                                       VARCHAR2(20)
 CHANNEL_CLASS                                      VARCHAR2(20)

SQL> select * from CHANNELS;

C CHANNEL_DESC         CHANNEL_CLASS
- -------------------- --------------------
S Direct Sales         Direct
T Tele Sales           Direct
C Catalog              Indirect
I Internet             Indirect
P Partners             Others

SQL> select count(*) from CHANNELS;

  COUNT(*)
----------
         5
```

__エクスポートの既存問題__
Oracle DB 21.3以降の場合、expdpを使用してOn-P/DBaaSからOCIオブジェクト・ストレージにエクスポートすると、次の問題が発生します。

```sql
[oracle@db21c dmp]$ expdp USER01/Your_Password@DB_Hostname_or_IP/db21cse_pdb1.publicsubnet1.vcn1.oraclevcn.com \
>      credential=TEST_CRED \
>      tables=CHANNELS \
>      dumpfile='https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNameSpace>/b/Bucket1/o/channels.dmp' \
>      logfile=export.log \
>      directory=TEST_DIR

Export: Release 21.0.0.0.0 - Production on Tue Jan 25 01:38:46 2022
Version 21.1.0.0.0

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

Connected to: Oracle Database 21c Standard Edition 2 Release 21.0.0.0.0 - Production
ORA-39001: invalid argument value
ORA-39000: bad dump file specification
ORA-31641: unable to create dump file "https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNameSpace>/b/Bucket1/o/channels.dmp"
ORA-27040: file create error, unable to create file
Linux-x86_64 Error: 2: No such file or directory
Additional information: 1


[oracle@db21c dmp]$
```

Oracleは、この問題を解決するために、次のMOSドキュメントを提供しています。 （アカウントは必要です）
[DATA PUMP EXPORT TO OCI OBJECT STORAGE FAILED ORA-39001 ORA-39000 ORA-31641 (Doc ID 2806178.1)](https://support.oracle.com/epmos/faces/DocumentDisplay?_afrLoop=150545848018733&id=2806178.1)

__原因__
オブジェクト・ストアODMライブラリは、デフォルトでは有効になっていません。

DBアラート・ファイルから、メッセージを確認してください。
DBアラート・ファイルの保存場所： 
`/u01/app/oracle/diag/rdbms/<Database_Unique_Name>/<Database_Name>/trace`
例: `/u01/app/oracle/diag/rdbms/db21cse_nrt12h/DB21cSE/trace`

「<strong>Database Unique Name</strong>（一意のデータベース名）」と「<strong>Database Name</strong>（データベース名）」の情報は、OCIコンソールから取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/8c2a58a1-cb4d-5b2a-13ea-d68e98abb67d.png)

```sql
[oracle@db21c ~]$ cd /u01/app/oracle/diag/rdbms/db21cse_nrt12h/DB21cSE/trace
[oracle@db21c trace]$ grep -i ODM alert_DB21cSE.log
......
Oracle instance running with ODM in SGA: FSDirect ODM Library Version 1.0
```

__解決方法__
次のコマンドを実行して、オブジェクト・ストアODMライブラリを有効にします。

`dbshut $ORACLE_HOME
cd $ORACLE_HOME/rdbms/lib
make -f ins_rdbms.mk opc_on
dbstart $ORACLE_HOME`

```sql
[oracle@db21c trace]$ dbshut $ORACLE_HOME
[oracle@db21c trace]$ cd $ORACLE_HOME/rdbms/lib
[oracle@db21c lib]$ make -f ins_rdbms.mk opc_on
rm -f /u01/app/oracle/product/21.0.0.0/dbhome_1/rdbms/lib/odm/libopcodm.so; \
    cp /u01/app/oracle/product/21.0.0.0/dbhome_1/lib/libopcodm.so /u01/app/oracle/product/21.0.0.0/dbhome_1/rdbms/lib/odm/libopcodm.so
[oracle@db21c lib]$ dbstart $ORACLE_HOME
[oracle@db21c lib]$
```

DBアラート・ファイルのメッセージをもう一度確認してください。

```sql
[oracle@db21c lib]$ cd /u01/app/oracle/diag/rdbms/db21cse_nrt12h/DB21cSE/trace
[oracle@db21c trace]$ grep -i ODM alert_DB21cSE.log
......
Oracle instance running with ODM in SGA: Object Store ODM Library Version 7.0
```

これで、エクスポートの再実行ができます。

# STEP11 - Oracle DBcからOCIオブジェクト・ストレージへデータをエクスポート
<strong>エクスポート用コマンド</strong>

`expdp user/password@<connection_string> \
     credential=credential_name \
     tables=table_name \
     dumpfile=https://objectstorage.ap-tokyo-1.oraclecloud.com/n/namespace-string/b/bucketname/o/export_file_name.dmp \
     logfile=export.log \
     directory=data_pump_dir`


```sql
[oracle@db21c dmp]$ expdp USER01/Your_Password@DB_Hostname_or_IP/db21cse_pdb1.publicsubnet1.vcn1.oraclevcn.com \
>      credential=TEST_CRED \
>      tables=CHANNELS \
>      dumpfile='https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNameSpace>/b/Bucket1/o/channels.dmp' \
>      logfile=export.log \
>      directory=TEST_DIR

Export: Release 21.0.0.0.0 - Production on Wed Jan 26 03:51:19 2022
Version 21.1.0.0.0

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

Connected to: Oracle Database 21c Standard Edition 2 Release 21.0.0.0.0 - Production
Starting "USER01"."SYS_EXPORT_TABLE_01":  USER01/********@DB_Hostname_or_IP/db21cse_pdb1.publicsubnet1.vcn1.oraclevcn.com credential=TEST_CRED tables=CHANNELS dumpfile=https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNameSpace>/b/Bucket1/o/channels.dmp logfile=export.log directory=TEST_DIR
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 "USER01"."CHANNELS"                         6.031 KB       5 rows
ORA-39173: Encrypted data has been stored unencrypted in dump file set.
Master table "USER01"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for USER01.SYS_EXPORT_TABLE_01 is:
  https://swiftobjectstorage.ap-tokyo-1.oraclecloud.com/v1/<ObjectStorageNameSpace>/Bucket1/channels.dmp
Job "USER01"."SYS_EXPORT_TABLE_01" successfully completed at Wed Jan 26 03:51:52 2022 elapsed 0 00:00:27

[oracle@db21c dmp]$
```
今回エクスポートは正常に動作しています。

__OCIコンソールからエクスポートされたダンプ・ファイルを確認__
以下のように２つファイルがバケットに新規作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/e24f7621-66b6-ce53-18ce-c76bab7052fe.png)

__DB 19cからのエクスポート__

上記と同じコマンドを使ってOracle DB 19c(<font color=blue>19.13以下</font>)からエクスポートしようとすると、次のようなエラーが発生します。そのため、現時点(2022年1月)まで、Oracle 19cからOCIオブジェクト・ストレージに<strong>直接エクスポートすることはできません</strong>。テーブルをローカル・ディレクトリにエクスポートしてから、データ・ポンプ・ファイルをオブジェクト・ストレージにアップロードする必要があります。

```sql
Connected to: Oracle Database 19c EE High Perf Release 19.0.0.0.0 - Production
ORA-39001: invalid argument value
ORA-39208: Parameter KU$_FILE_TYPE_URIDUMP_FILE is invalid for EXPORT jobs.
```
# STEP12 - OCIオブジェクト・ストレージからOracle DBへデータをインポート（オプション）
このステップはオプションです。エクスポートされたダンプ・ファイルが正常にインポートできることを確認します。

<strong>インポート用コマンド</strong>
`impdp user/password@<connection_string> \
     credential=credential_name \
     tables=table_name \
     table_exists_action=[SKIP|APPEND|TRUNCATE|REPLACE] \
     dumpfile=https://objectstorage.ap-tokyo-1.oraclecloud.com/n/namespace-string/b/bucketname/o/export_file_name.dmp \
     logfile=import.log`

```sql
[oracle@db21c ~]$ impdp USER01/Your_Password#@DB_Hostname_or_IP/db21cse_pdb1.publicsubnet1.vcn1.oraclevcn.com \
>      credential=TEST_CRED \
>      tables=CHANNELS \
>      table_exists_action=TRUNCATE \
>      dumpfile='https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNameSpace>/b/Bucket1/o/channels.dmp' \
>      logfile=import.log

Import: Release 21.0.0.0.0 - Production on Wed Jan 26 06:12:40 2022
Version 21.1.0.0.0

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

Connected to: Oracle Database 21c Standard Edition 2 Release 21.0.0.0.0 - Production
Master table "USER01"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded
Starting "USER01"."SYS_IMPORT_TABLE_01":  USER01/********@DB_Hostname_or_IP/db21cse_pdb1.publicsubnet1.vcn1.oraclevcn.com credential=TEST_CRED tables=CHANNELS table_exists_action=TRUNCATE dumpfile=https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNameSpace>/b/Bucket1/o/channels.dmp logfile=import.log
Processing object type TABLE_EXPORT/TABLE/TABLE
Table "USER01"."CHANNELS" exists and has been truncated. Data will be loaded but all dependent metadata will be skipped due to table_exists_action of truncate
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported "USER01"."CHANNELS"                         6.031 KB       5 rows
Processing object type TABLE_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER
Job "USER01"."SYS_IMPORT_TABLE_01" successfully completed at Wed Jan 26 06:12:47 2022 elapsed 0 00:00:04

[oracle@db21c ~]$
```

インポート後、テーブルの内容を確認します。

```sql
SQL> select * from channels;

C CHANNEL_DESC         CHANNEL_CLASS
- -------------------- --------------------
S Direct Sales         Direct
T Tele Sales           Direct
C Catalog              Indirect
I Internet             Indirect
P Partners             Others
```

以上

----
__関連記事__
[オラクル・クラウドの個人ブログ一覧](https://qiita.com/liu-wei/items/10152a4fec813c1b7d98)
[オブジェクト・ストレージからOracle DB 19c/21cにデータを導入する](https://qiita.com/liu-wei/items/398c91fd79a63eec6e7a)