データベースについて調べてみた

データベースについて調べたことのメモ。Oracle要素多めになる予定。

リフレッシュ可能PDBの作成手順を調べてみた

今回は、プラガブルデータベース(PDB)を使ったテスト環境の作り方を以前調査した際に存在を知って気になっていた、リフレッシュ可能PDBの作成手順について調べてみました。

 

1. リフレッシュ可能PDBとは

リフレッシュ可能PDBとは、ソースPDBからクローニングで作成したPDB(以降クローンPDBと表記)で、ソースPDBで発生した更新情報(REDOログ)を反映することで、ソースPDBと同期させることができる、読取り専用なクローンPDBです。同一CDB内でも異なるCDB間でも構成することが可能です。

ソースPDBとの同期処理(リフレッシュ)は、時間指定で自動的に行うことも、手動で行うことも可能ですが、リフレッシュする際は、リフレッシュ可能PDBをクローズ(PDBとしてはmount状態)する必要があります。

読取り専用なPDBである点や、ソースPDBREDOログ情報を用いてリフレッシュ可能PDBをリフレッシュさせる点、リフレッシュ時にはクローズ(mount)していないといけない点などから、リフレッシュ可能PDBは、DataGuardに非常に近しい機能と考えると、イメージしやすいかと思います。

 

 

2.作成手順

リフレッシュ可能PDBの手順について、以下のステップにわけて、実機確認した内容を記載していきます。

  • 準備作業
  • リフレッシュ可能PDBの作成
  • リフレッシュ動作の確認

今回の実機確認では、オンプレLinux x86-64版のOracle 19c(19.22.0)のRAC環境(TDE表領域なし)を使用し、ソースPDBと同一CDB内にリフレッシュ可能PDBを作成する構成(上図のA)で、手順確認を行いました。また、ソースPDB名とリフレッシュ可能PDB名は以下となります。

PDB種別 PDB
ソースPDB orclpdb
リフレッシュ可能PDB orclpdb_ref

 

2.1 準備

リフレッシュ可能PDBを作成するための準備作業として、以下を実施しました。

  • リフレッシュ可能PDBの要件充足確認
  • リフレッシュ可能PDBの格納領域準備
  • ネットサービス名の定義
  • DBリンク用共通ユーザの作成
  • DBリンクの作成

 

2.1.1 リフレッシュ可能PDBの要件充足確認

リフレッシュ可能PDBのソースとなるPDB(を収容しているCDB)は、以下2つの条件を満たしている必要があるため、それらが満たされていることを確認します。

  1. ARCHIVELOGモードであること
  2. ローカルUNDOモードであること

データファイルを格納するディレクトリを予め用意します。

-- ソースPDBが収容されているCDBへ接続
SQL> connect / as sysdba

-- アーカイブログモードの確認
SQL> SELECT log_mode FROM v$database;

LOG_MODE
------------
ARCHIVELOG  <---「ARCHIVELOG」であればOK

-- ローカルUNDOの確認
SELECT property_name, property_value FROM database_properties WHERE property_name = 'LOCAL_UNDO_ENABLED';

PROPERTY_NAME        PROPERTY_VALUE
-------------------- --------------------
LOCAL_UNDO_ENABLED   TRUE  <---「TRUE」であればOK

 

2.1.2 リフレッシュ可能PDBの格納領域準備

今回の環境はデータベースをASM内に格納する環境でしたので、リフレッシュ可能PDBのデータファイルを格納するディレクトリを予め用意します。

[grid]$ asmcmd mkdir +DATA/ORCLPDB_REF

 

2.1.3 ネットサービス名の定義

リフレッシュ可能PDBを作成する場合、同一CDB内であってもDBリンク経由でソースDBへ接続する必要があるため、ソースPDBに接続するためのネットサービス名(TNS接続文字列)を、リフレッシュ可能PDBが収容されるDBサーバ(※)上のtnsnames.ora内に定義します。また、リフレッシュ可能PDBに対してもリスナ経由で接続できるように、合わせて定義しておきます。
※今回リフレッシュ可能PDBはソースPDBと同一CDBに構成するため、ソースPDBと同じDBサーバ上のtnsnames.oraへの追記となります

# ソースPDB接続用
ORCLPDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = xxxxxxxxxx)(PORT = nnnn))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orclpdb)
    )
  )

# リフレッシュ可能PDB接続用
ORCLPDB_REF =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = xxxxxxxxxx)(PORT = nnnn))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orclpdb_ref)
    )
  )

 

2.1.4 DBリンク用共通ユーザの作成

DBリンクで使用する共通ユーザをソースPDBが収容されたCDB上に作成します。最初から存在しているSYSTEMユーザを使用してDBリンクを構成するのであれば、本作業は不要となる認識ですが、現実的にはセキュリティ要件などでSYSTEMユーザを安易に使用できないこともあるだろうと想定し、今回はユーザ(c##refusr)を作成しました。

リフレッシュ可能PDB向けDBリンクで使用するユーザを作成する際は、ソースPDBに対するCREATE PLUGGABLE DATABASE権限が必要なため、これを忘れず付与する必要があります。
なお、CREATE SESSION権限は、リフレッシュ可能PDBに関係なくDB接続に必要な権限なので、これも付与します。

-- DBリンク用ユーザの作成
SQL> CREATE USER c##refusr IDENTIFIED BY xxxxxxxx;
ユーザーが作成されました。

-- 必要権限の付与
SQL> GRANT CREATE SESSION TO c##refusr CONTAINER = ALL;
権限付与が成功しました。

SQL> GRANT CREATE PLUGGABLE DATABASE TO c##refusr CONTAINER = ALL;
権限付与が成功しました。

 

2.1.5 DBリンクの作成

リフレッシュ可能PDBを収容するCDB上で、ソースDBへのDBリンク(dl_orclpdb)を作成します。DBリンク作成時に(CONNECT TOに)指定するDBユーザは、先程作成したDBリンク用ユーザを、(USINGに指定する)ネットサービス名もtnsnames.oraに定義した、ソースPDBのネットサービス名(orclpdb)を指定します。

SQL> CREATE PUBLIC DATABASE LINK dl_orclpdb CONNECT TO c##refusr IDENTIFIED BY xxxxxxxx USING 'orclpdb';
データベース・リンクが作成されました。

 

 

2.2 リフレッシュ可能PDBの作成

リフレッシュ可能PDBは、CREATE PLUGGABLE DATABASE文を収容先のCDB上で実行して作成します。CREATE PLUGGABLE DATABASE文のポイントは、以下の2点です。

  1. ソースPDBの指定をDBリンク経由にする(緑字部分)
  2. REFRESH MODE句を指定する(青字部分)

なお、リフレッシュ可能PDBを作成する際、ソースPDBをクローズする必要はありません(ホットクローニングが可能)。また、リフレッシュは手動または自動を選択でき、以下は手動リフレッシュの例となります。自動リフレッシュを使用したい場合は、「MANUAL」部分を「EVERY <リフレッシュ間隔> [MINUTES | HOURS]」に変更してください。

SQL> CREATE PLUGGABLE DATABASE orclpdb_ref FROM orclpdb@dl_orclpdb
  2  FILE_NAME_CONVERT = ('+DATA/ORCL/ORCLPDB/', '+DATA/ORCL/ORCLPDB_REF/')
  3  REFRESH MODE MANUAL;
プラガブル・データベースが作成されました。

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 ORCLPDB                        READ WRITE NO
         5 ORCLPDB_REF                    MOUNTED

 

作成直後は、リフレッシュ可能PDBはクローズ状態(MOUNTED)なので、参照できるようにするためには、オープン状態にする必要があります。ただし、リフレッシュ可能PDBは読取り専用なので、READ ONLYでオープンする必要があります。

SQL> ALTER PLUGGABLE DATABASE orclpdb_ref OPEN READ ONLY;

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 ORCLPDB                        READ WRITE NO
         5 ORCLPDB_REF                    READ ONLY  NO

 

 

2.3 リフレッシュ動作の確認

リフレッシュ可能PDBがリフレッシュできているかの確認は、以下のステップで行います。

STEP ソースPDB
orclpdb
リフレッシュ可能PDB
orclpdb_ref
1 確認用テーブルの作成  
2 確認用テーブルの参照  
3   確認用テーブルの参照
4   PDBのクローズ
5   PDBのリフレッシュ
6   PDBのオープン
7   確認用テーブルの参照

 

2.3.1 確認用テーブルの作成【orclpdb】

ソースPDB(orclpdb)上に確認用のテーブル(t_tab)を作成して、レコードを1件格納しておきます。

SQL> connect test/xxxxx@orclpdb
接続されました。

SQL> CREATE TABLE t_tab(col01 NUMBER);
表が作成されました。

SQL> INSERT INTO t_tab VALUES(1);
1行が作成されました。

SQL> COMMIT;
コミットが完了しました。

 

2.3.2 確認用テーブルの参照【orclpdb】

ソースPDB上で確認用テーブルをSELECT作成して、レコードが表示されることを確認します。ここまではリフレッシュ動作確認の準備作業なので、特筆することはありません。

SQL> SELECT * FROM t_tab;

     COL01
----------
         1

 

2.3.3 確認用テーブルの参照【orclpdb_ref】

今度はリフレッシュ可能PDB側(orclpdb_ref)側で、ソースPDBで作成した確認用テーブルに対してSELECTを実行してみます。この時点ではまだリフレッシュをしていないため、確認用テーブルが存在しておらず、エラーが発生します。

SQL> connect test/xxxxx@orclpdb_ref
接続されました。

SQL> SELECT * FROM t_tab;
SELECT * FROM t_tab
              *
行1でエラーが発生しました。:
ORA-00942: 表またはビューが存在しません。

 

2.3.4 PDBのクローズ【orclpdb_ref】

リフレッシュ可能PDBをリフレッシュするため、収容しているCDBに接続し、PDBをクローズします。

SQL> connect / as sysdba
接続されました。

SQL> ALTER PLUGGABLE DATABASE orclpdb_ref CLOSE IMMEDIATE; 
プラガブル・データベースが変更されました。

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 ORCLPDB                        READ WRITE NO
         5 ORCLPDB_REF                    MOUNTED

 

2.3.5 PDBのリフレッシュ【orclpdb_ref】

PDBをクローズしたら、下記のALTER文でPDBをリフレッシュします。

SQL> ALTER PLUGGABLE DATABASE orclpdb_ref REFRESH;
プラガブル・データベースが変更されました。

 

2.3.6 PDBのオープン【orclpdb_ref】

PDBのリフレッシュが完了したら、PDBにアクセスできるように、再度PDBをオープンします。

SQL> ALTER PLUGGABLE DATABASE orclpdb_ref OPEN READ ONLY;

SQL> show pdbs

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 ORCLPDB                        READ WRITE NO
         5 ORCLPDB_REF                    READ ONLY  NO

 

2.3.7 確認用テーブルの参照【orclpdb_ref】

リフレッシュ可能PDBに再度接続し、確認用テーブルに対してSELECTを実施してみます。リフレッシュにより、ソースPDBで作成した確認用テーブルのREDO情報が伝搬・適用されたことで、今度はエラーが発生することなく、レコードを参照できることが確認できました。

SQL> connect test/xxxxx@orclpdb_ref
接続されました。

SQL> SELECT * FROM t_tab;

     COL01
----------
         1

 

 

3. おまけ

これでリフレッシュ可能PDBの作成手順と動作確認手順の紹介は終わりですが、最後に、リフレッシュ可能PDBの手順確認時に遭遇したエラーの紹介および、リフレッシュ可能PDBのAWRレポートが作成できるか試した結果、統合監査ログの取得確認結果を紹介します。

 

3.1 リフレッシュ可能PDB作成時に遭遇したエラー

今回リフレッシュ可能PDBの作成手順を実機確認した際に遭遇した、2つのエラーを参考までに紹介しておきます。

ORA-00922エラー

今回の手順確認では、ソースPDBと同一CDB内にリフレッシュ可能PDBを作成する前提で確認していたため、DBリンクを使用しないでリフレッシュ可能PDBを作成しようとしたところ、以下のエラーに遭遇しました。マニュアルのSQL言語リファレンスに記載された構文を見る限りでは、間違っている様に見えなかったため、原因に気が付くまで時間がかかりましたが、マニュアルの管理者ガイドに、リフレッシュ可能PDBの作成要件として、DBリンクが必要な旨が記載されていたのを見つけ、エラーを解消できました。

SQL> CREATE PLUGGABLE DATABASE orclpdb_ref FROM orclpdb
  2  FILE_NAME_CONVERT = ('+DATA/ORCL/ORCLPDB/', '+DATA/ORCL/ORCLPDB_REF/')
  3  REFRESH MODE MANUAL;
REFRESH MODE MANUAL
             *
行3でエラーが発生しました。:
ORA-00922: オプション指定されていないか、または無効です。

 

ORA-17628/ORA-01031エラー

もう1つは、下記の権限不足を示すエラーに遭遇しました。何の権限が足りないのか最初はわからず苦労しましたが、管理者ガイドに、クローニングにおけるデータベースリンクの前提条件として、DBリンクの接続ユーザにCREATE PLUGGABLE DATABASE権限が必要なことが記載されていたのを見つけ、エラーを解消することができました。改めてマニュアルの重要性に気づかされました…

SQL> CREATE PLUGGABLE DATABASE orclpdb_ref FROM orclpdb@dl_orclpdb
  2  FILE_NAME_CONVERT = ('+DATA/ORCL/ORCLPDB/', '+DATA/ORCL/ORCLPDB_REF/')
  3  REFRESH MODE MANUAL;
CREATE PLUGGABLE DATABASE orclpdb_ref FROM orclpdb@dl_orclpdb
*
行1でエラーが発生しました。:
ORA-17628: Oracleエラー1031がリモートOracleサーバーから返されました ORA-01031:
権限が不足しています

 

 

3.2 リフレッシュ可能PDB上でのPDBレベルのAWRレポート作成について

リフレッシュ可能PDBは読取り専用なので、AWRスナップショットはCDBで取得する必要がありますが、PDBレベルのAWRレポートは読取り専用のPDBからでも作成できるかと思い試してみたのですが、ORA-01403エラーが発生し、作成することができませんでした。

SQL> @?/rdbms/admin/awrrpt

(略)

Specify the location of AWR Data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AWR_ROOT - Use AWR data from root (default)
AWR_PDB - Use AWR data from PDB
awr_locationに値を入力してください:

Location of AWR Data Specified: AWR_ROOT


Current Instance
~~~~~~~~~~~~~~~~
DB Id          DB Name        Inst Num       Instance       Container Name
-------------- -------------- -------------- -------------- --------------
 3694512604     ORCL                        1 ORCL1          ORCLPDB_REF

declare
*
行1でエラーが発生しました。:
ORA-01403: データが見つかりません。 ORA-06512:
行60

SP2-0556: ファイル名が無効です。
SQL>

現時点では、awrrpt.sql内で実行されるSELECT結果が想定外に得られないことで、エラーになっていることは見えておりますが、原因は掴めていません。

もしかしたら、リフレッシュ可能PDBではPDBレベルのAWRレポートが作成できず、CDBレベルのAWRレポートからしか情報を得られないのかもしれません。何かわかったら、更新したいと思います。

 

★2024/08/15追記

MOSに本事象が記載されているドキュメントが公開されていました。

Doc ID 3039756.1: How To Create An AWR Report On Refreshable Clone PDB

エラー発生の詳細メカニズムは当該ドキュメントをご参照頂きたいですが、リフレッシュ可能PDBPDBレベルのAWRレポートを作成する場合は、awrrpt.sqlではなくawrrpti.sqlを使用することが案内されておりました。

awrrpti.sqlを使用することで、awrrpt.sqlの実行時にエラーとなったSELECTの実行が回避され、結果的にPDBレベルのAWRレポートを作成できることが確認できました。

 

 

3.3 リフレッシュ可能PDB上での統合監査ログの取得について

統合監査ログはデータベース内に監査ログを基本的に出力するため、読取り専用なリフレッシュ可能PDB上での操作に対する監査ログが取得できるかを確認しました。

以前書いた記事、「スタンバイデータベースで統合監査がどうなるか調べてみた」にて、スタンバイデータベースにおける統合監査ログは、スピルオーバー監査ファイル(拡張子.bin)というOSファイルに出力されると紹介しました。リフレッシュ可能PDBでも同様に、監査ログはスピルオーバー監査ファイルに出力されていることが確認できました。

監査ログの内容は、リフレッシュ可能PDB上でUNIFIED_AUDIT_TRAILディクショナリビューを参照することで表示できますが、ソースPDBのクローンPDBであるため、単にSELECTしてしまうとソースPDBの監査ログ情報も表示されてしまいます。

リフレッシュ可能PDBの監査ログだけ表示するためには、自PDBのdbidをWHERE句で指定したSELECT文を、下記の様に実行します。

-- リフレッシュ可能PDB上での操作
SQL> show user
ユーザーは"SYS"です。

SQL> show con_name
CON_NAME
------------------------------
ORCLPDB_REF

-- 自PDB(リフレッシュ可能PDB)のDBIDを確認
SQL> SELECT dbid FROM dba_pdbs;

      DBID
----------
3694512604

-- 自PDBの監査ログを出力
SELECT event_timestamp, sessionid, dbusername, action_name, sql_text
FROM unified_audit_trail
WHERE dbid = 3694512604
ORDER BY event_timestamp;

EVENT_TIMESTAMP                 SESSIONID DBUSERNAME ACTION_NAME     SQL_TEXT
------------------------------ ---------- ---------- --------------- -------------------------------
24-06-11 23:27:49.271882       2105079320 TEST       SELECT          select count(*) from tab02

 

 

次の記事:SQL*PlusからBLOBデータを登録/出力する方法を調べてみた

 

前回の記事:Oracle 23ai新機能のスキーマ権限について調べてみた