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

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

# 初めに
Autonomous DBからOCIオブジェクト・ストレージへデータをエクスポートするのは、一般的な要件です。今回は、データ・ポンプをエクスポートする方法を紹介したいと思います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/f6b97514-88a4-7dc8-763b-20675eb2570a.png", width="500">


※、「Computeインスタンス（クライアント） → Autonomous DB → サービスGW → オブジェクト・ストレージ」の流れは、すべてOCI内部の通信で完結する。

※、本記事には、エクスポートの準備に関連する以下の手順も含まれる。
- Oracle Linuxに、Oracle Instant Client (21c)をインストールする方法 ([STEP 1-5](#1-5-オラクルインスタントクライアントの準備))。
- Oracle Linuxから、SQL*Plusを使用してAutonomous DBに接続する方法 ([STEP 1-6](#1-6-クライアントからadbへの接続))。

__検証環境__
ADB ワークロード・タイプ: Autonomous Data Warehouse (Serverless)
アクセス・タイプ: <strong>プライベート・エンドポイント</strong>
Computeインスタンス：Oracle Linux <strong>8</strong> (VM)

__ステップ__

- [1. 事前準備](#1-事前準備)
  - [1-1. 関連ネットワーキング・リソースの設定](#1-1-関連ネットワーキングリソースの設定)
  - [1-2. 認証トークンの作成](#1-2-認証トークンの作成)
  - [1-3. バケットの作成](#1-3-バケットの作成)
  - [1-4. オブジェクト・ストレージ・ネームスペースの確認](#1-4-オブジェクトストレージネームスペースの確認)
  - [1-5. オラクル・インスタント・クライアントの準備](#1-5-オラクルインスタントクライアントの準備)
  - [1-6. クライアントからADBへの接続](#1-6-クライアントからadbへの接続)
  - [1-7. 検証用ユーザーとテーブルの準備](#1-7-検証用ユーザーとテーブルの準備)
- [2. クレデンシャルの作成](#2-クレデンシャルの作成)
- [3. エクスポートの実施](#3-エクスポートの実施)
  - [クイック・スタート](#クイックスタート) 
  - [テーブルサイズが大きい場合](#テーブルサイズが大きい場合)
- [4. インポートの実施（オプション）](#4-インポートの実施オプション)
- [付録](#付録)
  - [Cloud-init スクリプト](#cloud-init-スクリプト)

# 1. 事前準備

## 1-1. 関連ネットワーキング・リソースの設定
|タイプ|項目|内容|コメント|
|--|--|--|--|
|VCN|CIDR|10.0.0.0/16||
|プライベート・サブネット|CIDR|10.0.1.0/24|VMとADBの格納先|
|サービスGW|サービス|<strong>All \<Region-ID> Services in Oracle Services Network</strong> (※１)||
|ルート表<br>(サブネットに付ける)|ルール|ターゲット・タイプ: サービスGW<br>宛先サービス:<strong>All \<Region-ID> Services in Oracle Services Network</strong> (※１)||
|NSG (VM用)|Ingress|ソース CIDR: <strong>接続元のIP</strong><br>プロトコル: TCP, ポート: <strong>22</strong>|接続元からの通信を許可|
||Egress|<stron>ADBのプライベートIP, TCP <strong>1522</strong>|ADBへのアクセス<br>(sqlplus, expdp)|
||Egress|宛先タイプ：サービス<br>宛先サービス：<strong>All \<Region-ID> Services in Oracle Services Network</strong>|yum レポジトリへ|
|NSG (ADB用)|Ingress|ソース CIDR: <strong>VMのIP</strong><br>プロトコル: TCP, ポート: <strong>1522</strong>|DBクライアントからの通信を許可|
||Egress|宛先タイプ：サービス<br>宛先サービス：<strong>OCI \<Region-ID> Object Storage</strong>|オブジェクト・ストレージへ|

※１、オブジェクト・ストレージのみを利用する場合、"<strong>OCI \<Region-ID> Object Storage</strong>"を指定すればよいが、この例では、Computeインスタンスに、オラクル・インスタント・クライアントをインストールするため、サービスGWを経由して、yum <strong>レポジトリ</strong>にアクセスする。

外部から<strong>プライベート・サブネット内</strong>のVMに接続する際には、複数の方法があります。お好みの方法を選択してください。詳細については、以下の記事を参照してください。
[プライベート・サブネット内のOCI Computeインスタンスに接続する方法のまとめ](https://qiita.com/liu-wei/items/e0376fd71433d243bce0)

## 1-2. 認証トークンの作成
アイデンティティ → ドメイン → ドメイン名 → ユーザー → ユーザー名 → 認証トークン
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/aca14cda-be60-a950-5373-8e49e3c00212.png", width="500">

適当な説明を入力し、「トークンの作成」をクリックします
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/e54f3b9b-64d3-cd9a-ddc0-d2619ce3049a.png", width="400">

作成後、コピーしてください（二度と表示されないので、ご注意を）。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/c170f4e9-5192-feb7-8197-fd8b818193e0.png", width="400">
※、ユーザー毎、<strong>最大２個</strong>の認証トークンが作成できます。

## 1-3. バケットの作成
Autonomous DBと同じコンパートメントの下に、データ・ポンプ格納用のバケットを作成します。
※、公開の必要がなければ、デフォルトの<strong>プライベート</strong>にしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/b139b3e7-02f8-e50e-27ac-66541a08bf2d.png)

## 1-4. オブジェクト・ストレージ・ネームスペースの確認
OCIのオブジェクト・ストレージ・ネームスペースは、<strong>自動に付与される</strong>ものです。一部の古いテナンシは、ネームスペースとテナンシ名は同じですけど、そもそも<strong>別物</strong>なので、間違いようにご注意ください。

<font color=orange>AWS</font>は初クラウドの方は、特にこれをご注意ください。なぜかと言いますと、<strong>AWS S3のバケット名</strong>は、<strong>グローバル一意</strong>で、ネームスペースという概念がないわけです。

<font color=blue>Azure</font>は初クラウドの方は、このネームスペースをAzureの<strong>ストレージ・アカウント</strong>の名前だと理解していただければOKです。

プロファイル・アイコン(右上) → テナンシ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/b4568e02-162f-d7e3-6d7d-e6a072721228.png", width="200">

テナンシ詳細 → オブジェクト・ストレージ設定：
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/c160d0a4-177a-c345-274c-0f7985fc3988.png", width="550">
OCI CLIは既にインストールと設定済であれば、`oci os ns get`のコマンドでも簡単にネームスペースが取れます (Cloud Shellの場合、OCI-CLIのインストールは不要)。
```bat
$ oci os ns get
{
  "data": "<中略>"
}
```

## 1-5. オラクル・インスタント・クライアントの準備
Computeインスタンス（DBクライアント）から、expdpを実行しますので、事前にオラクル・インスタント・クライアントをインストールしてください。

以下は、<strong>Oracle Linux 8</strong>のコマンド例です（<strong>SQL*Plus</strong>と各種ツールをインストールする）。
※、expdpとimpdpは、`oracle-instantclient-tools`のパッケージに入っている。

- __1) インストール済かどうかをチェック__
```bash
[opc@linux8-client ~]$ sudo dnf list installed | grep instantclient
[opc@linux8-client ~]$
```

- __2) <strong>リリース・パッケージ</strong>のインストール__
```bash
[opc@linux8-client ~]$ sudo dnf install oracle-instantclient-release-el8 -y
<中略>
Installed:
  oracle-instantclient-release-el8-1.0-2.el8.x86_64

Complete!
[opc@linux8-client ~]$
```
- __3) <strong>SQL*Plusと各種ツール</strong>のインストール__
SQL*Plus: `sudo dnf install oracle-instantclient-sqlplus -y`
各種ツール: `sudo dnf install oracle-instantclient-tools -y`
（コマンドの結果を省略）
インストール後、もう一度チェックすると：
``` bash
[opc@linux-client ~]$ sudo dnf list installed | grep instantclient
oracle-instantclient-basic.x86_64                21.9.0.0.0-1.el8                            @ol8_oracle_instantclient21
oracle-instantclient-release-el8.x86_64          1.0-2.el8                                   @ol8_baseos_latest
oracle-instantclient-sqlplus.x86_64              21.9.0.0.0-1.el8                            @ol8_oracle_instantclient21
oracle-instantclient-tools.x86_64                21.9.0.0.0-1.el8                            @ol8_oracle_instantclient21
[opc@linux-client ~]$
```

下記場所に、SQL*Plusと各種ツールがインストールされました。
```bash
[opc@linux-client ~]$ ls  /usr/lib/oracle/21/client64/bin
adrci  exp  expdp  genezi  imp  impdp  sqlldr  sqlplus  wrc
[opc@linux-client ~]$
```

## 1-6. クライアントからADBへの接続
このステップは、SQL*Plusを使ってADBへの接続設定です。もちろん、SQL Devloperを使っていただいてもOKです。GUIツールの愛用者は、次の記事をご参照ください。
[Oracle LinuxでSQL Developerを利用する方法](https://qiita.com/liu-wei/items/46eb16dbd4f2d665c67f)

__環境変数の設定__
```bash
export ORACLE_HOME=/usr/lib/oracle/21/client64
export TNS_ADMIN=$ORACLE_HOME/lib/network/admin
export PATH=$PATH:$ORACLE_HOME/bin
```

__ADBウォレットの準備__
OCIコンソールから、ADBのウォレットをダウンロードし、DBクライアントにアップロードします（詳細を省略）。

ADBのウォレットを変数`TNS_ADMIN`に指定しているディレクトリに移動します。
```bash
[opc@linux-client ~]$ echo $TNS_ADMIN
/usr/lib/oracle/21/client64/lib/network/admin
[opc@linux-client ~]$ sudo mv Wallet_adwprivate.zip $TNS_ADMIN
[opc@linux-client ~]$
```

ウォレットの圧縮ファイルを解凍します。
```bash
[opc@linux-client ~]$ cd $TNS_ADMIN
[opc@linux-client admin]$ sudo mv README README.old
[opc@linux-client admin]$ sudo unzip Wallet_adwprivate.zip
Archive:  Wallet_adwprivate.zip
  inflating: ewallet.pem
  inflating: README
  inflating: cwallet.sso
  inflating: tnsnames.ora
  inflating: truststore.jks
  inflating: ojdbc.properties
  inflating: sqlnet.ora
  inflating: ewallet.p12
  inflating: keystore.jks
[opc@linux-client admin]$
```

__sqlnet.oraの編集__
次の行を編集し、Walletの保存先を置き換えます。
<font color=Magenta>編集前</font>：
```
WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY="?/network/admin")))
```

<font color=blue>編集後</strong>：
```
WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY="$TNS_ADMIN")))
```

__tnsnames.oraの情報を確認__
tnsnames.oraから、接続用のサービス名を確認します。
通常は以下となります。(dbname_high, dbname_medium, dbname_low)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/10f8fd2f-d2b4-2621-f394-19b0eb8a558a.png)

__SQL*PlusでADBに接続__
コマンド：`sqlplus <ユーザ名>/<パスワード>@<サービス名>`
```sql
[opc@linux-client admin]$ sqlplus admin/<replace_with_your_password>@adwprivate_high

SQL*Plus: Release 21.0.0.0.0 - Production on Wed Jul 12 07:48:03 2023
Version 21.9.0.0.0

Copyright (c) 1982, 2022, Oracle.  All rights reserved.

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

SQL>
```

## 1-7. 検証用ユーザーとテーブルの準備
__エクスポート専用ユーザーの作成__
管理者ユーザーで、次のSQLを実行して、エクスポート専用ユーザーを作成します。

※、<strong>既存ユーザーを利用</strong>したい場合、<strong>権限付与の部分</strong>（最後の３行）を実行してください（ユーザー名を置き換え）。この例では、`DWROLE`というロールを付与していますが、必ずそれを使わなければならないというわけではありません。

```sql
-- USER SQL
CREATE USER "DATA_PUMP_USER" IDENTIFIED BY "<replace_with_your_password>"  
DEFAULT TABLESPACE "DATA"
TEMPORARY TABLESPACE "TEMP";

-- QUOTAS
ALTER USER "DATA_PUMP_USER" QUOTA UNLIMITED ON "DATA";

-- ROLES
GRANT "DWROLE" TO "DATA_PUMP_USER";

-- SYSTEM PRIVILEGES
GRANT CREATE TABLE to DATA_PUMP_USER;
GRANT read, write on directory DATA_PUMP_DIR to DATA_PUMP_USER;
GRANT EXECUTE on DBMS_CLOUD to DATA_PUMP_USER;
```

__テーブルの準備__
検証用テーブルを用意します（ユーザー: `DATA_PUMP_USER`）。
```sql
SQL> select count(*) from zipcodejp;

  COUNT(*)
----------
    124523

SQL>
```

# 2. クレデンシャルの作成
ADBからOCIオブジェクト・ストレージへアクセスするため、クレデンシャルは必要です。

<strong>エクスポート対象のユーザー</strong>(DATA_PUMP_USER)でADBにログインします。DBMS_CLOUDを使って、クレデンシャルを作成します。（[STEP 1-2](#1-2-認証トークンの作成)で作成した認証トークンを使う。）

<strong>スクリプト</strong>：
BEGIN
<font color="blue">DBMS_CLOUD.CREATE_CREDENTIAL</font>(
<strong>credential_name</strong> => 'your credential name',
<strong>username</strong> => 'OCI user name',
<strong>password</strong> => 'auth token generated for OCI user'
);
END;
/

※、ユーザー名は、<strong>OCIユーザー</strong>であることにご注意ください（DBユーザーではない）。

作成例：
```sql
SQL> BEGIN
  2  DBMS_CLOUD.CREATE_CREDENTIAL(
  3  credential_name => 'EXPORT_CRED',
  4  username => '<replace_with_your_oci_user_name>',
  5  password => '<replace_with_your_auth_token>'
  6  );
  7  END;
  8  /

PL/SQL procedure successfully completed.

SQL>
```

__オブジェクト・ストレージへアクセス__
次のSQLコマンドで、出力先のバケットの中身を確認できます。
※、クレデンシャルを作成したDBユーザーで実行。

コマンド例：select * from <font color="blue">dbms_cloud.list_objects</font>('\<Credential_Name>','https://objectstorage.<strong>ap-tokyo-1</strong>.oraclecloud.com/n/<strong>ObjectStorageNameSpace</strong>/b/<strong>BucketName</strong>/o/');

- ObjectStorageNameSpace: [STEP 1-4](#1-4-オブジェクトストレージネームスペースの確認)で確認した内容
- BucketName: [STEP 1-3](#1-3-バケットの作成)で作成されたバケット名

この時点、まだエクスポートを実施していないので、カラの状態は想定通りです。
```sql
SQL> select * from dbms_cloud.list_objects('EXPORT_CRED','https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<replace_with_your_namespace>/b/Data_Pump/o/');

no rows selected

SQL
```

# 3. エクスポートの実施
## クイック・スタート
クライアントから、次のコマンドを実行して、エクスポートを開始します。
```bash
expdp DATA_PUMP_USER/<password>@adwprivate_high \
  credential=EXPORT_CRED \
  dumpfile=https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNamespace>/b/Data_Pump/o/data_pump_file.dmp \
  logfile=export.log \
  directory=data_pump_dir
```
パラメータの意味：
`credential`: 上記ステップで作成したクレデンシャルの名前
`dumpfile`: https:\//objectstorage.<strong>region</strong>.oraclecloud.com/n/<strong>ObjectStorageNameSpace</strong>/b/<strong>BucketName</strong>/o/<strong>ObjectName</strong>
`data_pump_dir`: ADBの標準ディレクトリです。次のコマンドで、ディレクトリの情報を確認できます。
`logfile`: ログの保存先は、ADBのディレクトリであり、クライアント側ではない。
```
SQL> select owner, directory_name, directory_path FROM dba_directories where directory_name='DATA_PUMP_DIR';

OWNER      DIRECTORY_NAME       DIRECTORY_PATH
---------- -------------------- ----------------------------------------------------------------------
SYS        DATA_PUMP_DIR        /u03/dbfs/FFA038E37518AFA8E0534310000AC205/data/dpdump

SQL>
```

__コマンドの出力結果__
```bash
[opc@linux-client ~]$ expdp DATA_PUMP_USER/<password>@adwprivate_high \
>   credential=EXPORT_CRED \
>   dumpfile=https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNamespace>/b/Data_Pump/o/data_pump_file.dmp \
>   logfile=export.log \
>   directory=data_pump_dir

Export: Release 21.0.0.0.0 - Production on Wed Jul 12 11:56:36 2023
Version 21.9.0.0.0

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

Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Starting "DATA_PUMP_USER"."SYS_EXPORT_SCHEMA_01":  DATA_PUMP_USER/********@adwprivate_high credential=EXPORT_CRED dumpfile=https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNamespace>/b/Data_Pump/o/data_pump_file.dmp logfile=export.log directory=data_pump_dir
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/ROLE_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/TABLESPACE_QUOTA
Processing object type SCHEMA_EXPORT/PASSWORD_HISTORY
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/COMMENT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/POST_SCHEMA/PROCOBJ
Processing object type SCHEMA_EXPORT/POST_SCHEMA/PROCACT_SCHEMA
. . exported "DATA_PUMP_USER"."ZIPCODEJP"                6.006 MB  124523 rows
ORA-39173: Encrypted data has been stored unencrypted in dump file set.
Master table "DATA_PUMP_USER"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Dump file set for DATA_PUMP_USER.SYS_EXPORT_SCHEMA_01 is:
  https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNamespace>/b/Data_Pump/o/data_pump_file.dmp
Job "DATA_PUMP_USER"."SYS_EXPORT_SCHEMA_01" successfully completed at Wed Jul 12 11:57:22 2023 elapsed 0 00:00:43

[opc@linux-client ~]$
```

__OCIコンソールから、オブジェクトを確認__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/c3cd985e-0cfc-31bf-ed73-8e93b2aa109d.png)
※、「`select * from dbms_cloud.list_objects('<Credential_Name>', '<Object_URL>');`」のコマンドでもオブジェクト一覧を確認できる。

ここまで、エクスポートは無事に完了しました。

## テーブルサイズが大きい場合
テーブルが大きくて、出力ファイルのサイズが大きい場合、ファイルの分割ができます。次は、<strong>5GB</strong>ごとでファイルを分割する例です。
```bash
expdp DATA_PUMP_USER/<password>@adwprivate_high \
  filesize=5GB \
  credential=EXPORT_CRED \
  dumpfile=https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNamespace>/b/Data_Pump/o/data_pump_file%U.dmp \
  parallel=16 \
  logfile=export.log \
  directory=data_pump_dir
```
出力ファイルの名前は、次のようです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/21be5a92-10bb-c168-b812-a1ca76407964.png", width="350">

# 4. インポートの実施（オプション）
エクスポートされたファイルを使って、インポート可否を試したほうがよいと思います。次は、指定したテーブルにインポートする例です。
```bash
impdp DATA_PUMP_USER/<password>adwprivate_high \
  credential=EXPORT_CRED \
  dumpfile=https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNamespace>/b/Data_Pump/o/data_pump_file.dmp \
  tables=ZIPCODEJP \
  table_exists_action=append \
  logfile=import.log \
  directory=data_pump_dir
```
コマンドの出力結果：
```bash
[opc@linux-client ~]$ impdp DATA_PUMP_USER/<password>@adwprivate_high \
>   credential=EXPORT_CRED \
>   dumpfile=https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNamespace>/b/Data_Pump/o/data_pump_file.dmp \
>   tables=ZIPCODEJP \
>   table_exists_action=append \
>   logfile=import.log \
>   directory=data_pump_dir

Import: Release 21.0.0.0.0 - Production on Wed Jul 12 13:28:59 2023
Version 21.9.0.0.0

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

Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Master table "DATA_PUMP_USER"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded
Starting "DATA_PUMP_USER"."SYS_IMPORT_TABLE_01":  DATA_PUMP_USER/********@adwprivate_high credential=EXPORT_CRED dumpfile=https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ObjectStorageNamespace>/b/Data_Pump/o/data_pump_file.dmp tables=ZIPCODEJP table_exists_action=append logfile=import.log directory=data_pump_dir
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Table "DATA_PUMP_USER"."ZIPCODEJP" exists. Data will be appended to existing table but all dependent metadata will be skipped due to table_exists_action of append
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Warning: Statistics not gathered while loading data for table "DATA_PUMP_USER.ZIPCODEJP"
. . imported "DATA_PUMP_USER"."ZIPCODEJP"                6.006 MB  124523 rows
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
Job "DATA_PUMP_USER"."SYS_IMPORT_TABLE_01" successfully completed at Wed Jul 12 13:29:07 2023 elapsed 0 00:00:06

[opc@linux-client ~]$
```

# トラブル・シューティング
- クレデンシャルを作成する時、次のエラーが発生した。
エラーメッセージ：`PLS-00904: insufficient privilege to access object C##CLOUD$SERVICE.DBMS_CLOUD`
可能の原因：実行したユーザーは、DBMS_CLOUDに対するアクセス権限がない。
対策：管理者より、対象ユーザーに権限を付与してから再作成する。

# 付録
## Cloud-init スクリプト
Computeインスタンス（DBクライアント）作成用のスクリプトです。
```bash
#!/bin/bash
sudo dnf install oracle-instantclient-release-el8 -y
sudo dnf install oracle-instantclient-sqlplus -y
sudo dnf install oracle-instantclient-tools -y

OPC_HOME=/home/opc
echo "# Env variables for Oracle Instant Client" >> ${OPC_HOME}/.bashrc
echo "export ORACLE_HOME=/usr/lib/oracle/21/client64" >> ${OPC_HOME}/.bashrc
echo 'export TNS_ADMIN=$ORACLE_HOME/lib/network/admin' >> ${OPC_HOME}/.bashrc
echo 'export PATH=$PATH:$ORACLE_HOME/bin' >> ${OPC_HOME}/.bashrc
source ${OPC_HOME}/.bashrc
```

----
__関連記事__
[オラクル・クラウドの個人ブログ一覧](https://qiita.com/liu-wei/items/10152a4fec813c1b7d98)
[Autonomous DBをエクスポート・インポートする方法のまとめ](https://qiita.com/letian/items/0c11c7871326f67d6e41)
[Oracle DBからOCIオブジェクト・ストレージへデータをエクスポートする手順](https://qiita.com/liu-wei/items/61f9df69b1b2a58c87c9)
[オブジェクト・ストレージからOracle DB 19c/21cにデータを導入する](https://qiita.com/liu-wei/items/398c91fd79a63eec6e7a)

----
__ドキュメント__ (英語)
[Oracle Instant Client Downloads](https://www.oracle.com/database/technologies/instant-client/downloads.html)
[Installing Oracle Instant Client Using RPMs](https://docs.oracle.com/en/database/oracle/oracle-database/21/lacli/install-instant-client-using-rpm.html)
[Connect SQL*Plus with a Wallet (mTLS)](https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/connect-sqlplus.html#GUID-A3005A6E-9ECF-40CB-8EFC-D1CFF664EC5A)