はじめに
以下の記事でも紹介されているとおり、Base Database Service(BaseDB)のSKU変更に伴い、今後OCPUベースからECPUベースへの環境移行が必要になるケースも考えられます。
OCI Base DB OCPUをBase DB ECPU に移行する
BaseDBはマルチテナント構成で、OCIコンソールからPDBをクローンできます。今回はこの機能を使って、OCPUベースからECPUベースへのデータベースの複製を試してみました。
利用したのは、一度クローンした後もソース側の変更を後から反映できる「リフレッシュ可能クローン」です。PDBを複製した後にソース側でデータを更新し、リフレッシュで差分を反映してから通常PDBへ変換するまでを確認しました。
SKU変更の詳細はOracle公式ドキュメントを参照してください。
本記事は個人の検証結果をまとめたものであり、所属する組織の公式見解を示すものではありません。サービスや機能の詳細は、Oracleの公式ドキュメントをご確認ください。
所要時間は今回の検証環境での実測値です。データ量や環境によって異なります。
検証環境
今回使用した環境は以下です。
| 項目 | ソース | ターゲット |
|---|---|---|
| CPUモデル | OCPUベース | ECPUベース |
| シェイプ | VM.Standard.E4.Flex | VM.BaseDB.x86 |
| CPU | 1 OCPU | 4 ECPU |
| データベース・エディション | Enterprise Edition | Enterprise Edition |
| データベース・バージョン | Oracle Database 19c | Oracle Database 19c |
| RU | 19.32 | 19.32 |
| CDB名 | BASEOCPU |
BASEECPU |
| PDB名 | BASEPDB |
BASEPDB |
ソースとターゲットは同じ可用性ドメイン(AD)、同じVCN内に配置しました。
リフレッシュ可能クローンは、異なるCDB間でPDBを複製し、その後もリフレッシュでソース側の変更を反映できる機能です。Base Database Serviceの公式ドキュメントでは、リフレッシュ可能クローンは同一AD内の異なるDBシステム/CDB間で利用できます。 PDBのクローン作成
移行イメージ図
切替前は、ソースPDBの更新をリフレッシュで移行先へ反映します。切替時はソースへの更新を停止し、最終リフレッシュ、通常PDBへの変換、アプリケーションの接続先切替を順に行う想定です。
1. ソースPDBにサンプルデータを作成
検証用のデータとして、Swingbenchの oewizard でスケール・ファクタ1のSOEスキーマを作成しました。
./swingbench/bin/oewizard \
-cl \
-create \
-cs "//<source-host>:1521/<source-pdb-service>" \
-dt thin \
-dba "sys as sysdba" \
-dbap "<Password>" \
-ts SOE \
-u SOE \
-p "<Password>" \
-scale 1 \
-tc 4 \
-allindexes \
-nopart \
-v
今回の作成結果は以下でした。
Data Generation Runtime Metrics
+-------------------------+-------------+
| Description | Value |
+-------------------------+-------------+
| Connection Time | 0:00:00.002 |
| Data Generation Time | 0:02:21.590 |
| DDL Creation Time | 0:01:54.731 |
| Total Run Time | 0:04:16.324 |
| Rows Inserted per sec | 112,047 |
| Actual Rows Generated | 15,741,058 |
| Commits Completed | 809 |
| Batch Updates Completed | 78,728 |
+-------------------------+-------------+
初期状態の主要テーブル件数も確認しておきます。
SELECT COUNT(*) AS orders_count,
MAX(order_id) AS max_order_id
FROM soe.orders;
SELECT COUNT(*) AS order_items_count
FROM soe.order_items;
ORDERS : 1,429,790
MAX_ORDER_ID : 1,429,790
ORDER_ITEMS : 7,022,645
2. データベース・リンク用の共通ユーザーを作成
CDB間のリフレッシュ可能クローンにはデータベース・リンクを利用します。
データベース・リンク用に、ソースCDBの CDB$ROOT で共通ユーザーを作成します。ユーザー名は C##PDBCLONE としました。
sqlplus / as sysdba
SHOW CON_NAME;
CDB$ROOT であることを確認します。
CON_NAME
------------------------------
CDB$ROOT
ユーザーを作成して権限を付与します。
CREATE USER C##PDBCLONE
IDENTIFIED BY "<Password>"
CONTAINER=ALL;
GRANT CREATE SESSION
TO C##PDBCLONE
CONTAINER=ALL;
GRANT CREATE PLUGGABLE DATABASE
TO C##PDBCLONE
CONTAINER=ALL;
GRANT SYSOPER
TO C##PDBCLONE
CONTAINER=ALL;
ユーザーを確認します。
SELECT con_id,
username,
common,
account_status
FROM cdb_users
WHERE username = 'C##PDBCLONE'
ORDER BY con_id;
CON_ID USERNAME COM ACCOUNT_STATUS
------ -------------- --- --------------
1 C##PDBCLONE YES OPEN
3 C##PDBCLONE YES OPEN
ターゲットDBシステムからソースCDBへの接続も確認します。
sqlplus 'C##PDBCLONE@//<source-host>:1521/<source-cdb-service> as sysoper'
SHOW CON_NAME;
SHOW CON_NAME の結果が CDB$ROOT であることを確認します。
CON_NAME
------------------------------
CDB$ROOT
3. リフレッシュ可能クローンを作成
OCIコンソールでソースのデータベース(baseocpu)を開き、「プラガブル・データベース」タブからクローン元PDB(basepdb)を選択します。PDBの詳細画面で「その他のアクション」→「クローン」を選択します。
「クローン・タイプ」に リフレッシュ可能クローン を選択します。
今回の入力内容は以下です。画面に従って各種パスワードも入力します。
クローン・タイプ : リフレッシュ可能クローン
宛先のDBシステム : baseecpu
宛先のデータベース : baseecpu
PDB名 : BASEPDB
データベース・リンク・ユーザー名 : C##PDBCLONE
クローン作成が完了しました。
今回の所要時間は以下でした。
受付 : 09:26:37 UTC
開始 : 09:26:48 UTC
終了 : 09:29:25 UTC
実処理時間は約2分37秒でした。
作成後、ターゲットCDBで確認します。
SELECT con_id, name, open_mode
FROM v$pdbs
ORDER BY con_id;
CON_ID NAME OPEN_MODE
---------- --------------- ----------
2 PDB$SEED READ ONLY
3 PDB READ WRITE
4 BASEPDB MOUNTED
DBA_PDBS も確認します。
SELECT pdb_name,
status,
refresh_mode,
refresh_interval,
last_refresh_scn
FROM dba_pdbs
WHERE pdb_name = 'BASEPDB';
PDB_NAME STATUS REFRES REFRESH_INTERVAL LAST_REFRESH_SCN
------------ ---------- ------ ---------------- ----------------
BASEPDB REFRESHING MANUAL 2772678
リフレッシュ可能クローン(STATUS=REFRESHING)として正常に作成されています。
2026/10/15追記
PDBのリフレッシュには差分反映のためアーカイブREDOログが必要になるケースがあります。
今回は自動バックアップ無効化環境で実施しましたが、自動バックアップ環境では必要なアーカイブREDOログがバックアップ側に退避されている可能性があります。
バックアップ側に退避される前に定期的にリフレッシュをするか、必要に応じてバックアップから必要なアーカイブREDOログをリストアしてリフレッシュをするなどの対応もご検討ください。
4. クローンをREAD ONLYで確認
リフレッシュ可能クローンはREAD ONLYで開いて参照できます。
ALTER PLUGGABLE DATABASE BASEPDB OPEN READ ONLY;
ALTER SESSION SET CONTAINER=BASEPDB;
SOEスキーマがコピーされていることを確認します。
SELECT username
FROM dba_users
WHERE username = 'SOE';
続いてデータ件数を確認します。
SELECT COUNT(*) AS orders_count,
MAX(order_id) AS max_order_id
FROM soe.orders;
SELECT COUNT(*) AS order_items_count
FROM soe.order_items;
ORDERS : 1,429,790
MAX_ORDER_ID : 1,429,790
ORDER_ITEMS : 7,022,645
ソース側の初期値と一致しています。
5. ソース側でSwingbenchを実行
次に、ソースPDBだけに更新を発生させます。
charbench を8ユーザー、3分間実行しました。
./swingbench/bin/charbench \
-c ./swingbench/configs/SOE_Server_Side_V2.xml \
-cs "//<source-host>:1521/<source-pdb-service>" \
-u SOE \
-p "<Password>" \
-uc 8 \
-rt 00:03 \
-v users,tpm,tps,errs,vresp
開始後は以下のようにトランザクションが流れます。
Results will be written to results.xml
Expected Benchmark Runtime is set to 3 minutes.
Time Users TPM TPS Errors NCR UCD BP OP PO BO SQ WQ WA
09:36:30 [0/8] 0 0 0 0 0 0 0 0 0 0 0 0
09:36:32 [0/8] 0 0 0 0 0 0 0 0 0 0 0 0
09:36:33 [8/8] 309 309 0 13 6 8 25 19 16 0 0 0
09:36:34 [8/8] 1116 807 0 8 3 5 19 7 6 0 0 0
:
3分後にソース側の件数を確認しました。
ORDERS : 1,480,473
MAX_ORDER_ID : 1,480,474
ORDER_ITEMS : 7,175,549
更新前との差分は以下です。
ORDERS : +50,683
ORDER_ITEMS : +152,904
一方、クローン側はまだリフレッシュ前のため初期値のままです。
ORDERS : 1,429,790
MAX_ORDER_ID : 1,429,790
ORDER_ITEMS : 7,022,645
6. リフレッシュを実行
リフレッシュ可能クローンをリフレッシュするには、PDBをMOUNTED状態にします。
Base Database Serviceでは、リフレッシュはPDBがMOUNTED状態のときのみ実行でき、READ ONLYでOPENしている状態ではリフレッシュできません。 PDBのリフレッシュ
まずクローンを閉じます。
ALTER SESSION SET CONTAINER=CDB$ROOT;
ALTER PLUGGABLE DATABASE BASEPDB CLOSE IMMEDIATE;
PDBがMOUNTED状態になっていることを確認します。
SHOW PDBS;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB READ WRITE NO
4 BASEPDB MOUNTED★
※ SQL出力中の「★」は、注目箇所を示すために追記しています。
OCIコンソールで以下を実行します。
ターゲットのデータベース(baseecpu)
→ 「プラガブル・データベース」タブ
→ BASEPDB行の右端にある「…」
→ 「リフレッシュ」
今回の所要時間は約34秒でした。
受付 : 09:44:37 UTC
開始 : 09:44:41 UTC
終了 : 09:45:15 UTC
7. リフレッシュ後のデータを確認
リフレッシュ完了後、再度READ ONLYで開きます。
ALTER PLUGGABLE DATABASE BASEPDB OPEN READ ONLY;
ALTER SESSION SET CONTAINER=BASEPDB;
件数を確認します。
SELECT COUNT(*) AS orders_count,
MAX(order_id) AS max_order_id
FROM soe.orders;
SELECT COUNT(*) AS order_items_count
FROM soe.order_items;
ORDERS : 1,480,473
MAX_ORDER_ID : 1,480,474
ORDER_ITEMS : 7,175,549
確認した2テーブルの件数と最大ORDER_IDは、ソース側の更新後の値と一致しています。
8. リフレッシュ可能クローンを通常PDBへ変換
最後にリフレッシュ可能クローンをソースから切り離し、通常PDBへ変換します。
OCIコンソールで以下を選択します。
ターゲットPDB(BASEPDB)の詳細画面
→ 「その他のアクション」
→ 「通常のPDBに変換」
変換画面では、SYSパスワードとTDEウォレット・パスワードを入力します。
検証環境では自動バックアップを無効にしているため、「PDB作成後すぐにバックアップを取得」も無効にして実行しました。
今回の処理時間は約1分13秒でした。
受付 : 09:51:04 UTC
開始 : 09:51:10 UTC
終了 : 09:52:23 UTC
OCI Base Database Serviceでは、リフレッシュ可能クローンを通常PDBへ変換することでソースPDBとのリフレッシュ関係を切り離せます。 リフレッシュ可能クローンから通常PDBへの変換
9. READ WRITEになったことを確認
ターゲットCDBの CDB$ROOT で、変換後のPDBを確認します。
SHOW PDBS;
CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB READ WRITE NO
4 BASEPDB READ WRITE★ NO
さらに DBA_PDBS を確認します。
SELECT pdb_name,
status,
refresh_mode
FROM dba_pdbs
WHERE pdb_name = 'BASEPDB';
PDB_NAME STATUS REFRES
---------- ---------- ------
BASEPDB NORMAL★ NONE
リフレッシュ可能クローンではなく、通常PDB(STATUS=NORMAL)になりました。
データも最終確認します。
ALTER SESSION SET CONTAINER=BASEPDB;
SELECT COUNT(*) AS orders_count,
MAX(order_id) AS max_order_id
FROM soe.orders;
SELECT COUNT(*) AS order_items_count
FROM soe.order_items;
ORDERS : 1,480,473
MAX_ORDER_ID : 1,480,474
ORDER_ITEMS : 7,175,549
確認した件数と最大ORDER_IDはソース側の最終値と一致しています。
検証結果
実処理時間は、作業リクエストの開始から終了までの時間です。
| 処理 | 実処理時間 |
|---|---|
| 初回クローン | 約2分37秒 |
| 差分リフレッシュ | 約34秒 |
| 通常PDBへの変換 | 約1分13秒 |
確認した2テーブルの件数は以下のとおりです。件数と最大ORDER_IDは、ソース側の更新後の値と一致しました。
| 項目 | 初期状態 | ソース側更新後 | ターゲット側リフレッシュ後 |
|---|---|---|---|
| ORDERS | 1,429,790 | 1,480,473 | 1,480,473 |
| ORDER_ITEMS | 7,022,645 | 7,175,549 | 7,175,549 |
| ORDERS差分 | - | +50,683 | 反映済み |
| ORDER_ITEMS差分 | - | +152,904 | 反映済み |
まとめ
OCPUベースのBase Database ServiceからECPUベースへPDBを複製し、リフレッシュで更新を反映できました。通常PDBへの変換後は、ECPU側でREAD WRITEになっていることも確認できました。
実際の切替では、通常PDBへの変換後にアプリケーションの接続先を切り替えることで、切替前までのデータ断面を継承しながら新環境で稼働を行う想定です。
おまけ:データベース・リンク用ユーザーの未作成によるクローン失敗
初回の試行では、データベース・リンク用ユーザーを作成せずにクローンを実行して失敗しました。
OCIコンソールの作業リクエストだけでは原因が分かりにくかったため、ターゲットDBシステムのDCSログを確認しました。
/opt/oracle/dcs/log/jobs/<job-id>.log
DBCA実行部分では、以下のようにデータベース・リンク用ユーザーとして C##PDBCLONE が指定されていました。
-createFromRemotePDB
...
-createAsRefreshablePDB true
-refreshMode MANUAL
...
-dbLinkUsername C##PDBCLONE
その直後に以下のエラーが記録されていました。
[DBT-15060] Specified user name: C##PDBCLONE is not a common user
[DBT-19404] Specified database link user (C##PDBCLONE)
does not exist in the database
指定した C##PDBCLONE がソースCDBに存在していないことが原因でした。手順2の共通ユーザー作成と接続確認を行い、再実行すると成功しました。













