ヘッダーをスキップ
Oracle® Databaseアドバンスト・レプリケーション・マネージメントAPIリファレンス
12cリリース1 (12.1)
E52979-02
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

9 レプリケーション・オブジェクトおよびキューの管理

この章では、レプリケーション・マネージメントAPIを使用した、レプリケーション環境でのレプリケーション・オブジェクトおよびキューの管理方法を説明します。

この章には、次の項が含まれます。

静止中のマスター・グループにあるレプリケート・オブジェクトの変更

データベースを変更する場合、レプリケート・オブジェクトの特性も変更する必要がある場合があります。DDLを直接実行して、レプリケート・オブジェクトを変更しないでください。直接実行すると、レプリケーション環境に障害が発生する原因となります。

DBMS_REPCATパッケージのALTER_MASTER_REPOBJECTプロシージャを使用して、静止中のマスター・グループにあるレプリケート・オブジェクトの特性を変更します。その場合、次のスクリプト例に示すように、必要なDDLをプロシージャ・コールに含めます(ddl_textパラメータを参照してください)。

これらのアクションを実行するには、次の要件を満たす必要があります。

実行者: レプリケーション管理者

実行場所: マスター定義サイト

レプリケーションの状態: 静止中

次に示す手順に従って、静止中のマスター・グループにあるレプリケート・オブジェクトを変更します。


注意:

このドキュメントをオンラインで参照している場合は、次の「BEGINNING OF SCRIPT」の行から「END OF SCRIPT」の行までのテキストをテキスト・エディタにコピーして編集し、使用している環境に適したスクリプトを作成します。

/************************* BEGINNING OF SCRIPT ******************************
手順1   マスター表を変更する場合、そのマスター表に基づく更新可能なマテリアライズド・ビューがあれば、更新可能なマテリアライズド・ビューをリフレッシュします。

更新可能なマテリアライズド・ビューをリフレッシュして、マスター表に変更をプッシュします。手順については、「マテリアライズド・ビューのリフレッシュ」を参照してください。

*/

PAUSE Press <RETURN> to continue when all of the updatable materialized views that are based on the master table have been refreshed.

/*
手順2   レプリケーション管理者としてマスター定義サイトに接続します。
*/
SET ECHO ON

SPOOL alter_rep_object.out

CONNECT repadmin@orc1.example.com

/*
手順3   必要な場合は、マスター・グループを静止します。

静止が不要な場合の詳細は、「ALTER_MASTER_REPOBJECTプロシージャ」を参照してください。

*/

BEGIN
   DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY (
      gname => 'hr_repg');
END;
/

/*
手順4   個別のSQL*Plusセッションで、静止するマスター・グループのステータスをチェックします。

グループのステータスがQUIESCEDになるまで進行を中断します。

ステータスをチェックするには、次の問合せを実行します。

SELECT GNAME, STATUS FROM DBA_REPGROUP;

*/

PAUSE Press <RETURN> to continue when the master group's status is QUIESCED.

/*
手順5   レプリケート・オブジェクトを変更します。
*/
BEGIN
   DBMS_REPCAT.ALTER_MASTER_REPOBJECT (
      sname => 'hr',
      oname => 'employees',
      type => 'TABLE',
      ddl_text => 'ALTER TABLE hr.employees ADD (timestamp DATE)');
END;
/

/*
手順6   変更されたオブジェクトに対するレプリケーション・サポートを再生成します。
*/
BEGIN 
    DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT (
      sname => 'hr',
      oname => 'employees', 
      type => 'TABLE',
      min_communication => TRUE); 
END;
/

/*
手順7   個別のSQL*Plusセッションで、DBA_REPCATLOGが空であるかどうかを確認します。

このビューが空になるまで進行を中断します。

他のSQL*Plusセッションで次のSELECT文を実行して、DBA_REPCATLOGビューを監視します。

SELECT * FROM DBA_REPCATLOG WHERE GNAME = 'HR_REPG';

*/

PAUSE Press <RETURN> to continue when DBA_REPCATLOG is empty.

/*
手順8   必要な場合は、マスター表のマテリアライズド・ビュー・ログを再作成します。

マスター表に基づく高速リフレッシュが可能なマテリアライズド・ビューがあるマスター表を変更し、かつ、次のいずれかの条件が満たされる場合は、マテリアライズド・ビュー・ログを削除して再作成する必要があります。

  • マテリアライズド・ビュー・ログには、マスター表に追加された1つ以上の新しい列が含まれている必要がある。この場合には、マテリアライズド・ビュー・ログを変更して、列を追加できます。「列の追加のためのマテリアライズド・ビュー・ログの変更」を参照してください。

  • マテリアライズド・ビュー・ログには、マスター表の変更された列が1つ以上含まれている。

  • マテリアライズド・ビュー・ログには、マスター表から削除された列が1つ以上含まれている。

*/

PAUSE Press <RETURN> to continue after the materialized view logs are re-created.

/*
手順9   必要な場合は、マテリアライズド・ビューを再作成します。

マスター表に基づく更新可能なマテリアライズド・ビューがあるマスター表を変更した場合は、これらの更新可能なマテリアライズド・ビューをすべて再作成する必要があります。

マスター表に基づく読取り専用のマテリアライズド・ビューがあるマスター表を変更し、かつ、次のいずれかの条件が満たされる場合は、これらの読取り専用のマテリアライズド・ビューを再作成する必要があります。

  • 読取り専用のマテリアライズド・ビューは、マスター表に追加された1つ以上の列を参照する必要がある。

  • 読取り専用のマテリアライズド・ビューは、マスター表の変更された列を1つ以上参照する。

  • 読取り専用のマテリアライズド・ビューは、マスター表から削除された列を1つ以上参照する。

*/

PAUSE Press <RETURN> to continue after the materialized views are re-created.

/*
手順10   レプリケーション・アクティビティを再開します。
*/
BEGIN
   DBMS_REPCAT.RESUME_MASTER_ACTIVITY (
      gname => 'hr_repg');
END;
/

SET ECHO OFF

SPOOL OFF

/************************* END OF SCRIPT **********************************/

変更をレプリケートしない表の変更

レプリケート・オブジェクトを変更する必要があるが、この変更をレプリケーション環境の他のサイトにレプリケートしない場合があります。たとえば、次の状況でレプリケーションを使用禁止にする必要があります。

  • プロシージャ・レプリケーションを使用して変更を伝播するときは、必ずプロシージャの開始時に行レベル・レプリケーションを使用禁止にします。

  • トリガー・アクションを複数回レプリケートするのを回避するため、レプリケート表で定義されたトリガー中のレプリケーションを使用禁止にする必要がある場合があります。詳細は、「レプリケート・トリガーの起動を1回のみにする」を参照してください。

  • 競合を手動で解決する場合、表の他のコピーにこの変更をレプリケートしない場合があります。

これが必要になるのは、たとえば、エラー・トランザクションを再実行したときに競合するレプリケート更新が成功するように、1つのサイトのレコードの状態を訂正する必要がある場合です。または、トランザクションが接続先サイトで適用できなかったため、起点サイトでのトランザクションの効果を取り消すために、レプリケートされない変更を使用する場合があります。この例では、Oracle Enterprise Manager Cloud ControlのAdvanced Replicationインタフェースを使用して、競合するトランザクションを接続先サイトから削除できます。

変更をレプリケートせずに表を変更するには、DBMS_REPUTILパッケージのREPLICATION_ONプロシージャおよびREPLICATION_OFFプロシージャを使用します。これらのプロシージャは引数を取らず、生成されたレプリケーション・トリガーでフラグとして使用されます。


注意:

レプリケーションを使用可能または使用禁止にするには、DBMS_REPUTILパッケージのEXECUTE権限を持っている必要があります。

レプリケーションの使用禁止

DBMS_REPUTIL.REPLICATION_OFFプロシージャは、カレント・セッションに関する内部レプリケーション変数の状態をFALSEに設定します。すべてのレプリケート・トリガーが、トランザクションをキューに入れる前にこの変数の状態をチェックするため、行レベル・レプリケーションを使用してレプリケート表を変更しても、遅延トランザクションはキューに入れられません。


注意:

レプリケーションのオンまたはオフの切り替えは、カレント・セッションにのみ適用されます。すなわち、現在同じサーバーに接続している他のユーザーは、遅延トランザクション・キューでコミットされる変更の入力を制限されません。

プロシージャ・レプリケーションを使用している場合は、次の例に示すようにプロシージャの開始時にREPLICATION_OFFをコールします。これにより、レプリケーション機能により行レベル・レプリケーションが使用されて変更が伝播されることがなくなります。

CREATE OR REPLACE PACKAGE update_objects AS
  PROCEDURE update_emp(adjustment IN NUMBER);
END;
/

CREATE OR REPLACE PACKAGE BODY update_objects AS
  PROCEDURE update_emp(adjustment IN NUMBER) IS
  BEGIN
   --turn off row-level replication for set update
   DBMS_REPUTIL.REPLICATION_OFF;
   UPDATE emp . . .;
   --reenable replication
   DBMS_REPUTIL.REPLICATION_ON;
  EXCEPTION WHEN OTHERS THEN
   . . . 
   DBMS_REPUTIL.REPLICATION_ON;
  END;
END;
/

レプリケーションの再有効化

競合を解消した後、またはレプリケート・プロシージャの終了時に、必ずDBMS_REPUTIL.REPLICATION_ONをコールし、レプリケート表またはマテリアライズド・ビューに対する変更の通常のレプリケーションを再開してください。このプロシージャは引数を取りません。REPLICATION_ONのコールにより、内部レプリケーション変数がTRUEに設定されます。

レプリケート・トリガーの起動を1回のみにする

レプリケート表でレプリケート・トリガーを定義済の場合、変更を行うごとにトリガーが1回のみ起動するようにする必要がある場合があります。通常は、トリガーを起動するのは変更が最初に行われたときのみで、変更がリモート・サイトにレプリケートされたときはリモート・トリガーを起動しません。

トリガーの開始時にDBMS_REPUTIL.FROM_REMOTEパッケージ変数の値をチェックする必要があります。この変数の値がFALSEの場合のみ、トリガーで表が更新される必要があります。

または、トリガーを起動する行以外の行を変更する場合は、トリガーの開始時にレプリケーションを使用禁止にし、トリガーの終了時に再び使用可能にできます。この方法により、元の変更のみがリモート・サイトにレプリケートされます。これによりレプリケート・トリガーが各リモート・サイトで起動します。レプリケート・トリガーで実行される更新は、他のサイトにプッシュされません。

このアプローチでは、競合解消はコールされません。このため、トリガーにより生じる変更がデータの整合性に影響しないようにする必要があります。

レプリケート表でのLONG列のLOB列への変換

BASICFILE記憶域を使用するLOB列はレプリケートできますが、LONG列はレプリケートできません。LONG列からCLOB列へのデータ型の変換、およびLONG_RAW列からBLOB列へのデータ型の変換が可能です。

LONG列をLOB列に変換すると、このような列のデータは変換後にレプリケートされるため、ネットワーク帯域幅の要件が増加する可能性があります。この項のプロシージャを実行する前に、十分なネットワーク帯域幅があることを確認してください。


注意:

SECUREFILE記憶域を使用するLOB列は、レプリケートできません。


関連項目:

アプリケーションの詳細およびLONGからLOBへの変換の詳細は、『Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド』を参照してください。

次に示す手順に従って、レプリケート表でLONG列をLOB列に変換します。

手順1   LONG列のデータがすべてのレプリケーション・サイトで整合性があることを確認します。

LONG列を含む表がマスター表として構成されている場合は、LONG列のデータへの変更はレプリケートされません。このため、LONG列のデータがすべてのレプリケーション・サイトで一致しない場合があります。変換前に、LONG列のデータがすべてのマスター・サイトで一致することを確認する必要があります。

手順2   レプリケーション管理者としてマスター定義サイトに接続します。
CONNECT repadmin@orc1.example.com
手順3   レプリケーションの状態が通常の場合は、静止中に変更します。
BEGIN
   DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY (
      gname => 'sales_mg');
END;
/
手順4   LONG列をLOB列に変換します。
BEGIN
   DBMS_REPCAT.ALTER_MASTER_REPOBJECT (
      sname => 'staff',
      oname => 'positions',
      type => 'TABLE',
      ddl_text => 'ALTER TABLE staff.positions MODIFY (job_desc CLOB)');
END;
/

類似したALTER TABLE文を使用して、LONG_RAW列をBLOB列に変換できます。

手順5   変更されたマスター表に対するレプリケーション・サポートを再生成します。
BEGIN 
    DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT (
      sname => 'staff',
      oname => 'positions', 
      type => 'TABLE',
      min_communication => TRUE); 
END;
/
手順6   レプリケーションを再開します。
BEGIN
   DBMS_REPCAT.RESUME_MASTER_ACTIVITY (
      gname => 'sales_mg');
END;
/
手順7   マテリアライズド・ビューがいずれかのマスター・サイトの変更された表をベースにしている場合は、このマテリアライズド・ビューを再作成します。

必要な場合は、マテリアライズド・ビューを再作成します。

レプリケート表間の違いの判別

レプリケート表間に違いが生じる場合があります。レプリケーション環境を管理するとき、2つのレプリケート表の内容が同じであるかどうかを定期的にチェックできます。DBMS_RECTIFIER_DIFFパッケージ内の次のプロシージャを使用すると、2つの表の違いを識別でき、また任意で調整もできます。


注意:

DBMS_COMPARISONパッケージを使用して、データベース・オブジェクト間の相違点を特定し、収束することもできます。


関連項目:

  • DBMS_COMPARISONパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

  • DBMS_COMPARISONパッケージの使用方法は、『Oracle Streamsレプリケーション管理者ガイド』を参照


DIFFERENCESプロシージャの使用

DIFFERENCESプロシージャは、1つの表の2つのレプリカを比較し、第1のレプリカにあるが第2のレプリカにはない行、および第2のレプリカにあるが第1のレプリカにはない行をすべて判別します。このプロシージャの出力は、ユーザーが作成した2つの表に格納されます。第1の表には欠落行の値が格納され、第2の表にはそれぞれの欠落行を含むサイトを示す情報が格納されます。

RECTIFYプロシージャの使用

RECTIFYプロシージャは、DIFFERENCESプロシージャで生成された情報を使用して、2つの表を調整します。第1の表にはあるが第2の表にはない行はすべて、第2の表に挿入されます。第2の表にはあるが第1の表にはない行はすべて、第2の表から削除されます。

レプリケート表のコピーをすべて同一にリストアするには、次の手順に従います。

手順1   表のコピーを1つ選択して参照表にします。

他のすべての表のレプリカを必要に応じて更新するときに、このコピーを使用します。

手順2   違いをチェックする必要があるのが、表の中のすべての行および列か、またはサブセットのみかを判別します。

たとえば、前回の違いのチェック以降に更新されていない行は、チェックしなくてもよい場合があります。すべての列をチェックする必要はありませんが、列のリストには、表の主キーを構成する(または代替識別キーとして指定した)列がすべて含まれている必要があります。

手順3   表の中のどの列をチェックするかを決定した後は、比較の結果を保持するための表を2つ作成します。

まず、比較する列のデータを保持する表を作成する必要があります。たとえば、employees表のemployee_id列、salary列およびdepartment_id列を比較する場合は、次のようなCREATE文を実行する必要があります。

CREATE TABLE hr.missing_rows_data (
  employee_id     NUMBER(6),
  salary          NUMBER(8,2),
  department_id   NUMBER(4));

次に、行が検出された位置を示す表も作成する必要があります。この表には、次の例に示すデータ型の列を3つ入れる必要があります。

CREATE TABLE hr.missing_rows_location (
  present     VARCHAR2(128),
  absent      VARCHAR2(128),
  r_id        ROWID);
手順4   比較対象の表があるレプリケーション・グループのレプリケーション・アクティビティを中断します。

グループのレプリケーション・アクティビティの中断は必須ではありませんが、最初に表を静止せずに調整すると、データに不整合が生じることがあります。

CONNECT repadmin

BEGIN
   DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY (
      gname => 'hr_repg');
END;
/
手順5   参照表があるサイトで、DIFFERENCESプロシージャをコールします。

たとえば、ニューヨークのサイトとサンフランシスコのサイトのemployees表を比較する場合、次のようなプロシージャをコールします。

BEGIN
   DBMS_RECTIFIER_DIFF.DIFFERENCES (
      sname1              =>   'hr',
      oname1              =>   'employees',
      reference_site      =>   'ny.example.com',
      sname2              =>   'hr',
      oname2              =>   'employees',
      comparison_site     =>   'mv4.example.com',
      where_clause        =>   '',
      column_list         =>   'employee_id,salary,department_id',
      missing_rows_sname  =>   'hr',
      missing_rows_oname1 =>   'missing_rows_data',
      missing_rows_oname2 =>   'missing_rows_location',
      missing_rows_site   =>   'ny.example.com',
      max_missing         =>    500,
      commit_rows         =>    50);
END;
/

図9-1に、employee表の2つのレプリカと、これらのレプリカに対してDIFFERENCESプロシージャを実行した場合に出力される欠落行表の例を示します。

図9-1 レプリカ間の違いの判別

図9-1の説明が続きます。
「図9-1 レプリカ間の違いの判別」の説明

2つの欠落行表が、ROWIDおよびr_id列によって対応付けられている点に注目してください。

手順6   参照サイトの表に等しくなるように比較サイトの表を調整します。
BEGIN
   DBMS_RECTIFIER_DIFF.RECTIFY (
      sname1              =>   'hr',
      oname1              =>   'employees',
      reference_site      =>   'ny.example.com',
      sname2              =>   'hr',
      oname2              =>   'employees',
      comparison_site     =>   'mv4.example.com',
      column_list         =>   'employee_id,salary,department_id',
      missing_rows_sname  =>   'hr',
      missing_rows_oname1 =>   'missing_rows_data',
      missing_rows_oname2 =>   'missing_rows_location',
      missing_rows_site   =>   'ny.example.com',
      commit_rows         =>    50);
END;
/

必要な挿入および削除を実行している間、その変更を伝播しないよう、RECTIFYプロシージャは、比較サイトのレプリケーションを一時的に使用禁止にします。RECTIFYは、最初に必要なDELETE操作をすべて実行し、次にINSERT操作をすべて実行します。これによって、キー制約の違反は発生しなくなります。

RECTIFYプロシージャが正常に実行されると、欠落行表は空になります。


注意:

比較表にその他の制約がある場合は、RECTIFYのコール時にそれらに違反しないようにする必要があります。欠落行表の情報を使用して、表を直接更新することが必要な場合もあります。その場合は、必ず欠落行表から該当の行をDELETEしてください。

手順7   レプリケート表の残りのコピーに対して、手順5および6を繰り返します。

このプロシージャの完了時にすべてのコピーが確実に同一になるように、必ず毎回同じ参照表を使用してください。

手順8   マスター・グループのレプリケーション・アクティビティを再開します。
BEGIN
   DBMS_REPCAT.RESUME_MASTER_ACTIVITY (
      gname => 'hr_repg');
END;
/

遅延トランザクション・キューの管理

通常、Advanced Replicationは、遅延トランザクション・キューのプッシュおよびパージを自動的に行うように構成されます。ただし、遅延トランザクション・キューのプッシュやパージを手動で行う必要があることもあります。遅延トランザクション・キューをプッシュするプロセスは、マスター・サイトでもマテリアライズド・ビュー・サイトでも同じです。

遅延トランザクション・キューのプッシュ

マスター・サイトは、遅延トランザクション・キューのプッシュを設定された間隔で自動的に行うように構成されます。マテリアライズド・ビュー・サイトでは、マテリアライズド・ビューのリフレッシュ時に、遅延トランザクション・キューのトランザクションを自動的に伝播させない場合は、次の手順を実行して、更新可能なマテリアライズド・ビューに加えられた変更をそのマスター表またはマスター・マテリアライズド・ビューに伝播します。

この例では、マテリアライズド・ビュー・サイトでの遅延トランザクション・キューのプッシュを示しますが、そのプロセスはマスター・サイトでもマテリアライズド・ビュー・サイトでも同じです。

実行者: マテリアライズド・ビュー管理者

実行場所: マテリアライズド・ビュー・サイト

次の手順に従います。

手順1   マテリアライズド・ビュー管理者としてマテリアライズド・ビュー・サイトに接続します。
CONNECT mviewadmin@mv1.example.com
手順2   次のSELECT文を実行して、遅延トランザクションとその接続先を表示します。

遅延トランザクション・キューの伝播は、トランザクションの接続先をベースにします。それぞれ固有の接続先と、その接続先に保留されているトランザクションの数が表示されます。

SELECT DISTINCT(dblink), COUNT(deferred_tran_id) 
   FROM deftrandest GROUP BY dblink;
手順3   遅延トランザクションの接続先としてリストされている各サイトに、DBMS_DEFER_SYS.PUSHファンクションを実行します。
DECLARE
   temp INTEGER;
BEGIN
   temp := DBMS_DEFER_SYS.PUSH (
      destination => 'orc1.example.com',
      stop_on_error => FALSE,
      delay_seconds => 0,
      parallelism => 0);
END;
/

手順2で実行したSELECT文で戻された各接続先に、PUSHプロシージャを実行します。

遅延トランザクション・キューのパージ

遅延トランザクション・キュー内の正常に伝播されたトランザクションを、定期的に自動的にパージするようにシステムが設定されていない場合は、次の手順を実行して、手動でパージする必要があります。

この例では、マテリアライズド・ビュー・サイトでの遅延トランザクション・キューのパージを示しますが、そのプロセスはマスター・サイトでもマテリアライズド・ビュー・サイトでも同じです。

実行者: マテリアライズド・ビュー管理者

実行場所: マテリアライズド・ビュー・サイト

次の手順に従います。

手順1   マテリアライズド・ビュー管理者としてマテリアライズド・ビュー・サイトに接続します。
CONNECT mviewadmin@mv1.example.com
手順2   遅延トランザクション・キューをパージします。
DECLARE
   temp INTEGER;
BEGIN
   temp := DBMS_DEFER_SYS.PURGE (
      purge_method => DBMS_DEFER_SYS.PURGE_METHOD_QUICK);
END;
/

注意:

purge_method_quickパラメータを使用する場合は、正常にプッシュされた遅延トランザクションおよび遅延プロシージャ・コールが、パージされるまで、それぞれDEFTRANおよびDEFCALLデータ・ディクショナリ・ビューに予想以上に長時間保持されることがあります。詳細は、DBMS_DEFER_SYS.PURGEに関する「使用上の注意」を参照してください。

ANYDATA型を使用した遅延コールの引数の値の判定

レプリケート表で列オブジェクト、コレクションまたはREFを使用している場合、DBMS_DEFER_QUERYパッケージのGET_ANYDATA_ARGファンクションを使用して、これらのユーザー定義型の1つを含む遅延コールの引数の値を判定できます。

次の例は、GET_ANYDATA_ARGファンクションの使用方法を示します。この例では、oeサンプル・スキーマで次のユーザー定義型を使用します。

CREATE TYPE phone_list_typ AS VARRAY(5) OF VARCHAR2(25);
/

CREATE TYPE warehouse_typ AS OBJECT
    (warehouse_id       NUMBER(3), 
     warehouse_name     VARCHAR2(35), 
     location_id        NUMBER(4)
    );
/

CREATE TYPE inventory_typ AS OBJECT
    (product_id          NUMBER(6), 
     warehouse           warehouse_typ,
     quantity_on_hand    NUMBER(8)
    );
/

CREATE TYPE inventory_list_typ AS TABLE OF inventory_typ;
/

次のプロシージャは、遅延トランザクション・キューに格納されたコールのコレクション、オブジェクトおよびREFインスタンスの引数値を取得します。このプロシージャは、コール番号およびトランザクションIDが使用可能であることを前提としています。

プロシージャを作成するユーザーは、DBMS_DEFER_QUERYパッケージのEXECUTE権限を持っていることと、CREATE PROCEDURE権限を持っていることが必要です。この例では、oeサンプル・スキーマを使用します。このため、この例を実行するには、oeユーザーにこれらの権限を与える必要があります。管理ユーザーとして接続して、次のように入力します。

GRANT EXECUTE ON DBMS_DEFER_QUERY TO oe;

GRANT CREATE PROCEDURE TO oe;

CONNECT oe@orc1.example.com

CREATE OR REPLACE PROCEDURE get_userdef_arg AS
  call_no      NUMBER := 0;
  txn_id       VARCHAR2(128) := 'xx.xx.xx';
  anydata_val  ANYDATA;
  t            ANYTYPE;
  data_pl      phone_list_typ;     -- varray
  data_ntt     inventory_list_typ; -- nested table type
  data_p       warehouse_typ;      -- object type
  ref1         REF inventory_typ;  -- REF type
  rval         PLS_INTEGER;        -- return value
  tc           PLS_INTEGER;        -- return value
  prec         PLS_INTEGER;        -- precision
  scale        PLS_INTEGER;        -- scale
  len          PLS_INTEGER;        -- length
  csid         PLS_INTEGER;        -- character set id
  csfrm        PLS_INTEGER;        -- character set form
  cnt          PLS_INTEGER;        -- count of varray elements or number of
                                   -- object attributes
  sname        VARCHAR2(35);       -- schema name
  type_name    VARCHAR2(35);       -- type name
  version      VARCHAR2(35);
BEGIN
   FOR i IN 1 .. 5 LOOP
     anydata_val := DBMS_DEFER_QUERY.GET_ANYDATA_ARG(call_no, i, txn_id);
     -- Get the type information, including type name.
     tc := anydata_val.GetType(t);
     tc := t.GetInfo(prec, scale, len, csid, csfrm, sname, type_name,
                     version, cnt);
     -- Based on the type name, convert the anydata value to the appropriate 
     -- user-defined types.
     IF type_name = 'PHONE_LIST_TYP' THEN
       -- The anydata_val contains phone_list_typ varray instance.
       rval := anydata_val.GetCollection(data_pl);
       -- Do something with data_pl.
     ELSIF type_name = 'INVENTORY_LIST_TYP' THEN
       -- anydata_val contains inventory_list_typ nested table instance.
       rval := anydata_val.GetCollection(data_ntt);
       -- Do something with data_ntt.
     ELSIF type_name = 'WAREHOUSE_TYP' THEN
       -- The anydata_val contains warehouse_typ object instance.
       rval := anydata_val.GetObject(data_p);
       -- Do something with data_p.
     ELSIF type_name = 'INVENTORY_TYP' THEN
       -- The anydata_val contains a reference to inventory_typ object instance.
       rval := anydata_val.GetRef(ref1);
       -- Do something with ref1.
     END IF;
   END LOOP;
END;
/

関連項目:

  • 「GET_datatype_ARGファンクション」

  • ANYDATAデータ型の詳細は、『Oracle Database SQL言語リファレンス』『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』および『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。


エラー・キューの管理

レプリケーション環境の管理者は、エラー・キューを定期的に監視し、ターゲット・マスター・サイトに正常に適用されなかった遅延トランザクションがあるかどうかを確認します。

エラー・キューを調べるには、ターゲット・マスター・サイトに接続した状態で、次のSELECT文を(レプリケーション管理者として)実行します。

SELECT * FROM deferror;

エラー・キューにエラーがあった場合は、エラー条件を解決し、遅延トランザクションを再実行します。遅延トランザクションを再実行するには、遅延トランザクションを受信したユーザーのセキュリティ・コンテキストで再実行するか、または別のセキュリティ・コンテキストで再実行するという、2通りの方法があります。


注意:

エラー・トランザクションが複数ある場合に、確実に正しい順序で再実行するには、次の項のプロシージャでdeferred_tran_idパラメータにNULLを指定できます。NULLを指定しない場合、個々のトランザクションが不正な順序で再実行され、競合の原因となる場合があります。

受信者としてのエラー・トランザクションの再実行

次に示すプロシージャは、遅延トランザクションを受信したユーザーのセキュリティ・コンテキストで、指定された遅延トランザクションを再実行します。このプロシージャは、エラー条件が解決した後で実行します。

これらのアクションを実行するには、次の要件を満たす必要があります。

実行者: レプリケーション管理者

実行場所: エラーの発生したサイト

レプリケーションの状態: 通常

次の手順に従います。

手順1    SQL*Plusで、レプリケーション管理者としてマスター・サイトに接続します。

SQL*Plusでデータベースに接続する方法については、『Oracle Database管理者ガイド』を参照してください。

手順2   エラー・トランザクションを再実行します。
BEGIN
   DBMS_DEFER_SYS.EXECUTE_ERROR (
      deferred_tran_id => '1.12.2904',
      destination => 'orc2.example.com');
END;
/

代替ユーザーとしてのエラー・トランザクションの再実行

次に示すプロシージャは、カレント接続ユーザーのセキュリティ・コンテキストで、指定された遅延トランザクションを再実行します。このプロシージャは、エラー条件が解決した後で実行します。

これらのアクションを実行するには、次の要件を満たす必要があります。

実行者: 接続ユーザー

実行場所: エラーの発生したサイト

レプリケーションの状態: 通常

次の手順に従います。

手順1    SQL*Plusで、代替ユーザーとしてマスター・サイトに接続します。

SQL*Plusでデータベースに接続する方法については、『Oracle Database管理者ガイド』を参照してください。

手順2   エラー・トランザクションを再実行します。
BEGIN
   DBMS_DEFER_SYS.EXECUTE_ERROR_AS_USER (
      deferred_tran_id => '1.12.2904',
      destination => 'orc2.example.com');
END;
/