Edited at

Active Data Guard DML Redirectを試す(Oracle Database 19c)

Oracle Database 19cの新機能であるActive Data Guard DML Redirect機能を試してみました。この機能を使うと、Data Guardスタンバイ・インスタンス上で更新系DMLを実行できるようになります。実際には更新系DML文は、プライマリ・インスタンス上に転送(Redirect)/実行され、実行結果のREDO情報がスタンバイ・インスタンスで確認できるようになります。


準備

Redirect DML機能の利用に特別な準備は必要ありません。通常と同じようにActive Data Guardインスタンスを構成します。常時Redirect DML機能を有効にする場合は、スタンバイ・インスタンスの初期化パラメータadg_redirect_dmlをTRUEに指定します(デフォルトFALSE)。後述の理由にリアルタイム適用が有効になっていることが望まれます。

SQL> SHOW PARAMETER adg_redirect_dml

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
adg_redirect_dml boolean FALSE
SQL>
SQL> SELECT process, pid, status, thread#, sequence# FROM V$MANAGED_STANDBY WHERE process='MRP0';

PROCESS PID STATUS THREAD# SEQUENCE#
--------- ------------------------ ------------ ---------- ----------
MRP0 159079 APPLYING_LOG 1 61


実行

Active Data Guardのスタンバイ・インスタンスは通常Read Onlyモードで起動されています。このため、スタンバイ・インスタンス上で実行された更新系DMLはエラーになります。

SQL> CONNECT scott/tiger

Connected.
SQL> SELECT * FROM data1;

C1 C2
---------- ----------
100 primary1

SQL> INSERT INTO data1 VALUES (200, 'standby2');
INSERT INTO data1 VALUES (200, 'standby2')
*
ERROR at line 1:
ORA-16000: database or pluggable database open for read-only access

しかしALTER SESSION ENABLE ADG_REDIRECT_DML文を実行することで、DML文はプライマリ・インスタンスに転送されることになります。

SQL> ALTER SESSION ENABLE ADG_REDIRECT_DML;

Session altered.

SQL> INSERT INTO data1 VALUES (200, 'standby2');

1 row created.

SQL> COMMIT;

Commit complete.

SQL> SELECT * FROM data1;

C1 C2
---------- ----------
100 primary1
200 standby2

マニュアルに記述が見つからないのですが、プライマリ・インスタンスへの接続情報は、初期化パラメーターfal_serverの値を使っているようです。このため、初期化パラメーターfal_serverの設定が指定されていない場合、更新系DMLはエラーになります。

SQL> SHOW PARAMETER fal_server

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
fal_server string
SQL>
SQL> INSERT INTO data1 VALUES (100, 'standby1');
INSERT INTO data1 VALUES (100, 'standby1')
*
ERROR at line 1:
ORA-16397: statement redirection from Oracle Active Data Guard standby database
to primary database failed

SQL> !oerr ora 16397
16397, 00000, "statement redirection from Oracle Active Data Guard standby database to primary database failed"
// *Cause: The statement redirection failed because of one of the following reasons:
// 1. The primary database connect string was not established.
// 2. The primary database could not be reached.
// 3. The undo-mode or incarnation were not the same.
// 4. The current user and logged-in user were not the same.
// 5. Redirecting CREATE TABLE AS SELECT (CTAS) of the global temporary
// table was not supported.
// 6. Redirecting PL/SQL execution having bind variable was not supported.
// *Action: Run the statement after fixing the condition that caused the failure.


制約

スタンバイ・インスタンス上で実行された更新系DMLは、プライマリ・インスタンスへ転送/実行され、スタンバイ・インスタンスにREDO転送/適用が完了するまでユーザーに処理を返さないように見えます。このためリアルタイム適用の運用が必須になると思われます。

PL/SQLプロシージャによる更新は別の制御が必要になります。こちらは別途検証しようと思います。