ラベル マルチテナント の投稿を表示しています。 すべての投稿を表示
ラベル マルチテナント の投稿を表示しています。 すべての投稿を表示

2023年6月15日木曜日

APEX_SESSION.SET_TENANT_IDを活用する

最近、プロシージャAPEX_SESSION.SET_TENANT_IDを使ってAPEXアプリケーションをマルチテナントに対応させよう、という記事を読みました。Jon Dixsonさんが彼のブログより公開しています。

Building Multi-Tenant APEX Apps
https://blog.cloudnueva.com/multi-tenant-apex-apps

イタリアのRoberto Capancioniさんも記事を書いています。
Multitenant App with APEX

気になったので、自分でも使ってみようと思います。

Oracle APEXはアプリケーション・コンテキストのネームスペースとしてAPEX$SESSIONを用意しています。SYS_CONTEXT関数を呼び出して、ネーム・スペースAPEX$SESSIONよりAPP_ID、APP_SESSION、APP_USERといった値を参照できます。

SYS_CONTEXT関数から参照できる、APEXの組み込み置換文字列についてはマニュアルに記載があります。アプリケーション・コンテキストとして置換文字列の値を参照することには、いくつかの利点があります。
  1. V関数よりも高速である。V関数はPL/SQLによって実装されており、SELECT文にV関数が含まれていると、SQLとPL/SQLの実行エンジン間でのコンテキスト・スイッチが発生する。
  2. バインド変数と異なり、ビューを定義するSELECT文に含めることができる。
仮想プライベート・データベースにより同様の実装が可能ですが、その際は自前でネームスペースを作成する必要があります。APEX_SESSION.SET_TENANT_IDは、テナントの分離にパラメータを1つしか使わず、仮想プライベート・データベースまでは実装したくない、といった場合に手軽に活用できます。

簡単に言うと、APEX_SESSION.SET_TENANT_ID(p_tenant_id)を呼び出して設定した文字列は、SYS_CONTEXT('APEX$SESSION','APP_TENANT_ID')から参照できます。

サンプル・データセットのEMP/DEPTに含まれる表EMPを使って、APEX_SESSION.SET_TENANT_IDを使ったアプリケーションを作ってみます。

テナントを分離するパラメータとして列DEPTNOを使用します。列ENAMEの名前でアプリケーションにサインインすると、所属部門が同じ従業員(列DEPTNOの値が同じ)に限り参照できるようにします。

アプリケーション作成ウィザードを起動し、表EMPをソースとした対話モード・レポートのページを追加します。


追加する対話モード・レポートのページ名はEMPとします。表またはビュー、対話モード・レポートを選択し、表またはビューとしてEMPを選択します。フォームを含めるにチェックを入れます。


以上の設定でアプリケーションを作成します。

APEX_SESSION.SET_TENANT_IDは、サインイン時に実行される認証スキームの認証後のプロシージャ内で呼び出します。サインインの処理が完了した後にAPEX_SESSION.SET_TENANT_IDを呼び出し、APP_TENANT_IDを変更することはできません。

表EMPの列ENAMEの値でサインインする認証スキームを作成します。その認証スキームの認証後のプロシージャよりAPEX_SESSION.SET_TENANT_IDを呼び出し、APP_TENANT_IDを設定します。

共有コンポーネントの認証スキームを開きます。


作成済みの認証スキームが一覧されます。作成をクリックします。


スキームの作成はギャラリからの事前構成済スキームに基づくを選択します。

次に進みます。


作成する認証スキームの名前は任意ですが、今回はENAMEでサインインとしました。スキーム・タイプとして公開資格証明を選択します。これは主にテストに使用する、ユーザー名だけでサインインする認証スキームです。


認証スキームが作成され、カレントの認証スキームになります。

ソースのPL/SQLコードに以下を記述します。サインインしたユーザ名で表EMPを検索し、見つかった従業員の部門コード(列DEPTNOの値)をAPP_TENANT_IDに設定しています。


プロシージャset_tenantをログイン・プロセスの認証後のプロシージャ名に記述します。


以上でアプリケーション・コンテキストAPP_TENANT_IDの設定は完了です。

対話モード・レポートの列DEPTNOが数値で表示されるよう、識別のタイプをプレーン・テキストに変更します。


アプリケーションを実行します。

公開資格証明のサインインが要求されるので、SCOTTでサインインします。


今の所、アプリケーション・コンテキストのAPP_TENENT_IDは設定されていますが、アプリケーション側に何も制限はかかっていません。そのため表EMPのすべての行が表示されます。

SCOTTのDEPTNOは40で、同じ部門の従業員はMARTINのみです。


対話モード・レポートにAPP_TENANT_IDを使った制限を加えます。

ソースのWHERE句に以下の条件を記述します。

DEPTNO = SYS_CONTEXT('APEX$SESSION','APP_TENANT_ID')


ページを実行すると、SCOTTとMARTINに表示が限定されることが確認できます。


APP_TENANT_IDを使って検索結果を制限することができましたが、表EMPがデータ・ソースに現れる度にWHERE句を追加するのは大変です。

表EMP(列DEPTNOを持つ表)を扱う際には、常にAPP_TENANT_IDで制限されるようにビューEMP_SVを作成します。そして表EMPの代わりにビューEMP_SVを指定することにより、アプリケーションのどこでも所属している部門のデータだけが扱えるように制限します。
create or replace view emp_sv
as
select empno, ename, job, mgr, hiredate, sal, comm from emp
where deptno = sys_context('APEX$SESSION','APP_TENANT_ID');

ビューEMP_SVは列DEPTNOを含んでいません。このビューに新規行を挿入すると、このままでは列DEPTNOが空白になります。列DEPTNOにAPP_TENANT_IDの値が設定されるよう、トリガーを作成します。



以上で準備は完了です。

ページ作成ウィザードを使って、ビューEMP_SVをデータ・ソースとした対話モード・レポートとフォームのページを作成します。


対話モード・レポートを選択します。


ページ定義のフォーム・ページを含めるにチェックを入れます。データ・ソースの表/ビューの名前としてEMP_SVを指定します。

次へ進みます。


主キー列1としてEMPNO(Number)を選択します。

ページの作成をクリックします。


以上の操作により、ビューEMP_SVをデータ・ソースとした対話モード・レポートとフォームのページが作成されます。

表EMPをデータ・ソースとした場合と、手順に違いはありません。


対話モード・レポートおよびフォームの操作からは、扱えるデータが制限されていることは分かりません。新規行を作成していますが、トリガーによってAPP_TENANT_IDが列DEPTNOに設定されているため、作成した行がレポートに表示されます。


APEXアプリケーションでのAPEX_SESSION.SET_TENANT_IDの活用は以上になります。

ビューEMP_SVに適用している条件がアクセス制限として適切なのかどうかを、APEXアプリケーションにアクセスして検証するのはあまり現実的ではありません。

APEXではコマンド・ラインの接続よりAPEXのセッションを作成するAPIとして、APEX_SESSION.CREATE_SESSIONを提供しています。このAPIの引数p_call_post_authenticationにtrueを渡すことにより、今回APEX_SESSION.SET_TENANT_IDを呼び出すために記述した認証後のプロシージャが実行されます。

これらの機能を使って、コマンド・ラインからビューEMP_SVを検索することができます。

SQL> begin

  2  apex_session.create_session(

  3  p_app_id => 222,

  4  p_page_id => 1,

  5  p_username => 'SCOTT',

  6  p_call_post_authentication => true

  7  );

  8  end;

  9* /


PL/SQLプロシージャが正常に完了しました。


SQL> select * from emp_sv;


   EMPNO     ENAME          JOB     MGR    HIREDATE     SAL    COMM 

________ _________ ____________ _______ ___________ _______ _______ 

    7788 SCOTT     PRESIDENT       7566 82-12-16       4000     300 

    7654 MARTIN    CLERK           7698 81-09-28       1250    1400 


SQL> 


色々な条件のテスト・スクリプトを準備することにより、APP_TENANT_IDによるデータの分離が適切かどうかユーザー・インターフェースへアクセスせずに検証することができます。

本記事は以上になります。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-set-tenant-id.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。

完

2023年6月1日木曜日

Oracle APEXのアップグレード(3) - 色々なクローン手順

 オラクル・データベースのマルチテナントの機能として提供されている、色々なクローン手順を使って、アプリケーションのテストを行う環境を作ってみます。

手順の検証に、Oracle Cloudのコンピュート・インスタンスにインストールしたOracle Database 23c Freeを使用しています。

以下の3種類のクローン方法を紹介します。

  1. データベース・リンク経由でリフレッシュ可能クローンを作成する。
  2. リフレッシュ可能クローンから更新可能なクローンを作成する。
  3. 更新可能クローンをリード・オンリーに変更し、そのスナップショット・コピーを作成する。

プロダクションの環境を想定しているコンピュート・インスタンスがひとつあり、PDBとしてFREEPDB1が作成済みとします。

テスト環境として想定しているコンピュート・インスタンスがひとつあり、シード以外のPDBは未作成という状態から始めます。


準備作業1 - ポート1521の通信許可


リモート・クローンに使用するデータベース・リンクを作成するため、ポート番号1521の通信を許可します。プロダクションとテストの双方のコンピュート・インスタンスで実施します。

firewalldで禁止されているTCPの1521番ポートへの接続を許可します。

firewall-cmd --add-port=1521/tcp
firewall-cmd --runtime-to-permanent
firewall-cmd --list-ports


[root@apex-prod ~]# firewall-cmd --add-port=1521/tcp

success

[root@apex-prod ~]# firewall-cmd --runtime-to-permanent

success

[root@apex-prod ~]# firewall-cmd --list-ports

1521/tcp

[root@apex-prod ~]#


Oracle Database 23c Freeのインストールでは、TNSリスナーはデフォルトでlocalhostにバインドしています。

netstat -an | grep 1521 | grep LISTEN

[oracle@apex-prod admin]$ netstat -an | grep 1521 | grep LISTEN

tcp        0      0 127.0.0.1:1521          0.0.0.0:*               LISTEN     

unix  2      [ ACC ]     STREAM     LISTENING     27618    /var/tmp/.oracle/sEXTPROC1521

[oracle@apex-prod admin]$ 


この状態では、localhost以外からの接続を受け付けません。

一旦、TNSリスナーを停止します。

lsnrctl stop

[oracle@apex-test admin]$ lsnrctl stop


LSNRCTL for Linux: Version 23.0.0.0.0 - Developer-Release on 01-JUN-2023 09:32:51


Copyright (c) 1991, 2023, Oracle.  All rights reserved.


Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))

The command completed successfully

[oracle@apex-test admin]$ 


$ORACLE_HOME/network/admin以下のlistener.oraに含まれるHOSTの指定をlocalhostから0.0.0.0へ変更します。

DEFAULT_SERVICE_LISTENER = FREE


LISTENER =

  (DESCRIPTION_LIST =

    (DESCRIPTION =

      (ADDRESS = (PROTOCOL = TCP)(HOST = 0.0.0.0)(PORT = 1521))

      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))

    )

  )


TNSリスナーを起動し、バインドしているIPアドレスが127.0.0.1から0.0.0.0に変わっていることを確認します。

lsnrctl start
netstat -an | grep 1521 | grep LISTEN

[oracle@apex-test admin]$ lsnrctl start


LSNRCTL for Linux: Version 23.0.0.0.0 - Developer-Release on 01-JUN-2023 09:48:50


Copyright (c) 1991, 2023, Oracle.  All rights reserved.


Starting /opt/oracle/product/23c/dbhomeFree/bin/tnslsnr: please wait...


TNSLSNR for Linux: Version 23.0.0.0.0 - Developer-Release

System parameter file is /opt/oracle/product/23c/dbhomeFree/network/admin/listener.ora

Log messages written to /opt/oracle/diag/tnslsnr/apex-test/listener/alert/log.xml

Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))

Listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))


Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=0.0.0.0)(PORT=1521)))

STATUS of the LISTENER

------------------------

Alias                     LISTENER

Version                   TNSLSNR for Linux: Version 23.0.0.0.0 - Developer-Release

Start Date                01-JUN-2023 09:48:50

Uptime                    0 days 0 hr. 0 min. 0 sec

Trace Level               off

Security                  ON: Local OS Authentication

SNMP                      OFF

Default Service           FREE

Listener Parameter File   /opt/oracle/product/23c/dbhomeFree/network/admin/listener.ora

Listener Log File         /opt/oracle/diag/tnslsnr/apex-test/listener/alert/log.xml

Listening Endpoints Summary...

  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=0.0.0.0)(PORT=1521)))

  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))

The listener supports no services

The command completed successfully

[oracle@apex-test admin]$ netstat -an | grep 1521 | grep LISTEN

tcp        0      0 0.0.0.0:1521            0.0.0.0:*               LISTEN     

unix  2      [ ACC ]     STREAM     LISTENING     53617    /var/tmp/.oracle/sEXTPROC1521

[oracle@apex-test admin]$ 


Oracle Cloudの設定であるセキュリティ・リストのイングレス・ルールで、TCPの1521番ポートを許可します。


以上でオラクル・データベースへのリモート接続の準備ができました。


準備作業2 -  アーカイブログ・モードに変更



データベースをアーカイブ・ログ・モードに変更します。

最初にアーカイブログ・モードを確認します。

archive log list

SQL> archive log list

Database log mode       No Archive Mode

Automatic archival       Disabled

Archive destination       /opt/oracle/product/23c/dbhomeFree/dbs/arch

Oldest online log sequence     4

Current log sequence       6

SQL> 


Database log modeがNo Archive Modeであれば、Archive Log Modeに変更します。

shutdown immediate
startup mount
alter database archivelog;
shutdown
startup

SQL> shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

SQL> startup mount 

ORACLE instance started.


Total System Global Area 1222532352 bytes

Fixed Size   10042624 bytes

Variable Size   536870912 bytes

Database Buffers   671088640 bytes

Redo Buffers     4530176 bytes

Database mounted.

SQL> alter database archivelog;


Database altered.


SQL> shutdown 

ORA-01109: database not open



Database dismounted.

ORACLE instance shut down.

SQL> startup

ORACLE instance started.


Total System Global Area 1222532352 bytes

Fixed Size   10042624 bytes

Variable Size   536870912 bytes

Database Buffers   671088640 bytes

Redo Buffers     4530176 bytes

Database mounted.

Database opened.

SQL> 


変更を確認します。

archive log list

SQL> archive log list

Database log mode       Archive Mode

Automatic archival       Enabled

Archive destination       /opt/oracle/product/23c/dbhomeFree/dbs/arch

Oldest online log sequence     4

Next log sequence to archive   6

Current log sequence       6

SQL> 



準備3 - データベース・リンクの作成



テスト環境で、プロダクション想定のデータベースのCDBを接続先としてデータベース・リンクを作成します。その際に使用する接続ユーザーをプロダクション想定の環境に作成します。

プロダクション想定のデータベースのCDBに接続して作業します。作成するユーザーはC##CLONEADMINとします。

drop user c##cloneadmin;
create user c##cloneadmin identified by <パスワード> container=all;
grant create session, resource, dba to c##cloneadmin container=all;
grant sysoper, create pluggable database to c##cloneadmin container=all;

SQL> drop user c##cloneadmin;


User dropped.


SQL> create user c##cloneadmin identified by <パスワード> container=all;


User created.


SQL> grant create session, resource, dba to c##cloneadmin container=all;


Grant succeeded.


SQL> grant sysoper, create pluggable database to c##cloneadmin container=all;


Grant succeeded.


SQL>


テスト環境想定の環境のCDBに接続し、パブリック・データベース・リンクを作成します。データベース・リンク名はlink$cloneとします。

drop public database link link$clone;
create public database link link$clone connect to c##cloneadmin identified by <c##cloneadminのパスワード> using '//<プロダクション想定のプライベートIP>/free';

SQL> drop public database link link$clone;


Database link dropped.


SQL> create public database link link$clone connect to c##cloneadmin identified by <パスワード> using '//<プライベートIP>/free';


Database link created.


SQL>


作成したデータベース・リンクをテストします。

select * from dual@link$clone;

SQL> select * from dual@link$clone;


D

-

X


SQL> 


以上で、リモート・クローンで使用するデータベース・リンクの準備ができました。


リフレッシュ可能クローンの作成



テスト環境想定のデータベースのCDBに接続します。シード以外のPDBが存在しないことを確認します。

SQL> show pdbs


    CON_ID CON_NAME   OPEN MODE  RESTRICTED

---------- ------------------------------ ---------- ----------

2 PDB$SEED   READ ONLY  NO

SQL> 


PDBが存在する時は、削除しておきます。今回の作業でOracle Database 23c FreeのPDB数の上限である3個のPDBを作成するため、他にPDBがあると作業を継続できません。

PDBとしてFREEPDB1がある場合は、以下のコマンドを実行します。

alter pluggable database freepdb1 close immediate;
drop pluggable database freepdb1 including datafiles;

SQL> alter pluggable database freepdb1 close immediate;


Pluggable database altered.


SQL> drop pluggable database freepdb1 including datafiles;


Pluggable database dropped.


SQL> 


プロダクション想定の環境にあるPDB - FREEPDB1のリフレッシュ可能PDBを、FREEPDB1_REFとして作成します。

set timing on
create pluggable database freepdb1_ref from freepdb1@link$clone refresh mode manual file_name_convert = ('FREEPDB1','FREEPDB1_REF');
alter pluggable database freepdb1_ref open read only;

SQL> set timing on

SQL> create pluggable database freepdb1_ref from freepdb1@link$clone refresh mode manual file_name_convert = ('FREEPDB1','FREEPDB1_REF');


Pluggable database created.


Elapsed: 00:00:51.77

SQL> alter pluggable database freepdb1_ref open read only;


Pluggable database altered.


Elapsed: 00:00:00.95

SQL> 


リフレッシュ可能クローンの初回作成時は完全なクローンが作成されるため、作成に時間がかかります。

リフレッシュ可能クローンは更新ができないため、APEXがインストールされていても使用できません。そのため、リフレッシュ可能クローンを元に、更新可能なクローンを作成します。

create pluggable database freepdb2 from freepdb1_ref file_name_convert = ('FREEPDB1_REF','FREEPDB2');
alter pluggable database freepdb2 open read write;

SQL> create pluggable database freepdb2 from freepdb1_ref file_name_convert = ('FREEPDB1_REF','FREEPDB2');


Pluggable database created.


Elapsed: 00:01:38.60

SQL> alter pluggable database freepdb2 open read write;


Pluggable database altered.


Elapsed: 00:00:06.73

SQL> 


更新可能なPDBがFREEPDB2として作成されました。これはプロダクション想定の環境にあるFREEPDB1のクローンになります。

ORDSの接続プールを作成します。

ords --config /etc/ords/config install \
--admin-user sys \
--db-pool pdb2 --db-hostname localhost --db-port 1521 --db-servicename freepdb2 \
--feature-db-api true --feature-rest-enabled-sql true --feature-sdw true \
--gateway-mode proxied --gateway-user APEX_PUBLIC_USER --proxy-user \
--config-only


[oracle@apex-test config]$ ords --config /etc/ords/config install \

> --admin-user sys \

> --db-pool pdb2 --db-hostname localhost --db-port 1521 --db-servicename freepdb2 \

> --feature-db-api true --feature-rest-enabled-sql true --feature-sdw true \

> --gateway-mode proxied --gateway-user APEX_PUBLIC_USER --proxy-user \

> --config-only


ORDS: Release 23.1 Production on Thu Jun 01 03:18:20 2023


Copyright (c) 2010, 2023, Oracle.


Configuration:

  /etc/ords/config/


Enter the database password for SYS AS SYSDBA: ******

Enter the database password for ORDS_PUBLIC_USER: ******

Confirm password: ******

Oracle REST Data Services - Non-Interactive Install

The setting named: db.connectionType was set to: basic in configuration: pdb2

The setting named: db.hostname was set to: localhost in configuration: pdb2

The setting named: db.port was set to: 1521 in configuration: pdb2

The setting named: db.servicename was set to: freepdb2 in configuration: pdb2

The setting named: plsql.gateway.mode was set to: proxied in configuration: pdb2

The setting named: db.username was set to: ORDS_PUBLIC_USER in configuration: pdb2

The setting named: db.password was set to: ****** in configuration: pdb2

The setting named: feature.sdw was set to: true in configuration: pdb2

The setting named: restEnabledSql.active was set to: true in configuration: pdb2

The setting named: security.requestValidationFunction was set to: ords_util.authorize_plsql_gateway in configuration: pdb2

2023-06-01T03:18:27.072Z INFO        To run in standalone mode, use the ords serve command:

2023-06-01T03:18:27.074Z INFO        ords --config /etc/ords/config serve

2023-06-01T03:18:27.074Z INFO        Visit the ORDS Documentation to access tutorials, developer guides and more to help you get started with the new ORDS Command Line Interface (http://oracle.com/rest).

[oracle@apex-test config]$ 


作成したPDB、FREEPDB2のユーザーORDS_PUBLIC_USERのパスワードの更新とアカウントのアンロックを実施します。

alter session set container = freepdb2;
alter user ords_public_user identified by <ORDS_PUBLIC_USERのパスワード> account unlock;


SQL> alter session set container = freepdb2;


Session altered.


SQL> alter user ords_public_user identified by <ORDS_PUBLIC_USERのパスワード> account unlock;


User altered.


SQL> 


作成したプールpdb2をURLに指定することで、APEXに接続できるようになります。プロダクション想定の環境にあるFREEPDB1のクローンなので、ワークスペースやユーザーはそのまま使えます。

http://テスト想定のパブリックIP/ords/pdb2/


開発環境にサインインすると、クローン元となったプロダクション想定の環境と同じであることが確認できます。


プロダクション想定の環境を変更し、テスト環境をリフレッシュします。

プロダクション想定のAPEX環境で、新規にアプリケーションを作成しました。


テスト想定の環境のCDBに接続し、FREEPDB1_REFをリフレッシュします。

alter session set container=freepdb1_ref;
alter pluggable database close;
set timing on
alter pluggable database refresh;
alter pluggable database open read only;


リフレッシュは差分更新であるため、初回実施時よりも短時間でPDBが更新されます。

SQL> alter session set container=freepdb1_ref;


Session altered.


SQL> alter pluggable database close;


Pluggable database altered.


SQL> set timing on

SQL> alter pluggable database refresh;


Pluggable database altered.


Elapsed: 00:00:03.13

SQL> alter pluggable database open read only;


Pluggable database altered.


Elapsed: 00:00:00.70

SQL> 


最新の状態を反映したFREEPDB1_REFから、更新可能PDBであるFREEPDB2を作り直します。

set timing off
alter session set container=cdb$root;
alter pluggable database freepdb2 close immediate;
drop pluggable database freepdb2 including datafiles;
create pluggable database freepdb2 from freepdb1_ref file_name_convert = ('FREEPDB1_REF','FREEPDB2');
alter pluggable database freepdb2 open read write;
alter session set container=freepdb2;
alter user ords_public_user identified by <ORDS_PUBLIC_USERのパスワード> account unlock;


SQL> set timing off    

SQL> alter session set container=cdb$root;


Session altered.


SQL> alter pluggable database freepdb2 close immediate;


Pluggable database altered.


SQL> drop pluggable database freepdb2 including datafiles;


Pluggable database dropped.


SQL> create pluggable database freepdb2 from freepdb1_ref file_name_convert = ('FREEPDB1_REF','FREEPDB2');


Pluggable database created.


SQL> alter pluggable database freepdb2 open read write;

Pluggable database altered.


SQL> alter session set container=freepdb2;


Session altered.


SQL> alter user ords_public_user identified by <ORDS_PUBLIC_USERのパスワード> account unlock;


User altered.


SQL> 


以上でFREEPDB2のAPEX環境に接続すると、プロダクション環境での更新が反映されていることが確認できます。




スナップショット・コピーの作成



データファイルが通常のファイルシステムに存在している場合、PDBのスナップショット・コピーを作成するには、初期化パラメータのclonedbをtrueにします。

初期化パラメータclonedbの設定を確認します。

show parameter clonedb

SQL> show parameter clonedb


NAME     TYPE VALUE

------------------------------------ ----------- ------------------------------

clonedb      boolean FALSE

clonedb_dir     string

SQL> 


値がFALSEであれば、trueに変更します。データベースに変更を反映するために、再起動が必要です。

alter system set clonedb=true scope=spfile;
shutdown immediate
startup
show parameter clonedb

SQL> alter system set clonedb=true scope=spfile;


System altered.


SQL> shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

SQL> startup

ORACLE instance started.


Total System Global Area 1222532352 bytes

Fixed Size   10042624 bytes

Variable Size   805306368 bytes

Database Buffers   402653184 bytes

Redo Buffers     4530176 bytes

Database mounted.

Database opened.

SQL> show parameter clonedb


NAME     TYPE VALUE

------------------------------------ ----------- ------------------------------

clonedb      boolean TRUE

clonedb_dir     string

SQL> 


最初にFREEPDB2のフル・クローンとしてFREEPDB3を作成し、作成にかかる時間を確認します。

alter pluggable database freepdb2 open read only;
set timing on
create pluggable database freepdb3 from freepdb2 file_name_convert = ('FREEPDB2','FREEPDB3');

ほとんどAPEXをインストールしただけのPDBですが、クローンの作成に2分程度の時間がかかっています。

SQL> alter pluggable database freepdb2 open read only;


Pluggable database altered.


SQL> set timing on 

SQL> create pluggable database freepdb3 from freepdb2 file_name_convert = ('FREEPDB2','FREEPDB3');


Pluggable database created.


Elapsed: 00:01:40.13

SQL> 


スナップショット・コピーとしてFREEPDB3を作り直します。

drop pluggable database freepdb3 including datafiles;
set timing on
create pluggable database freepdb3 from freepdb2 snapshot copy file_name_convert = ('FREEPDB2','FREEPDB3');

スナップショット・コピーはデータのコピーを伴わないため、一瞬でクローンが終了します。

SQL> drop pluggable database freepdb3 including datafiles;


Pluggable database dropped.


SQL> set timing on

SQL> create pluggable database freepdb3 from freepdb2 snapshot copy file_name_convert = ('FREEPDB2','FREEPDB3');


Pluggable database created.


Elapsed: 00:00:01.57

SQL> 


作成したFREEPDB3をオープンします。

alter pluggable database freepdb3 open read write;

SQL> alter pluggable database freepdb3 open read write;



Pluggable database altered.


SQL>


ORDSに接続プールpdb3を作成します。ユーザーORDS_PUBLIC_USERのパスワードとして、FREEPDB2に設定した値を入力します。

ords --config /etc/ords/config install \
--admin-user sys \
--db-pool pdb3 --db-hostname localhost --db-port 1521 --db-servicename freepdb3 \
--feature-db-api true --feature-rest-enabled-sql true --feature-sdw true \
--gateway-mode proxied --gateway-user APEX_PUBLIC_USER --proxy-user \
--config-only

[oracle@apex-test config]$ ords --config /etc/ords/config install \

> --admin-user sys \

> --db-pool pdb3 --db-hostname localhost --db-port 1521 --db-servicename freepdb3 \

> --feature-db-api true --feature-rest-enabled-sql true --feature-sdw true \

> --gateway-mode proxied --gateway-user APEX_PUBLIC_USER --proxy-user \

> --config-only


ORDS: Release 23.1 Production on Thu Jun 01 04:23:22 2023


Copyright (c) 2010, 2023, Oracle.


Configuration:

  /etc/ords/config/


Enter the database password for SYS AS SYSDBA: *******

Enter the database password for ORDS_PUBLIC_USER: *******

Confirm password: *******

Oracle REST Data Services - Non-Interactive Install

The setting named: db.connectionType was set to: basic in configuration: pdb3

The setting named: db.hostname was set to: localhost in configuration: pdb3

The setting named: db.port was set to: 1521 in configuration: pdb3

The setting named: db.servicename was set to: freepdb3 in configuration: pdb3

The setting named: plsql.gateway.mode was set to: proxied in configuration: pdb3

The setting named: db.username was set to: ORDS_PUBLIC_USER in configuration: pdb3

The setting named: db.password was set to: ****** in configuration: pdb3

The setting named: feature.sdw was set to: true in configuration: pdb3

The setting named: restEnabledSql.active was set to: true in configuration: pdb3

The setting named: security.requestValidationFunction was set to: ords_util.authorize_plsql_gateway in configuration: pdb3

2023-06-01T04:23:28.870Z INFO        To run in standalone mode, use the ords serve command:

2023-06-01T04:23:28.875Z INFO        ords --config /etc/ords/config serve

2023-06-01T04:23:28.875Z INFO        Visit the ORDS Documentation to access tutorials, developer guides and more to help you get started with the new ORDS Command Line Interface (http://oracle.com/rest).

[oracle@apex-test config]$ 


作成したAPEX環境に接続します。

http://テスト想定のパブリックIP/ords/pdb3/

この環境もプロダクション環境のクローンなので、同じアプリケーションが作成されています。


アプリケーションのテストを行うことは重要ですが、データの更新が発生するような後戻りが難しいテストを繰り返し実施することには制約があります。

Oracle Databaseのマルチテナントの機能が提供している、色々なクローン手順を駆使することにより、従来は困難だったアプリケーションのテストを実施できるかもしれません。

続く