はじめに
CREATE PLUGGABLE DATABASE ... RELOCATE AVAILABILITY MAX を使って、PDB を別の CDB へリロケート(移動)しようとしたところ、ORA-65348: unable to create pluggable database というエラーで止まってしまいました。
エラーメッセージだけでは、PDBを作成できなかったことしかわかりません。
前提条件を満たしていないだけであろうと、先入観を持ちエラーの内容自体を調べることを後回しにしてしまい
DBリンクの権限、変換先ディレクトリ、パスワード期限、アラートログ、トレースファイルなどを順番に調べました。しかし、いずれも原因ではありませんでした。
最終的に原因が分かったきっかけは、Oracleのエラー検索ツールであるoerrです。
この記事では、ORA-65348の調査で遠回りした経験と、「まずOERRを引くべきだった」という教訓を共有します。
検証環境
| 項目 | 内容 |
|---|---|
| OS | Oracle Linux 7(UEK 5.4) |
| DB | Oracle Database 19c EE 19.3.0.0.0 |
| VM | VMware Workstation 上の検証環境 |
| ソース CDB | SOURCE_CDB(PDB:SOURCE_PDB, SOURCE_PDB2) |
| ターゲット CDB | TARGET_CDB |
| リスナー | 両 CDB で同一ホストのリスナーを共有 |
SOURCE_CDBのSOURCE_PDBをTARGET_CDBへリロケートします。
PDB Relocate(リロケート)のおさらい
PDB リロケートは、ソースPDBをオープンしたまま(READ WRITE のまま)ホットクローンし、最後にターゲット側で OPEN した時点でソースを閉じて切り替える機能です。アンプラグ/プラグインと違い、停止時間をほぼゼロにできます。
AVAILABILITY句には 2 種類あります。
| 句 | 想定するリスナー構成 | 動作 |
|---|---|---|
AVAILABILITY NORMAL(デフォルト) |
共通のリスナー(同一リスナー、またはクロス登録) | 新しい場所でサービスが登録されるだけ。同一ホスト内の CDB 間ならこれで十分 |
AVAILABILITY MAX |
互いに独立したリスナー | ソース側のリスナーに転送先を設定し、旧接続先への接続を新しい場所へリダイレクトする |
前提条件の確認
マニュアルに記載されている主な前提条件を、実機で確認していきます。
ARCHIVELOG モード・ローカル UNDO
ソース側(SOURCE_CDB)とターゲット側(TARGET_CDB)の両方で確認します。
SQL> archive log list
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 10
Next log sequence to archive 12
Current log sequence 12
SQL> SELECT property_value FROM database_properties
2 WHERE property_name = 'LOCAL_UNDO_ENABLED';
PROPERTY_VALUE
--------------------------------------------------------------------------------
TRUE
TARGET_CDB 側も同様に、Archive Mode かつ LOCAL_UNDO_ENABLED = TRUE であることを確認しました。
DB リンクで接続するユーザーと権限
DB リンクはターゲット CDB に作成し、ソース CDB のルートに接続させます。接続するユーザーは共通ユーザーで、CREATE PLUGGABLE DATABASE 権限または SYSOPER 権限が必要です。
SQL> grant sysoper, create session, create pluggable database to system container=all;
Grant succeeded.
SYSOPER はパスワードファイルで管理される権限です。DB リンク経由のリモート接続で使えるか、次のように確認しておくと安心です。
sqlplus system/<password>@SOURCE_CDB as sysoper
ORA-65348が発生
準備が整ったので、リロケートを実行しました。PDB 名は、移動したことが分かるように RENAMED_PDB に変えました。
SQL> create pluggable database renamed_pdb from source_pdb@link_source
2 relocate availability max file_name_convert=('SOURCE_CDB','TARGET_CDB');
create pluggable database renamed_pdb from source_pdb@link_source
*
ERROR at line 1:
ORA-65348: unable to create pluggable database
ここでは、「PDBを作成できない」という結果しか書かれておらず、原因まで読み取れませんでした。
OERRやERROR HELP PORTALを確認せず、遠回りをしてしまった
ここで最初にoerrを実行すればよかったのですが、先に環境やログを調べてしまいました。
疑ったこと(すべてハズレ)
| 疑ったこと | 確認・対処 | 結果 |
|---|---|---|
| DB リンクのユーザーに SYSOPER がない |
GRANT SYSOPER ... CONTAINER=ALL を実行 |
変わらず |
| 変換先のディレクトリが存在しない |
mkdir -p .../TARGET_CDB/SOURCE_PDB を実行 |
変わらず |
| パスワードの猶予期間(ORA-28002)の警告 | パスワードを再設定 | 変わらず |
アラートログとトレースを見ても原因が分からない
TARGET_CDB のアラートログには、ORA-65348 signalled during: ... としか出ていません。
そこでエラースタックを取得してみました。
SQL> ALTER SESSION SET EVENTS '65348 trace name errorstack level 3';
$ grep -n "ORA-" /u01/app/oracle/diag/rdbms/target_cdb/TARGET_CDB/trace/TARGET_CDB_ora_11569.trc
29:ORA-65348: unable to create pluggable database
トレースにも ORA-65348 しか出ていません。さらに、ソース側(SOURCE_CDB)のアラートログには、リロケートを試した時刻の記録が一切ありませんでした。
まずOERRを実行すればよかった
調査を続けて行き詰った後、何気なくoerrコマンドを確認してみると、、、
$ oerr ora 65348
65348, 00000, "unable to create pluggable database"
// *Cause: An attempt was made to relocate a pluggable database with
// availability max clause using a target pluggable database
// name which is different from source pluggable database name.
// *Action: Use source pluggable database name as the target pluggable
// database name.
日本語にすると、次の内容
-
原因
AVAILABILITY MAX句を指定してPDBをリロケートしようとしたが、ターゲットPDBにソースPDBと異なる名前を使用した -
対処
ターゲットPDB名には、ソースPDBと同じ名前を使用する
そうです、「SOURCE_PDBをRENAMED_PDB」としたことが原因でした。
最初にOERRを実行していれば、原因も対処もすぐに特定できたことになります。
原因 AVAILABILITY MAX では PDB 名を変えられない
PDB名をソースと同じにしたところ、あっさり成功しました。
SQL> create pluggable database source_pdb from source_pdb@link_source
2 relocate availability max file_name_convert=('SOURCE_CDB','TARGET_CDB');
Pluggable database created.
一方、AVAILABILITY NORMAL であれば、別の名前でもリロケートできます。
なぜ同じ名前でないといけないのか
ここからは、機能の仕組みを踏まえた考察です。
PDBのデフォルト・サービス名は、PDB名と同じです。
AVAILABILITY MAX は、旧サービス名宛ての接続を新しい場所の同じサービス名へ転送する仕組みです。
そのため、PDB 名(=サービス名)が変わると転送先のサービスが存在しなくなり、転送が成り立他なくなると考えられます。
教訓 エラー発生時にはOERRを確認する
今回の調査で最も反省した点は、エラー番号が出ているにもかかわらず、エラーの内容を確認しなかった点です。
1. OERRでCauseとActionを確認
$ oerr ora 65348
または、Oracle Homeを明示して実行
$ $ORACLE_HOME/bin/oerr ora 65348
2. Oracle Error Helpを確認
OERRの内容に加え、公開されているOracle Error Helpも確認します。
今回のORA-65348については、OERRとOracle Error Helpのどちらにも、原因と対処が明確に書かれていました。
まとめ
今回は、権限、ディレクトリ、パスワード、アラートログ、トレースファイルと順に調べましたが、答えは最初からOERRに書かれていました。
「エラーが出たら、まずOERR」