ヘッダーをスキップ
Oracle Streamsレプリケーション管理者ガイド
11g リリース1(11.1)
E05776-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

20 単一ソースの異機種間レプリケーションの例

この章では、Oracle Streamsを使用して構成できる単一ソースの異機種間レプリケーション環境、およびこの環境に新しいオブジェクトおよびデータベースを追加する場合に必要となるタスクの例を説明します。

この章の内容は次のとおりです。

単一ソースの異機種間レプリケーションの例の概要

この例では、Oracle Streamsを使用して4つのデータベース間でデータをレプリケートする方法を説明します。データベースのうち3つがOracle Databaseで1つがSybaseデータベースであるため、異機種間環境です。dbs1.net Oracle Databaseで、hrスキーマ内の表に対して行われたDML変更とDDL変更が取得され、他の2つのOracle Databaseに伝播します。適用プロセスではOracle以外のデータベースにはDDL変更を適用できないため、DML変更のみが取得されてdbs4.netデータベースに伝播します。hrスキーマに対する変更は、dbs1.netでのみ発生します。hrスキーマは、環境内の他のデータベースでは読取り専用です。

図20-1に、この環境の概要を示します。

図20-1 単一ソース・データベースからのデータを共有する環境の例

図20-1の説明が続きます。
図20-1「単一ソース・データベースからのデータを共有する環境の例」の説明

図20-1に示すように、dbs1.nethrスキーマには次の表が含まれています。

この例では有向ネットワークを使用しています。これは、ソース・データベースで取得された変更が、1つ以上の中間データベースを介して他のデータベースに伝播されることを意味します。ここでは、dbs1.netデータベースから中間データベースdbs2.netを介して、dbs3.netデータベースに変更が伝播します。この構成は、有向ネットワークでのキューによる転送の一例です。また、dbs1.netデータベースからdbs2.netデータベースに変更が伝播され、そこで変更がOracle Database Gatewayを介してdbs4.netデータベースに直接適用されます。

この環境内の一部のデータベースには、特定の表がありません。データベースが表の中間データベースではなく、その表が含まれていない場合、そのデータベースには表に対する変更を伝播する必要はありません。たとえば、departmentsemployeesjob_historyおよびjobsの各表は、dbs3.netには存在しません。したがって、これらの表に対する変更はdbs2.netからdbs3.netには伝播しません。

この例では、Oracle Streamsを使用して次の一連のアクションが実行されます。

  1. 取得プロセスは、dbs1.netデータベースでhrスキーマ内のすべての表に対するDML変更とDDL変更を取得し、その変更をエンキューします。この例では、7つの表のうち4つに対する変更のみが接続先データベースに伝播されますが、「既存のOracle Streamsレプリケーション環境へのオブジェクトの追加」を示す例では、hrスキーマ内の残りの表が接続先データベースに追加されます。

  2. dbs1.netデータベースからは、これらの変更がメッセージの形式でdbs2.netのキューに伝播します。

  3. dbs2.netでは、jobs表に対するDML変更がassignments表(jobsの直接のマッピング)に対するDML変更に変換されてから適用されます。hrスキーマ内の他の表に対する変更は、dbs2.netでは適用されません。

  4. dbs3.netのキューは、dbs1.netcountrieslocationsおよびregions表で発生した変更をdbs2.netのキューから受信するため、これらの変更はdbs2.netからdbs3.netに伝播します。この構成は、有向ネットワークの一例です。

  5. dbs3.netの適用プロセスは、countrieslocationsおよびregionsの各表に変更を適用します。

  6. dbs4.netはSybaseデータベースであり、dbs1.netで発生したjobs表に対する変更をdbs2.netのキューから受信するため、これらの変更はOracle Database Gateway経由でdbs4.netのデータベース・リンクを使用してdbs2.netからリモートで適用されます。この構成は、異機種間サポートの一例です。

前提条件

この章の例を開始する前に、前提条件となる次の作業を完了する必要があります。

キューおよびデータベース・リンクの作成

次の手順を実行して、3つのOracle Databaseと1つのSybaseデータベースを含むOracle Streamsレプリケーション環境にキューおよびデータベース・リンクを作成します。

  1. 出力およびスプール結果の表示

  2. dbs1.netでのANYDATAキューの作成

  3. dbs1.netでのデータベース・リンクの作成

  4. dbs2.netでのANYDATAキューの作成

  5. dbs2.netでのデータベース・リンクの作成

  6. dbs2.netでのhr.assignments表の作成

  7. dbs3.netでのANYDATAキューの作成

  8. dbs3.netからdbs1.netへのデータベース・リンクの作成

  9. dbs3.netでのhrスキーマ内のすべての表の削除

  10. スプール結果のチェック


注意:

このマニュアルをオンラインで参照している場合、この注意の後にある「BEGINNING OF SCRIPT」の行から次の「END OF SCRIPT」の行までのテキストをテキスト・エディタにコピーし、テキストを編集してご使用の環境用のスクリプトを作成できます。環境内のすべてのデータベースに接続可能なコンピュータで、SQL*Plusを使用してスクリプトを実行します。

/************************* BEGINNING OF SCRIPT ******************************

手順1: 出力およびスプール結果の表示

SET ECHO ONを実行し、スクリプトのスプール・ファイルを指定します。このスクリプトの実行後に、スプール・ファイルにエラーがないかをチェックします。

*/

SET ECHO ON
SPOOL streams_setup_single.out

/*

手順2: dbs1.netでのANYDATAキューの作成

変更を取得するデータベースにOracle Streams管理者として接続します。この例では、データベースdbs1.netに接続します。

*/

CONNECT strmadmin@dbs1.net

/*

SET_UP_QUEUEプロシージャを実行して、dbs1.netstreams_queueというキューを作成します。このキューはANYDATAキューとして動作し、他のデータベースに伝播される取得された変更を保持します。

SET_UP_QUEUEプロシージャを実行すると、次のアクションが実行されます。

*/

EXEC DBMS_STREAMS_ADM.SET_UP_QUEUE();

/*

手順3: dbs1.netでのデータベース・リンクの作成

変更が取得されるデータベースから変更が伝播されるデータベースへのデータベース・リンクを作成します。この例では、変更が取得されるデータベースはdbs1.netです。これらの変更は、dbs2.netに伝播されます。

*/

ACCEPT password PROMPT 'Enter password for user: ' HIDE

CREATE DATABASE LINK dbs2.net CONNECT TO strmadmin IDENTIFIED BY &password
   USING 'dbs2.net';

/*

手順4: dbs2.netでのANYDATAキューの作成

Oracle Streams管理者としてdbs2.netに接続します。

*/

CONNECT strmadmin@dbs2.net

/*

SET_UP_QUEUEプロシージャを実行して、dbs2.netstreams_queueというキューを作成します。このキューはANYDATAキューとして動作し、このデータベースに適用される変更および他のデータベースに伝播される変更を保持します。

SET_UP_QUEUEプロシージャを実行すると、次のアクションが実行されます。

*/

EXEC  DBMS_STREAMS_ADM.SET_UP_QUEUE();

/*

手順5: dbs2.netでのデータベース・リンクの作成

変更が伝播されるデータベースへのデータベース・リンクを作成します。この例では、データベースdbs2.netからdbs3.net(別のOracle Database)およびdbs4.net(Sybaseデータベース)に変更が伝播されます。Sybaseデータベースへのデータベース・リンクが、Oracle Streams管理者ではなく表の所有者に接続されていることに注意してください。このデータベース・リンクは、そのデータベースのhr.jobs表を変更する権限を持つ、dbs4.netのいずれかのユーザーに接続できます。


注意:

Sybaseなどの一部のOracle以外のデータベースでは、ユーザー名およびパスワードの大/小文字が正しいことを確認する必要があります。したがって、Sybaseデータベースのユーザー名およびパスワードは、二重引用符で指定します。

*/

CREATE DATABASE LINK dbs3.net CONNECT TO strmadmin IDENTIFIED BY &password
   USING 'dbs3.net';

CREATE DATABASE LINK dbs4.net CONNECT TO "hr" IDENTIFIED BY "&password"
   USING 'dbs4.net';

/*

手順6: dbs2.netでのhr.assignments表の作成

この例では、dbs1.nethr.jobs表に対する変更をdbs2.nethr.assignments表に対する変更に変換するルールベースの変換について説明します。この例での変換を正常に実行するために、dbs2.nethr.assignments表を作成する必要があります。

hrとしてdbs2.netに接続します。

*/

CONNECT hr@dbs2.net

/*

dbs2.netデータベースにhr.assignments表を作成します。

*/

CREATE TABLE hr.assignments AS SELECT * FROM hr.jobs;

ALTER TABLE hr.assignments ADD PRIMARY KEY (job_id);

/*

手順7: dbs3.netでのANYDATAキューの作成

Oracle Streams管理者としてdbs3.netに接続します。

*/

CONNECT strmadmin@dbs3.net

/*

SET_UP_QUEUEプロシージャを実行して、dbs3.netstreams_queueというキューを作成します。このキューはANYDATAキューとして動作し、このデータベースに適用される変更を保持します。

SET_UP_QUEUEプロシージャを実行すると、次のアクションが実行されます。

*/

EXEC  DBMS_STREAMS_ADM.SET_UP_QUEUE();

/*

手順8: dbs3.netからdbs1.netへのデータベース・リンクの作成

dbs3.netからdbs1.netへのデータベース・リンクを作成します。このデータベース・リンクは、この例の後半で、手順9で削除するデータベース・オブジェクトの一部をインスタンス化するために使用します。この例では、DBMS_DATAPUMPパッケージを使用して、dbs1.netデータベースから直接これらのデータベース・オブジェクトのネットワーク・インポートを実行します。この例ではネットワーク・インポートを実行するため、ダンプ・ファイルは不要です。

または、ソース・データベースdbs1.netでエクスポートを実行し、エクスポート・ダンプ・ファイルを接続先データベースdbs3.netに転送して、接続先データベースでエクスポート・ダンプ・ファイルをインポートすることもできます。この場合、この手順で作成するデータベース・リンクは不要です。

*/

CREATE DATABASE LINK dbs1.net CONNECT TO strmadmin IDENTIFIED BY &password
   USING 'dbs1.net';

/*

手順9: dbs3.netでのhrスキーマ内のすべての表の削除

この例では、データ・ポンプを使用してdbs1.netからdbs3.netに表をインポートすることによって、hrスキーマ内の表をインスタンス化する方法について説明します。この例でのインスタンス化を正常に実行するために、dbs3.netでこれらの表を削除する必要があります。

hrとしてdbs3.netに接続します。

*/

CONNECT hr@dbs3.net

/*

dbs3.netデータベースのhrスキーマ内のすべての表を削除します。


注意:

この手順を実行してhrスキーマ内のすべての表を削除した場合、この例の残りの項の手順を実行して、dbs3.nethrスキーマを再インスタンス化する必要があります。hrスキーマがOracle Databaseに存在しない場合、Oracleマニュアル・セットの一部の例が失敗する可能性があります。

*/

DROP TABLE hr.countries CASCADE CONSTRAINTS;
DROP TABLE hr.departments CASCADE CONSTRAINTS;
DROP TABLE hr.employees CASCADE CONSTRAINTS;
DROP TABLE hr.job_history CASCADE CONSTRAINTS;
DROP TABLE hr.jobs CASCADE CONSTRAINTS;
DROP TABLE hr.locations CASCADE CONSTRAINTS;
DROP TABLE hr.regions CASCADE CONSTRAINTS;

/*

手順10: スプール結果のチェック

streams_setup_single.outスプール・ファイルをチェックして、このスクリプトの完了後にすべてのアクションが正常に終了していることを確認します。

*/

SET ECHO OFF
SPOOL OFF

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

1つのデータベースからのデータを共有するスクリプトの例

この例では、Oracle Streamsを使用してhrスキーマ内の表のレプリケーションを行う2つの方法について説明します。

1つのデータベースからのデータを共有する簡単な構成

次の手順を実行して、主にDBMS_STREAMS_ADMパッケージを使用して、取得、伝播および適用の定義を指定します。

  1. 出力およびスプール結果の表示

  2. dbs1.netでの伝播の構成

  3. dbs1.netでの取得プロセスの構成

  4. 他のデータベースでの既存の表に対するインスタンス化SCNの設定

  5. dbs3.netでのdbs1.netの表のインスタンス化

  6. dbs3.netでの適用プロセスの構成

  7. dbs3.netでの適用プロセスの適用ユーザーとしてのhrの指定

  8. hrユーザーへの適用プロセスのルール・セットに対するEXECUTE権限の付与

  9. dbs3.netでの適用プロセスの起動

  10. dbs2.netでの伝播の構成

  11. dbs2.netでの行LCRのルールベースの変換の作成

  12. dbs2.netでのローカル適用を実行するための適用プロセスの構成

  13. dbs2.netでの適用プロセスの適用ユーザーとしてのhrの指定

  14. hrユーザーへの適用プロセスのルール・セットに対するEXECUTE権限の付与

  15. dbs2.netでのローカル適用を実行するための適用プロセスの起動

  16. dbs4.netでの適用を実行するためのdbs2.netでの適用プロセスの構成

  17. dbs4.netでの適用を実行するためのdbs2.netでの適用プロセスの起動

  18. dbs1.netでの取得プロセスの起動

  19. スプール結果のチェック


注意:

このマニュアルをオンラインで参照している場合、この注意の後にある「BEGINNING OF SCRIPT」の行から次の「END OF SCRIPT」の行までのテキストをテキスト・エディタにコピーし、テキストを編集してご使用の環境用のスクリプトを作成できます。環境内のすべてのデータベースに接続可能なコンピュータで、SQL*Plusを使用してスクリプトを実行します。

/************************* BEGINNING OF SCRIPT ******************************

手順1: 出力およびスプール結果の表示

SET ECHO ONを実行し、スクリプトのスプール・ファイルを指定します。このスクリプトの実行後に、スプール・ファイルにエラーがないかをチェックします。

*/

SET ECHO ON
SPOOL streams_share_schema1.out

/*

手順2: dbs1.netでの伝播の構成

strmadminユーザーとしてdbs1.netに接続します。

*/

CONNECT strmadmin@dbs1.net

/*

dbs1.netのキューからdbs2.netのキューへのhrスキーマ内のDML変更およびDDL変更の伝播を構成およびスケジュールします。

*/

BEGIN
  DBMS_STREAMS_ADM.ADD_SCHEMA_PROPAGATION_RULES(
    schema_name             => 'hr',
    streams_name            => 'dbs1_to_dbs2',
    source_queue_name       => 'strmadmin.streams_queue',
    destination_queue_name  => 'strmadmin.streams_queue@dbs2.net',
    include_dml             => TRUE,
    include_ddl             => TRUE,
    source_database         => 'dbs1.net',
    inclusion_rule          => TRUE,
    queue_to_queue          => TRUE);
END;
/

/*

手順3: dbs1.netでの取得プロセスの構成

dbs1.nethrスキーマ全体に対する変更を取得するように取得プロセスを構成します。この手順では、指定したスキーマ内の表に対する変更が取得プロセスによって取得され、指定したキューにエンキューされるように指定します。

また、この手順では、hrスキーマをインスタンス化のために準備し、このスキーマ内の表のすべての主キー列、一意キー列、ビットマップ索引列および外部キー列のサプリメンタル・ロギングを有効にします。サプリメンタル・ロギングによって、表に対する変更の追加の情報がREDOログに記録されます。適用プロセスでは、一意の行の識別や競合解消など、一部の操作を実行するために、この追加情報が必要です。この環境では、dbs1.netデータベースでのみ変更が取得されるため、hrスキーマ内の表に対してサプリメンタル・ロギングを指定する必要があるのはこのデータベースのみです。

*/

BEGIN
  DBMS_STREAMS_ADM.ADD_SCHEMA_RULES(
    schema_name    => 'hr',
    streams_type   => 'capture',
    streams_name   => 'capture',
    queue_name     => 'strmadmin.streams_queue',
    include_dml    => TRUE,
    include_ddl    => TRUE,
    inclusion_rule => TRUE);
END;
/

/*

手順4: 他のデータベースでの既存の表に対するインスタンス化SCNの設定

この例では、dbs2.netおよびdbs4.nethr.jobs表がすでに存在します。dbs2.netでは、この表の名前はassignmentsですが、この表はdbs1.netjobs表と同じ形式で、同じデータを含んでいます。また、この例では、dbs4.netはSybaseデータベースです。Oracle Streams環境内の他のすべての表が、データ・ポンプ・インポートを使用して他の接続先データベースでインスタンス化されます。

hr.jobs表はdbs2.netおよびdbs4.netにすでに存在するため、この例では、dbs1.netDBMS_FLASHBACKパッケージのGET_SYSTEM_CHANGE_NUMBERファンクションを使用して、データベースの現行のSCNを取得します。このSCNは、dbs2.netDBMS_APPLY_ADMパッケージのSET_TABLE_INSTANTIATION_SCNプロシージャを実行するために使用されます。このプロシージャを2回実行して、dbs2.netおよびdbs4.nethr.jobs表にインスタンス化SCNを設定します。

SET_TABLE_INSTANTIATION_SCNプロシージャを使用すると、適用プロセスで無視される表のLCRと、適用プロセスで適用される表のLCRを制御できます。ソース・データベースからの表に関するLCRのコミットSCNが、接続先データベースでその表のインスタンス化SCN以下であれば、接続先データベースの適用プロセスではLCRが廃棄されます。それ以外の場合は、適用プロセスによってLCRが適用されます。

この例では、dbs2.netの適用プロセスは、この手順で取得したSCNの後にコミットされたSCNを持つhr.jobs表にトランザクションを適用します。


注意:

この例では、dbs1.netdbs2.netおよびdbs4.nethr.jobs表(dbs2.netの場合はhr.assignments)の内容は、この手順の実行時に一貫性があると想定しています。一貫性を確保するために、この手順の実行中に各データベースの表をロックすることをお薦めします。

*/

DECLARE
  iscn  NUMBER;         -- Variable to hold instantiation SCN value
BEGIN
  iscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();
  DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN@DBS2.NET(
    source_object_name    => 'hr.jobs',
    source_database_name  => 'dbs1.net',
    instantiation_scn     => iscn);
  DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN@DBS2.NET(
    source_object_name    => 'hr.jobs',
    source_database_name  => 'dbs1.net',
    instantiation_scn     => iscn,
    apply_database_link   => 'dbs4.net');
END;
/

/*

手順5: dbs3.netでのdbs1.netの表のインスタンス化

この例では、データ・ポンプを使用して次の表のネットワーク・インポートを実行します。

  • hr.countries

  • hr.locations

  • hr.regions

ネットワーク・インポートとは、エクスポート・ダンプ・ファイルを使用せずに、データ・ポンプでdbs1.netからこれらの表をインポートすることを意味します。


参照:

インポートを実行する方法の詳細は、『Oracle Databaseユーティリティ』を参照してください。

strmadminユーザーとしてdbs3.netに接続します。

*/

CONNECT strmadmin@dbs3.net

/*

この例では、DBMS_DATAPUMPパッケージを使用して表のインポートを実行します。簡略化するために、どのAPIコールからの例外も捕捉されません。ただし、例外ハンドラを定義し、障害発生時にGET_STATUSをコールしてエラーの詳細情報を取得することをお薦めします。インポートを監視する場合は、インポート・データベースでDBA_DATAPUMP_JOBSデータ・ディクショナリ・ビューを問い合せます。

*/

SET SERVEROUTPUT ON
DECLARE
  h1        NUMBER;         -- Data Pump job handle
  sscn      NUMBER;         -- Variable to hold current source SCN
  job_state VARCHAR2(30);   -- To keep track of job state
  js        ku$_JobStatus;  -- The job status from GET_STATUS
  sts       ku$_Status;     -- The status object returned by GET_STATUS
  job_not_exist    exception;
  pragma exception_init(job_not_exist, -31626);
BEGIN
-- Create a (user-named) Data Pump job to do a table-level import.
  h1 := DBMS_DATAPUMP.OPEN(
          operation   => 'IMPORT',
          job_mode    => 'TABLE',
          remote_link => 'DBS1.NET',
          job_name    => 'dp_sing1');
-- A metadata filter is used to specify the schema that owns the tables
-- that will be imported.
  DBMS_DATAPUMP.METADATA_FILTER(
    handle    => h1,
    name      => 'SCHEMA_EXPR',
    value     => '=''HR''');
-- A metadata filter is used to specify the tables that will be imported.
  DBMS_DATAPUMP.METADATA_FILTER(
    handle    => h1,
    name      => 'NAME_EXPR',
    value     => 'IN(''COUNTRIES'', ''REGIONS'', ''LOCATIONS'')');
-- Get the current SCN of the source database, and set the FLASHBACK_SCN
-- parameter to this value to ensure consistency between all of the
-- objects included in the import.
  sscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER@dbs1.net();
  DBMS_DATAPUMP.SET_PARAMETER(
    handle => h1,
    name   => 'FLASHBACK_SCN',
    value  => sscn);
-- Start the job.
  DBMS_DATAPUMP.START_JOB(h1);
-- The import job should be running. In the following loop, the job
-- is monitored until it completes.
  job_state := 'UNDEFINED';
  BEGIN
    WHILE (job_state != 'COMPLETED') AND (job_state != 'STOPPED') LOOP
      sts:=DBMS_DATAPUMP.GET_STATUS(
             handle  => h1,
             mask    => DBMS_DATAPUMP.KU$_STATUS_JOB_ERROR +
                        DBMS_DATAPUMP.KU$_STATUS_JOB_STATUS +
                        DBMS_DATAPUMP.KU$_STATUS_WIP,
             timeout => -1);
      js := sts.job_status;
      DBMS_LOCK.SLEEP(10);
      job_state := js.state;
    END LOOP;
  -- Gets an exception when job no longer exists
    EXCEPTION WHEN job_not_exist THEN
      DBMS_OUTPUT.PUT_LINE('Data Pump job has completed');
      DBMS_OUTPUT.PUT_LINE('Instantiation SCN: ' ||sscn);
  END;
END;
/

/*

手順6: dbs3.netでの適用プロセスの構成

strmadminユーザーとしてdbs3.netに接続します。

*/

CONNECT strmadmin@dbs3.net

/*

countries表、locations表およびregions表に変更を適用するようにdbs3.netを構成します。

*/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_RULES(
    table_name      => 'hr.countries',
    streams_type    => 'apply',
    streams_name    => 'apply',
    queue_name      => 'strmadmin.streams_queue',
    include_dml     => TRUE,
    include_ddl     => TRUE,
    source_database => 'dbs1.net',
    inclusion_rule  => TRUE);
END;
/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_RULES(
    table_name      => 'hr.locations',
    streams_type    => 'apply',
    streams_name    => 'apply',
    queue_name      => 'strmadmin.streams_queue',
    include_dml     => TRUE,
    include_ddl     => TRUE,
    source_database => 'dbs1.net',
    inclusion_rule  => TRUE);
END;
/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_RULES(
    table_name      => 'hr.regions',
    streams_type    => 'apply',
    streams_name    => 'apply',
    queue_name      => 'strmadmin.streams_queue',
    include_dml     => TRUE,
    include_ddl     => TRUE,
    source_database => 'dbs1.net',
    inclusion_rule  => TRUE);
END;
/

/*

手順7: dbs3.netでの適用プロセスの適用ユーザーとしてのhrの指定

この例では、hrユーザーが、このデータベースで適用プロセスによって変更が適用されるすべてのデータベース・オブジェクトを所有します。したがって、hrはこれらのデータベース・オブジェクトを変更するために必要な権限をすでに持っており、hrを適用ユーザーにすることが有効です。

前述の手順で適用プロセスを作成したときに、適用プロセスを作成したプロシージャをOracle Streams管理者strmadminが実行したため、デフォルトでは、strmadminが適用ユーザーとして指定されています。hrを適用ユーザーとして指定するかわりに、strmadminを適用ユーザーのままにしておくこともできますが、この場合、変更が適用されるすべてのデータベース・オブジェクトに対する権限、および適用プロセスで使用されるすべてのユーザー・プロシージャを実行する権限をstrmadminに付与する必要があります。適用プロセスが複数のスキーマ内のデータベース・オブジェクトに変更を適用する環境では、Oracle Streams管理者を適用ユーザーとして使用する方が有効な場合があります。


参照:

Oracle Streams管理者を構成する方法の詳細は、『Oracle Streams概要および管理』を参照してください。

*/

BEGIN
  DBMS_APPLY_ADM.ALTER_APPLY(
    apply_name => 'apply',
    apply_user => 'hr');
END;
/

/*

手順8: hrユーザーへの適用プロセスのルール・セットに対するEXECUTE権限の付与

前述の手順でhrユーザーを適用ユーザーとして指定したため、hrユーザーには、適用プロセスで使用されるポジティブ・ルール・セットに対するEXECUTE権限が必要です。

*/

DECLARE
   rs_name  VARCHAR2(64);   -- Variable to hold rule set name
BEGIN
  SELECT RULE_SET_OWNER||'.'||RULE_SET_NAME
    INTO rs_name
    FROM DBA_APPLY
    WHERE APPLY_NAME='APPLY';
  DBMS_RULE_ADM.GRANT_OBJECT_PRIVILEGE(
    privilege   => SYS.DBMS_RULE_ADM.EXECUTE_ON_RULE_SET,
    object_name => rs_name,
    grantee     => 'hr');
END;
/

/*

手順9: dbs3.netでの適用プロセスの起動

エラーが発生した場合に適用プロセスが無効化されないように、disable_on_errorパラメータをnに設定して、dbs3.netで適用プロセスを起動します。

*/

BEGIN
  DBMS_APPLY_ADM.SET_PARAMETER(
    apply_name  => 'apply',
    parameter   => 'disable_on_error',
    value       => 'N');
END;
/

BEGIN
  DBMS_APPLY_ADM.START_APPLY(
    apply_name  => 'apply');
END;
/

/*

手順10: dbs2.netでの伝播の構成

strmadminユーザーとしてdbs2.netに接続します。

*/

CONNECT strmadmin@dbs2.net

/*

dbs2.netのキューからdbs3.netのキューへの伝播を構成およびスケジュールします。この伝播は、dbs3.netで変更を適用する表ごとに指定する必要があります。dbs2.netの変更はdbs1.netで発生したものであるため、この構成は、有向ネットワークの一例です。

*/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_PROPAGATION_RULES(
    table_name               => 'hr.countries',
    streams_name             => 'dbs2_to_dbs3',
    source_queue_name        => 'strmadmin.streams_queue',
    destination_queue_name   => 'strmadmin.streams_queue@dbs3.net',
    include_dml              => TRUE,
    include_ddl              => TRUE,
    source_database          => 'dbs1.net',
    inclusion_rule           => TRUE,
    queue_to_queue           => TRUE);
END;
/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_PROPAGATION_RULES(
    table_name              => 'hr.locations',
    streams_name            => 'dbs2_to_dbs3',
    source_queue_name       => 'strmadmin.streams_queue',
    destination_queue_name  => 'strmadmin.streams_queue@dbs3.net',
    include_dml             => TRUE,
    include_ddl             => TRUE,
    source_database         => 'dbs1.net',
    inclusion_rule          => TRUE);
END;
/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_PROPAGATION_RULES(
    table_name              => 'hr.regions',
    streams_name            => 'dbs2_to_dbs3',
    source_queue_name       => 'strmadmin.streams_queue',
    destination_queue_name  => 'strmadmin.streams_queue@dbs3.net',
    include_dml             => TRUE,
    include_ddl             => TRUE,
    source_database         => 'dbs1.net',
    inclusion_rule          => TRUE);
END;
/

/*

手順11: dbs2.netでの行LCRのルールベースの変換の作成

hrユーザーとしてdbs2.netに接続します。

*/

CONNECT hr@dbs2.net

/*

dbs1.netjobs表に対するDML文によって発生する行変更をdbs2.netassignments表に対する行変更に変換するルールベースの変換ファンクションを作成します。

次のファンクションを実行すると、jobs表のすべての行LCRがassignments表の行LCRに変換されます。


注意:

assignments表にDDL変更も適用された場合、DDL LCR用に別の変換が必要になります。この変換では、オブジェクト名およびDDLテキストを変更する必要があります。

*/

CREATE OR REPLACE FUNCTION hr.to_assignments_trans_dml(
  p_in_data in ANYDATA)
  RETURN ANYDATA IS out_data SYS.LCR$_ROW_RECORD;
  tc   pls_integer;
BEGIN
  -- Typecast AnyData to LCR$_ROW_RECORD
     tc := p_in_data.GetObject(out_data);
     IF out_data.GET_OBJECT_NAME() = 'JOBS'
     THEN
  -- Transform the in_data into the out_data
     out_data.SET_OBJECT_NAME('ASSIGNMENTS');
     END IF;
  -- Convert to AnyData
     RETURN ANYDATA.ConvertObject(out_data);
END;
/

/*

手順12: dbs2.netでのローカル適用を実行するための適用プロセスの構成

strmadminユーザーとしてdbs2.netに接続します。

*/

CONNECT strmadmin@dbs2.net

/*

assignments表に変更を適用するようにdbs2.netを構成します。assignments表がdbs1.netjobs表から変更を受信することに注意してください。

*/

DECLARE
  to_assignments_rulename_dml   VARCHAR2(30);
  dummy_rule                    VARCHAR2(30);
BEGIN
--  DML changes to the jobs table from dbs1.net are applied to the assignments
--  table. The to_assignments_rulename_dml variable is an out parameter
--  in this call.
  DBMS_STREAMS_ADM.ADD_TABLE_RULES(
    table_name      => 'hr.jobs', -- jobs, not assignments, specified
    streams_type    => 'apply',
    streams_name    => 'apply_dbs2',
    queue_name      => 'strmadmin.streams_queue',
    include_dml     => TRUE,
    include_ddl     => FALSE,
    source_database => 'dbs1.net',
    dml_rule_name   => to_assignments_rulename_dml,
    ddl_rule_name   => dummy_rule,
    inclusion_rule  => TRUE);
--  Modify the rule for the hr.jobs table to use the transformation function.
  DBMS_STREAMS_ADM.SET_RULE_TRANSFORM_FUNCTION(
    rule_name          => to_assignments_rulename_dml,
    transform_function => 'hr.to_assignments_trans_dml');
END;
/

/*

手順13: dbs2.netでの適用プロセスの適用ユーザーとしてのhrの指定

この例では、hrユーザーが、このデータベースで適用プロセスによって変更が適用されるすべてのデータベース・オブジェクトを所有します。したがって、hrはこれらのデータベース・オブジェクトを変更するために必要な権限をすでに持っており、hrを適用ユーザーにすることが有効です。

前述の手順で適用プロセスを作成したときに、適用プロセスを作成したプロシージャをOracle Streams管理者strmadminが実行したため、デフォルトでは、strmadminが適用ユーザーとして指定されています。hrを適用ユーザーとして指定するかわりに、strmadminを適用ユーザーのままにしておくこともできますが、この場合、変更が適用されるすべてのデータベース・オブジェクトに対する権限、および適用プロセスで使用されるすべてのユーザー・プロシージャを実行する権限をstrmadminに付与する必要があります。適用プロセスが複数のスキーマ内のデータベース・オブジェクトに変更を適用する環境では、Oracle Streams管理者を適用ユーザーとして使用する方が有効な場合があります。


参照:

Oracle Streams管理者を構成する方法の詳細は、『Oracle Streams概要および管理』を参照してください。

*/

BEGIN
  DBMS_APPLY_ADM.ALTER_APPLY(
    apply_name => 'apply_dbs2',
    apply_user => 'hr');
END;
/

/*

手順14: hrユーザーへの適用プロセスのルール・セットに対するEXECUTE権限の付与

前述の手順でhrユーザーを適用ユーザーとして指定したため、hrユーザーには、適用プロセスで使用されるポジティブ・ルール・セットに対するEXECUTE権限が必要です。

*/

DECLARE
   rs_name  VARCHAR2(64);   -- Variable to hold rule set name
BEGIN
  SELECT RULE_SET_OWNER||'.'||RULE_SET_NAME
    INTO rs_name
    FROM DBA_APPLY
    WHERE APPLY_NAME='APPLY_DBS2';
  DBMS_RULE_ADM.GRANT_OBJECT_PRIVILEGE(
    privilege   => SYS.DBMS_RULE_ADM.EXECUTE_ON_RULE_SET,
    object_name => rs_name,
    grantee     => 'hr');
END;
/

/*

手順15: dbs2.netでのローカル適用を実行するための適用プロセスの起動

エラーが発生した場合に適用プロセスが無効化されないように、disable_on_errorパラメータをnに設定して、dbs2.netでローカル適用を実行するために適用プロセスを起動します。

*/

BEGIN
  DBMS_APPLY_ADM.SET_PARAMETER(
    apply_name  => 'apply_dbs2',
    parameter   => 'disable_on_error',
    value       => 'N');
END;
/

BEGIN
  DBMS_APPLY_ADM.START_APPLY(
    apply_name  => 'apply_dbs2');
END;
/

/*

手順16: dbs4.netでの適用を実行するためのdbs2.netでの適用プロセスの構成

dbs4.net(Sybaseデータベース)の適用プロセスを構成します。dbs2.netデータベースは、dbs4.netへのゲートウェイとして機能しています。したがって、dbs4.netの適用プロセスは、dbs2.netで構成する必要があります。適用プロセスでDDL変更をOracle以外のデータベースに適用することはできません。したがって、ADD_TABLE_RULESプロシージャの実行時に、include_ddlパラメータがFALSEに設定されています。

*/

BEGIN
  DBMS_APPLY_ADM.CREATE_APPLY(
    queue_name          => 'strmadmin.streams_queue',
    apply_name          => 'apply_dbs4',
    apply_database_link => 'dbs4.net',
    apply_captured      => TRUE);
END;
/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_RULES(
    table_name      => 'hr.jobs',
    streams_type    => 'apply',
    streams_name    => 'apply_dbs4',
    queue_name      => 'strmadmin.streams_queue',
    include_dml     => TRUE,
    include_ddl     => FALSE,
    source_database => 'dbs1.net',
    inclusion_rule  => TRUE);
END;
/

/*

手順17: dbs4.netでの適用を実行するためのdbs2.netでの適用プロセスの起動

エラーが発生した場合に適用プロセスが無効化されないように、disable_on_errorパラメータをnに設定して、データベース・リンクdbs4.netを使用してSybaseのリモート適用を開始します。

*/

BEGIN
  DBMS_APPLY_ADM.SET_PARAMETER(
    apply_name  => 'apply_dbs4',
    parameter   => 'disable_on_error',
    value       => 'N');
END;
/

BEGIN
  DBMS_APPLY_ADM.START_APPLY(
    apply_name  => 'apply_dbs4');
END;
/

/*

手順18: dbs1.netでの取得プロセスの起動

strmadminユーザーとしてdbs1.netに接続します。

*/

CONNECT strmadmin@dbs1.net

/*

dbs1.netで取得プロセスを起動します。

*/

BEGIN
  DBMS_CAPTURE_ADM.START_CAPTURE(
    capture_name  => 'capture');
END;
/

/*

手順19: スプール結果のチェック

streams_share_schema1.outスプール・ファイルをチェックして、このスクリプトの完了後にすべてのアクションが正常に終了していることを確認します。

*/

SET ECHO OFF
SPOOL OFF

/*

ここで、dbs1.netの特定の表に対してDML変更およびDDL変更を行い、この環境内のOracle Streamsプロセスおよび伝播について構成したルールに基づいて、環境内の他のデータベースにこれらの変更がレプリケートされていることを確認できます。


参照:

この環境内でレプリケートされる変更の例については、「hrスキーマ内の表に対するDML変更およびDDL変更」を参照してください。

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

1つのデータベースからのデータを共有する柔軟な構成

次の手順を実行して、より柔軟な方法を使用して、取得、伝播および適用の定義を指定します。この方法では、DBMS_STREAMS_ADMパッケージを使用しません。かわりに、次のパッケージを使用します。

  • DBMS_CAPTURE_ADMパッケージ。取得プロセスを構成します。

  • DBMS_PROPAGATION_ADMパッケージ。伝播を構成します。

  • DBMS_APPLY_ADMパッケージ。適用プロセスを構成します。

  • DBMS_RULES_ADMパッケージ。取得プロセス、伝播および適用プロセスのルールおよびルール・セットを指定します。


    注意:

    ALL_STREAMS_TABLE_RULESおよびDBA_STREAMS_TABLE_RULESデータ・ディクショナリ・ビューはいずれも、この例で作成するルールでは移入されません。この例で作成されるルールを表示するには、ALL_STREAMS_RULESまたはDBA_STREAMS_RULESデータ・ディクショナリ・ビューを問い合せます。

この例の手順は次のとおりです。

  1. 出力およびスプール結果の表示

  2. dbs1.netでの伝播の構成

  3. dbs1.netでの取得プロセスの構成

  4. dbs1.netでのhrスキーマのインスタンス化のための準備

  5. 他のデータベースでの既存の表に対するインスタンス化SCNの設定

  6. dbs3.netでのdbs1.netの表のインスタンス化

  7. dbs3.netでの適用プロセスの構成

  8. hrユーザーへの適用プロセスのルール・セットに対するEXECUTE権限の付与

  9. dbs3.netでの適用プロセスの起動

  10. dbs2.netでの伝播の構成

  11. dbs2.netでの行LCRのルールベースの変換の作成

  12. dbs2.netでのローカル適用を実行するための適用プロセスの構成

  13. hrユーザーへの適用プロセスのルール・セットに対するEXECUTE権限の付与

  14. dbs2.netでのローカル適用を実行するための適用プロセスの起動

  15. dbs4.netでの適用を実行するためのdbs2.netでの適用プロセスの構成

  16. dbs4.netでの適用を実行するためのdbs2.netでの適用プロセスの起動

  17. dbs1.netでの取得プロセスの起動

  18. スプール結果のチェック


注意:

このマニュアルをオンラインで参照している場合、この注意の後にある「BEGINNING OF SCRIPT」の行から次の「END OF SCRIPT」の行までのテキストをテキスト・エディタにコピーし、テキストを編集してご使用の環境用のスクリプトを作成できます。環境内のすべてのデータベースに接続可能なコンピュータで、SQL*Plusを使用してスクリプトを実行します。

/************************* BEGINNING OF SCRIPT ******************************

手順1: 出力およびスプール結果の表示

SET ECHO ONを実行し、スクリプトのスプール・ファイルを指定します。このスクリプトの実行後に、スプール・ファイルにエラーがないかをチェックします。

*/

SET ECHO ON
SPOOL streams_share_schema2.out

/*

手順2: dbs1.netでの伝播の構成

strmadminユーザーとしてdbs1.netに接続します。

*/

CONNECT strmadmin@dbs1.net

/*

dbs1.netのキューからdbs2.netのキューへの伝播を構成およびスケジュールします。この構成では、伝播によってhrスキーマに対するすべての変更が伝播されるように指定します。ルール・セットの指定を省略することもできますが、この場合、キュー内のすべてのものが伝播されます。これは、将来複数の取得プロセスでstreams_queueを使用する場合に望ましくない場合があります。

*/

BEGIN
  -- Create the rule set
  DBMS_RULE_ADM.CREATE_RULE_SET(
    rule_set_name       => 'strmadmin.propagation_dbs1_rules',
    evaluation_context  => 'SYS.STREAMS$_EVALUATION_CONTEXT');
  -- Create rules for all modifications to the hr schema
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name  => 'strmadmin.all_hr_dml',
    condition  => ' :dml.get_object_owner() = ''HR'' AND ' ||
                  ' :dml.is_null_tag() = ''Y'' AND ' ||
                  ' :dml.get_source_database_name() = ''DBS1.NET'' ');
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name  => 'strmadmin.all_hr_ddl',
    condition  => ' (:ddl.get_object_owner() = ''HR'' OR ' ||
                  ' :ddl.get_base_table_owner() =   ''HR'') AND ' ||
                  ' :ddl.is_null_tag() = ''Y'' AND ' ||
                  ' :ddl.get_source_database_name() = ''DBS1.NET'' ');
  -- Add rules to rule set
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_hr_dml',
    rule_set_name  => 'strmadmin.propagation_dbs1_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_hr_ddl',
    rule_set_name  => 'strmadmin.propagation_dbs1_rules');
  -- Create a propagation that uses the rule set as its positive rule set
  DBMS_PROPAGATION_ADM.CREATE_PROPAGATION(
    propagation_name    => 'dbs1_to_dbs2',
    source_queue        => 'strmadmin.streams_queue',
    destination_queue   => 'strmadmin.streams_queue',
    destination_dblink  => 'dbs2.net',
    rule_set_name       => 'strmadmin.propagation_dbs1_rules');
END;
/

/*

手順3: dbs1.netでの取得プロセスの構成

dbs1.nethrスキーマ全体を取得する取得プロセスおよびルールを作成します。

*/

BEGIN
  -- Create the rule set
  DBMS_RULE_ADM.CREATE_RULE_SET(
    rule_set_name       => 'strmadmin.demo_rules',
    evaluation_context  => 'SYS.STREAMS$_EVALUATION_CONTEXT');
  --   Create rules that specify the entire hr schema
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name  => 'strmadmin.schema_hr_dml',
    condition  => ' :dml.get_object_owner() = ''HR''  AND ' ||
                  ' :dml.is_null_tag() = ''Y'' AND ' ||
                  ' :dml.get_source_database_name() = ''DBS1.NET'' ');
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name  => 'strmadmin.schema_hr_ddl',
    condition  => ' (:ddl.get_object_owner() = ''HR'' OR ' ||
                  ' :ddl.get_base_table_owner() =   ''HR'') AND ' ||
                  ' :ddl.is_null_tag() = ''Y'' AND ' ||
                  ' :ddl.get_source_database_name() = ''DBS1.NET'' ');
  --  Add the rules to the rule set
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.schema_hr_dml',
    rule_set_name  => 'strmadmin.demo_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.schema_hr_ddl',
    rule_set_name  => 'strmadmin.demo_rules');
  --  Create a capture process that uses the rule set as its positive rule set
  DBMS_CAPTURE_ADM.CREATE_CAPTURE(
    queue_name    => 'strmadmin.streams_queue',
    capture_name  => 'capture',
    rule_set_name => 'strmadmin.demo_rules');
END;
/

/*

手順4: dbs1.netでのhrスキーマのインスタンス化のための準備

dbs1.netにOracle Streams管理者として接続したままで、dbs3.netdbs1.nethrスキーマをインスタンス化のために準備します。この手順では、インスタンス化のためにスキーマ内の表の最小SCNにマークが付けられます。最小SCNより後のSCNは、インスタンス化に使用できます。

また、この手順では、hrスキーマ内の表のすべての主キー列、一意キー列、ビットマップ索引列および外部キー列のサプリメンタル・ロギングを有効にします。サプリメンタル・ロギングによって、表に対する変更の追加の情報がREDOログに記録されます。適用プロセスでは、一意の行の識別や競合解消など、一部の操作を実行するために、この追加情報が必要です。この環境では、dbs1.netデータベースでのみ変更が取得されるため、hrスキーマ内の表に対してサプリメンタル・ロギングを指定する必要があるのはこのデータベースのみです。


注意:

この手順は、「1つのデータベースからのデータを共有する簡単な構成」では不要です。簡単な構成の例では、手順3DBMS_STREAMS_ADMパッケージのADD_SCHEMA_RULESプロシージャを実行するときに、DBMS_CAPTURE_ADMパッケージのPREPARE_SCHEMA_INSTANTIATIONプロシージャがhrスキーマに対して自動的に実行されます。

*/

BEGIN
  DBMS_CAPTURE_ADM.PREPARE_SCHEMA_INSTANTIATION(
    schema_name          => 'hr',
    supplemental_logging => 'keys');
END;
/

/*

手順5: 他のデータベースでの既存の表に対するインスタンス化SCNの設定

この例では、dbs2.netおよびdbs4.nethr.jobs表がすでに存在します。dbs2.netでは、この表の名前はassignmentsですが、この表はdbs1.netjobs表と同じ形式で、同じデータを含んでいます。また、この例では、dbs4.netはSybaseデータベースです。Oracle Streams環境内の他のすべての表が、データ・ポンプ・インポートを使用して他の接続先データベースでインスタンス化されます。

hr.jobs表はdbs2.netおよびdbs4.netにすでに存在するため、この例では、dbs1.netDBMS_FLASHBACKパッケージのGET_SYSTEM_CHANGE_NUMBERファンクションを使用して、データベースの現行のSCNを取得します。このSCNは、dbs2.netDBMS_APPLY_ADMパッケージのSET_TABLE_INSTANTIATION_SCNプロシージャを実行するために使用されます。このプロシージャを2回実行して、dbs2.netおよびdbs4.nethr.jobs表にインスタンス化SCNを設定します。

SET_TABLE_INSTANTIATION_SCNプロシージャを使用すると、適用プロセスで無視される表のLCRと、適用プロセスで適用される表のLCRを制御できます。ソース・データベースからの表に関するLCRのコミットSCNが、接続先データベースでその表のインスタンス化SCN以下であれば、接続先データベースの適用プロセスではLCRが廃棄されます。それ以外の場合は、適用プロセスによってLCRが適用されます。

この例では、dbs2.netの適用プロセスは、この手順で取得したSCNの後にコミットされたSCNを持つhr.jobs表にトランザクションを適用します。


注意:

この例では、dbs1.netdbs2.netおよびdbs4.nethr.jobs表(dbs2.netの場合はhr.assignments)の内容は、この手順の実行時に一貫性があると想定しています。一貫性を確保するために、この手順の実行中に各データベースの表をロックすることをお薦めします。

*/

DECLARE
  iscn  NUMBER;         -- Variable to hold instantiation SCN value
BEGIN
  iscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER();
  DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN@DBS2.NET(
    source_object_name    => 'hr.jobs',
    source_database_name  => 'dbs1.net',
    instantiation_scn     => iscn);
  DBMS_APPLY_ADM.SET_TABLE_INSTANTIATION_SCN@DBS2.NET(
    source_object_name    => 'hr.jobs',
    source_database_name  => 'dbs1.net',
    instantiation_scn     => iscn,
    apply_database_link   =>     'dbs4.net');
END;
/

/*

手順6: dbs3.netでのdbs1.netの表のインスタンス化

この例では、データ・ポンプを使用して次の表のネットワーク・インポートを実行します。

  • hr.countries

  • hr.locations

  • hr.regions

ネットワーク・インポートとは、エクスポート・ダンプ・ファイルを使用せずに、データ・ポンプでdbs1.netからこれらの表をインポートすることを意味します。


参照:

インポートを実行する方法の詳細は、『Oracle Databaseユーティリティ』を参照してください。

strmadminユーザーとしてdbs3.netに接続します。

*/

CONNECT strmadmin@dbs3.net

/*

この例では、DBMS_DATAPUMPパッケージを使用して表のインポートを実行します。簡略化するために、どのAPIコールからの例外も捕捉されません。ただし、例外ハンドラを定義し、障害発生時にGET_STATUSをコールしてエラーの詳細情報を取得することをお薦めします。インポートを監視する場合は、インポート・データベースでDBA_DATAPUMP_JOBSデータ・ディクショナリ・ビューを問い合せます。

*/

SET SERVEROUTPUT ON
DECLARE
  h1        NUMBER;         -- Data Pump job handle
  sscn      NUMBER;         -- Variable to hold current source SCN
  job_state VARCHAR2(30);   -- To keep track of job state
  js        ku$_JobStatus;  -- The job status from GET_STATUS
  sts       ku$_Status;     -- The status object returned by GET_STATUS
  job_not_exist    exception;
  pragma exception_init(job_not_exist, -31626);
BEGIN
-- Create a (user-named) Data Pump job to do a table-level import.
  h1 := DBMS_DATAPUMP.OPEN(
          operation   => 'IMPORT',
          job_mode    => 'TABLE',
          remote_link => 'DBS1.NET',
          job_name    => 'dp_sing2');
-- A metadata filter is used to specify the schema that owns the tables
-- that will be imported.
  DBMS_DATAPUMP.METADATA_FILTER(
    handle    => h1,
    name      => 'SCHEMA_EXPR',
    value     => '=''HR''');
-- A metadata filter is used to specify the tables that will be imported.
  DBMS_DATAPUMP.METADATA_FILTER(
    handle    => h1,
    name      => 'NAME_EXPR',
    value     => 'IN(''COUNTRIES'', ''REGIONS'', ''LOCATIONS'')');
-- Get the current SCN of the source database, and set the FLASHBACK_SCN
-- parameter to this value to ensure consistency between all of the
-- objects included in the import.
  sscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER@dbs1.net();
  DBMS_DATAPUMP.SET_PARAMETER(
    handle => h1,
    name   => 'FLASHBACK_SCN',
    value  => sscn);
-- Start the job.
  DBMS_DATAPUMP.START_JOB(h1);
-- The import job should be running. In the following loop, the job
-- is monitored until it completes.
  job_state := 'UNDEFINED';
  BEGIN
    WHILE (job_state != 'COMPLETED') AND (job_state != 'STOPPED') LOOP
      sts:=DBMS_DATAPUMP.GET_STATUS(
             handle  => h1,
             mask    => DBMS_DATAPUMP.KU$_STATUS_JOB_ERROR +
                        DBMS_DATAPUMP.KU$_STATUS_JOB_STATUS +
                        DBMS_DATAPUMP.KU$_STATUS_WIP,
             timeout => -1);
      js := sts.job_status;
      DBMS_LOCK.SLEEP(10);
      job_state := js.state;
    END LOOP;
  -- Gets an exception when job no longer exists
    EXCEPTION WHEN job_not_exist THEN
      DBMS_OUTPUT.PUT_LINE('Data Pump job has completed');
      DBMS_OUTPUT.PUT_LINE('Instantiation SCN: ' ||sscn);
  END;
END;
/

/*

手順7: dbs3.netでの適用プロセスの構成

strmadminユーザーとしてdbs3.netに接続します。

*/

CONNECT strmadmin@dbs3.net

/*

countries表、locations表およびregions表にDML変更およびDDL変更を適用するようにdbs3.netを構成します。

*/

BEGIN
  -- Create the rule set
  DBMS_RULE_ADM.CREATE_RULE_SET(
    rule_set_name       => 'strmadmin.apply_rules',
    evaluation_context  => 'SYS.STREAMS$_EVALUATION_CONTEXT');
  -- Rules for hr.countries
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name    => 'strmadmin.all_countries_dml',
    condition    => ' :dml.get_object_owner() = ''HR'' AND ' ||
                    ' :dml.get_object_name() = ''COUNTRIES''  AND ' ||
                    ' :dml.is_null_tag() = ''Y'' AND ' ||
                    ' :dml.get_source_database_name() = ''DBS1.NET'' ');
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name    => 'strmadmin.all_countries_ddl',
    condition    => ' (:ddl.get_object_owner() = ''HR'' OR ' ||
                    ' :ddl.get_base_table_owner() =         ''HR'') AND ' ||
                    ' :ddl.get_object_name() = ''COUNTRIES'' AND ' ||
                    ' :ddl.is_null_tag() = ''Y'' AND ' ||
                    ' :ddl.get_source_database_name() = ''DBS1.NET'' ');
  -- Rules for hr.locations
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name    => 'strmadmin.all_locations_dml',
    condition    => ' :dml.get_object_owner() = ''HR'' AND ' ||
                    ' :dml.get_object_name() = ''LOCATIONS'' AND ' ||
                    ' :dml.is_null_tag() = ''Y'' AND ' ||
                    ' :dml.get_source_database_name() = ''DBS1.NET'' ');
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name    => 'strmadmin.all_locations_ddl',
    condition    => ' (:ddl.get_object_owner() = ''HR'' OR ' ||
                    ' :ddl.get_base_table_owner() =         ''HR'') AND ' ||
                    ' :ddl.get_object_name() = ''LOCATIONS'' AND ' ||
                    ' :ddl.is_null_tag() = ''Y'' AND ' ||
                    ' :ddl.get_source_database_name() = ''DBS1.NET'' ');
  -- Rules for hr.regions
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name    => 'strmadmin.all_regions_dml',
    condition    => ' :dml.get_object_owner() = ''HR'' AND ' ||
                    ' :dml.get_object_name() = ''REGIONS'' AND ' ||
                    ' :dml.is_null_tag() = ''Y'' AND ' ||
                    ' :dml.get_source_database_name() = ''DBS1.NET'' ');
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name    => 'strmadmin.all_regions_ddl',
    condition    => ' (:ddl.get_object_owner() = ''HR'' OR ' ||
                    ' :ddl.get_base_table_owner() =         ''HR'') AND ' ||
                    ' :ddl.get_object_name() = ''REGIONS'' AND ' ||
                    ' :ddl.is_null_tag() = ''Y'' AND ' ||
                    ' :ddl.get_source_database_name() = ''DBS1.NET'' ');
  -- Add rules to rule set
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_countries_dml',
    rule_set_name  => 'strmadmin.apply_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_countries_ddl',
    rule_set_name  => 'strmadmin.apply_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_locations_dml',
    rule_set_name  => 'strmadmin.apply_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_locations_ddl',
    rule_set_name  => 'strmadmin.apply_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_regions_dml',
    rule_set_name  => 'strmadmin.apply_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_regions_ddl',
    rule_set_name  => 'strmadmin.apply_rules');
  -- Create an apply process that uses the rule set as its positive rule set
  DBMS_APPLY_ADM.CREATE_APPLY(
    queue_name      => 'strmadmin.streams_queue',
    apply_name      => 'apply',
    rule_set_name   => 'strmadmin.apply_rules',
    apply_user      => 'hr',
    apply_captured  => TRUE,
    source_database => 'dbs1.net');
END;
/

/*

手順8: hrユーザーへの適用プロセスのルール・セットに対するEXECUTE権限の付与

前述の手順でhrユーザーを適用ユーザーとして指定したため、hrユーザーには、適用プロセスで使用されるポジティブ・ルール・セットに対するEXECUTE権限が必要です。

*/

BEGIN
  DBMS_RULE_ADM.GRANT_OBJECT_PRIVILEGE(
    privilege   => SYS.DBMS_RULE_ADM.EXECUTE_ON_RULE_SET,
    object_name => 'strmadmin.apply_rules',
    grantee     => 'hr');
END;
/

/*

手順9: dbs3.netでの適用プロセスの起動

エラーが発生した場合に適用プロセスが無効化されないように、disable_on_errorパラメータをnに設定して、dbs3.netで適用プロセスを起動します。

*/

BEGIN
  DBMS_APPLY_ADM.SET_PARAMETER(
    apply_name  => 'apply',
    parameter   => 'disable_on_error',
    value       => 'N');
END;
/

BEGIN
  DBMS_APPLY_ADM.START_APPLY(
    apply_name  => 'apply');
END;
/

/*

手順10: dbs2.netでの伝播の構成

strmadminユーザーとしてdbs2.netに接続します。

*/

CONNECT strmadmin@dbs2.net

/*

dbs2.netのキューからdbs3.netのキューへの伝播を構成およびスケジュールします。dbs2.netの変更はdbs1.netで発生したものであるため、この構成は、有向ネットワークの一例です。

*/

BEGIN
  -- Create the rule set
  DBMS_RULE_ADM.CREATE_RULE_SET(
    rule_set_name       => 'strmadmin.propagation_dbs3_rules',
    evaluation_context  => 'SYS.STREAMS$_EVALUATION_CONTEXT');
  -- Create rules for all modifications to the countries table
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name  => 'strmadmin.all_countries_dml',
    condition  => ' :dml.get_object_owner() = ''HR'' AND ' ||
                  ' :dml.get_object_name() = ''COUNTRIES'' AND ' ||
                  ' :dml.is_null_tag() = ''Y'' AND ' ||
                  ' :dml.get_source_database_name() = ''DBS1.NET'' ');
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name  => 'strmadmin.all_countries_ddl',
    condition  => ' (:ddl.get_object_owner() = ''HR'' OR ' ||
                  ' :ddl.get_base_table_owner() =   ''HR'') AND ' ||
                  ' :ddl.get_object_name() = ''COUNTRIES'' AND ' ||
                  ' :ddl.is_null_tag() = ''Y'' AND ' ||
                  ' :ddl.get_source_database_name() = ''DBS1.NET'' ');
  -- Create rules for all modifications to the locations table
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name   => 'strmadmin.all_locations_dml',
    condition  => ' :dml.get_object_owner() = ''HR'' AND ' ||
                  ' :dml.get_object_name() = ''LOCATIONS'' AND ' ||
                  ' :dml.is_null_tag() = ''Y'' AND ' ||
                  ' :dml.get_source_database_name() = ''DBS1.NET'' ');
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name   => 'strmadmin.all_locations_ddl',
    condition  => ' (:ddl.get_object_owner() = ''HR'' OR ' ||
                  ' :ddl.get_base_table_owner() =   ''HR'') AND ' ||
                  ' :ddl.get_object_name() = ''LOCATIONS'' AND ' ||
                  ' :ddl.is_null_tag() = ''Y'' AND ' ||
                  ' :ddl.get_source_database_name() = ''DBS1.NET'' ');
  -- Create rules for all modifications to the regions table
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name   => 'strmadmin.all_regions_dml',
    condition  => ' :dml.get_object_owner() = ''HR'' AND ' ||
                  ' :dml.get_object_name() = ''REGIONS'' AND ' ||
                  ' :dml.is_null_tag() = ''Y'' AND ' ||
                  ' :dml.get_source_database_name() = ''DBS1.NET'' ');
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name   => 'strmadmin.all_regions_ddl',
    condition  => ' (:ddl.get_object_owner() = ''HR'' OR ' ||
                  ' :ddl.get_base_table_owner() =   ''HR'') AND ' ||
                  ' :ddl.get_object_name() = ''REGIONS'' AND ' ||
                  ' :ddl.is_null_tag() = ''Y'' AND ' ||
                  ' :ddl.get_source_database_name() = ''DBS1.NET'' ');
  -- Add rules to rule set
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_countries_dml',
    rule_set_name  => 'strmadmin.propagation_dbs3_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_countries_ddl',
    rule_set_name  => 'strmadmin.propagation_dbs3_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_locations_dml',
    rule_set_name  => 'strmadmin.propagation_dbs3_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_locations_ddl',
    rule_set_name  => 'strmadmin.propagation_dbs3_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_regions_dml',
    rule_set_name  => 'strmadmin.propagation_dbs3_rules');
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_regions_ddl',
    rule_set_name  => 'strmadmin.propagation_dbs3_rules');
  -- Create a propagation that uses the rule set as its positive rule set
  DBMS_PROPAGATION_ADM.CREATE_PROPAGATION(
    propagation_name    => 'dbs2_to_dbs3',
    source_queue        => 'strmadmin.streams_queue',
    destination_queue   => 'strmadmin.streams_queue',
    destination_dblink  => 'dbs3.net',
    rule_set_name       => 'strmadmin.propagation_dbs3_rules');
END;
/

/*

手順11: dbs2.netでの行LCRのルールベースの変換の作成

hrユーザーとしてdbs2.netに接続します。

*/

CONNECT hr@dbs2.net

/*

dbs1.netjobs表に対するDML文によって発生する行変更をdbs2.netassignments表に対する行変更に変換するルールベースの変換ファンクションを作成します。

次のファンクションを実行すると、jobs表のすべての行LCRがassignments表の行LCRに変換されます。


注意:

assignments表にDDL変更も適用された場合、DDL LCR用に別の変換が必要になります。この変換では、オブジェクト名およびDDLテキストを変更する必要があります。

*/

CREATE OR REPLACE FUNCTION hr.to_assignments_trans_dml(
  p_in_data in ANYDATA)
  RETURN ANYDATA IS out_data SYS.LCR$_ROW_RECORD;
  tc   pls_integer;
BEGIN
  -- Typecast AnyData to LCR$_ROW_RECORD
     tc := p_in_data.GetObject(out_data);
     IF out_data.GET_OBJECT_NAME() = 'JOBS'
     THEN
  -- Transform the in_data into the out_data
     out_data.SET_OBJECT_NAME('ASSIGNMENTS');
     END IF;
  -- Convert to AnyData
     RETURN ANYDATA.ConvertObject(out_data);
END;
/

/*

手順12: dbs2.netでのローカル適用を実行するための適用プロセスの構成

strmadminユーザーとしてdbs2.netに接続します。

*/

CONNECT strmadmin@dbs2.net

/*

ローカルのassignments表に変更を適用するようにdbs2.netを構成します。assignments表がdbs1.netjobs表から変更を受信することに注意してください。この手順では、DBMS_STREAMS_ADMパッケージのSET_RULE_TRANSFORM_FUNCTIONプロシージャを使用せずにルールベースの変換を指定します。かわりに、名前/値ペアをルールのアクション・コンテキストに手動で追加します。名前/値ペアでは、名前にSTREAMS$_TRANSFORM_FUNCTION、値にhr.to_assignments_trans_dmlが指定されます。

*/

DECLARE
  action_ctx_dml       SYS.RE$NV_LIST;
  action_ctx_ddl       SYS.RE$NV_LIST;
  ac_name              VARCHAR2(30) := 'STREAMS$_TRANSFORM_FUNCTION';
BEGIN
  -- Specify the name-value pair in the action context
  action_ctx_dml := SYS.RE$NV_LIST(SYS.RE$NV_ARRAY());
  action_ctx_dml.ADD_PAIR(
    ac_name,
    ANYDATA.CONVERTVARCHAR2('hr.to_assignments_trans_dml'));
  --  Create the rule set strmadmin.apply_rules
  DBMS_RULE_ADM.CREATE_RULE_SET(
    rule_set_name       => 'strmadmin.apply_rules',
    evaluation_context  => 'SYS.STREAMS$_EVALUATION_CONTEXT');
  --  Create a rule that transforms all DML changes to the jobs table into
  --  DML changes for assignments table
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name       => 'strmadmin.all_jobs_dml',
    condition       => ' :dml.get_object_owner() = ''HR'' AND ' ||
                       ' :dml.get_object_name() = ''JOBS'' AND ' ||
                       ' :dml.is_null_tag() = ''Y'' AND ' ||
                       ' :dml.get_source_database_name() = ''DBS1.NET'' ',
    action_context  => action_ctx_dml);
  --  Add the rule to the rule set
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_jobs_dml',
    rule_set_name  => 'strmadmin.apply_rules');
  -- Create an apply process that uses the rule set as its positive rule set
  DBMS_APPLY_ADM.CREATE_APPLY(
    queue_name      => 'strmadmin.streams_queue',
    apply_name      => 'apply_dbs2',
    rule_set_name   => 'strmadmin.apply_rules',
    apply_user      => 'hr',
    apply_captured  => TRUE,
    source_database => 'dbs1.net');
END;
/

/*

手順13: hrユーザーへの適用プロセスのルール・セットに対するEXECUTE権限の付与

前述の手順でhrユーザーを適用ユーザーとして指定したため、hrユーザーには、適用プロセスで使用されるポジティブ・ルール・セットに対するEXECUTE権限が必要です。

*/

BEGIN
  DBMS_RULE_ADM.GRANT_OBJECT_PRIVILEGE(
    privilege   => SYS.DBMS_RULE_ADM.EXECUTE_ON_RULE_SET,
    object_name => 'strmadmin.apply_rules',
    grantee     => 'hr');
END;
/

/*

手順14: dbs2.netでのローカル適用を実行するための適用プロセスの起動

エラーが発生した場合に適用プロセスが無効化されないように、disable_on_errorパラメータをnに設定して、dbs2.netでローカル適用を実行するために適用プロセスを起動します。

*/

BEGIN
  DBMS_APPLY_ADM.SET_PARAMETER(
    apply_name  => 'apply_dbs2',
    parameter   => 'disable_on_error',
    value       => 'N');
END;
/

BEGIN
  DBMS_APPLY_ADM.START_APPLY(
    apply_name  => 'apply_dbs2');
END;
/

/*

手順15: dbs4.netでの適用を実行するためのdbs2.netでの適用プロセスの構成

dbs4.net(Sybaseデータベース)のjobs表にDML変更を適用するようにdbs2.netを構成します。この変更はdbs1.netで発生したことに注意してください。

*/

BEGIN
  -- Create the rule set
  DBMS_RULE_ADM.CREATE_RULE_SET(
    rule_set_name      => 'strmadmin.apply_dbs4_rules',
    evaluation_context => 'SYS.STREAMS$_EVALUATION_CONTEXT');
  -- Create rule strmadmin.all_jobs_remote for all modifications
  -- to the jobs table
  DBMS_RULE_ADM.CREATE_RULE(
    rule_name    => 'strmadmin.all_jobs_remote',
    condition    => ' :dml.get_object_owner() = ''HR'' AND ' ||
                    ' :dml.get_object_name() = ''JOBS'' AND ' ||
                    ' :dml.is_null_tag() = ''Y'' AND ' ||
                    ' :dml.get_source_database_name() = ''DBS1.NET'' ');
  -- Add the rule to the rule set
  DBMS_RULE_ADM.ADD_RULE(
    rule_name      => 'strmadmin.all_jobs_remote',
    rule_set_name  => 'strmadmin.apply_dbs4_rules');
  -- Create an apply process that uses the rule set as its positive rule set
  DBMS_APPLY_ADM.CREATE_APPLY(
    queue_name          => 'strmadmin.streams_queue',
    apply_name          => 'apply_dbs4',
    rule_set_name       => 'strmadmin.apply_dbs4_rules',
    apply_database_link => 'dbs4.net',
    apply_captured      => TRUE,
    source_database     => 'dbs1.net');
END;
/

/*

手順16: dbs4.netでの適用を実行するためのdbs2.netでの適用プロセスの起動

エラーが発生した場合に適用プロセスが無効化されないように、disable_on_errorパラメータをnに設定して、データベース・リンクdbs4.netを使用してSybaseのリモート適用を開始します。

*/

BEGIN
  DBMS_APPLY_ADM.SET_PARAMETER(
    apply_name  => 'apply_dbs4',
    parameter   => 'disable_on_error',
    value       => 'N');
END;
/

BEGIN
  DBMS_APPLY_ADM.START_APPLY(
    apply_name  => 'apply_dbs4');
END;
/

/*

手順17: dbs1.netでの取得プロセスの起動

strmadminユーザーとしてdbs1.netに接続します。

*/

CONNECT strmadmin@dbs1.net

/*

dbs1.netで取得プロセスを起動します。

*/

BEGIN
  DBMS_CAPTURE_ADM.START_CAPTURE(
    capture_name  => 'capture');
END;
/

/*

手順18: スプール結果のチェック

streams_share_schema2.outスプール・ファイルをチェックして、このスクリプトの完了後にすべてのアクションが正常に終了していることを確認します。

*/

SET ECHO OFF
SPOOL OFF

/*

ここで、dbs1.netの特定の表に対してDML変更およびDDL変更を行い、この環境内のOracle Streamsプロセスおよび伝播について構成したルールに基づいて、環境内の他のデータベースにこれらの変更がレプリケートされていることを確認できます。


参照:

この環境内でレプリケートされる変更の例については、「hrスキーマ内の表に対するDML変更およびDDL変更」を参照してください。

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

hrスキーマ内の表に対するDML変更およびDDL変更

「1つのデータベースからのデータを共有するスクリプトの例」で説明したいずれかの例を完了した後に、dbs1.netデータベースのhrスキーマ内の表に対してDML変更およびDDL変更を行うことができます。これらの変更は、Oracle Streamsプロセスおよび伝播について構成したルールに基づいて、環境内の他のデータベースにレプリケートされます。他のデータベースをチェックして、変更がレプリケートされていることを確認できます。

たとえば、次の手順を実行して、dbs1.nethr.jobsおよびhr.locations表に対してDML変更を行います。また、dbs1.nethr.locations表に対してDDL変更を行うこともできます。

これらの変更を行った後に、dbs2.nethr.assignments表を問い合せて、dbs1.netのこの表に対して行ったDML変更がレプリケートされていることを確認できます。dbs2.netの適用プロセスに構成したルールベースの変換によって、hr.jobs表に対するDML変更がhr.assignments表に対するDML変更に変換されていることに注意してください。dbs3.nethr.locations表を問い合せて、dbs1.netのこの表に対して行ったDML変更およびDDL変更がレプリケートされていることも確認できます。


手順1: hrスキーマ内の表に対するDML変更およびDDL変更

次の変更を行います。

CONNECT hr@dbs1.net
Enter password: password

UPDATE hr.jobs SET max_salary=10000 WHERE job_id='MK_REP';
COMMIT;

INSERT INTO hr.locations VALUES(
  3300, '521 Ralston Avenue', '94002', 'Belmont', 'CA', 'US');
COMMIT;

ALTER TABLE hr.locations RENAME COLUMN state_province TO state_or_province;

手順2: dbs2.netでのhr.assignments表の問合せ

前述の手順で行った変更が取得、伝播および適用されるまで待ってから、次の問合せを実行して、dbs1.nethr.jobs表に対して行ったUPDATE変更がdbs2.nethr.assignments表に適用されていることを確認します。

CONNECT hr@dbs2.net
Enter password: password

SELECT max_salary FROM hr.assignments WHERE job_id='MK_REP';

max_salaryの値が10000と表示されるはずです。

手順3: dbs3.netでのhr.locations表の問合せおよび定義の表示

次の問合せを実行して、dbs1.nethr.locations表に対して行ったINSERT変更がdbs3.netで適用されていることを確認します。

CONNECT hr@dbs3.net
Enter password: password

SELECT * FROM hr.locations WHERE location_id=3300;

前述の手順でdbs1.nethr.locations表に挿入した行が表示されるはずです。

次に、hr.locations表の定義を表示して、ALTER TABLE変更が正常に伝播および適用されていることを確認します。

DESC hr.locations

表の5列目がstate_or_provinceであるはずです。

既存のOracle Streamsレプリケーション環境へのオブジェクトの追加

この例では、レプリケート・オブジェクトを既存のデータベースに追加して、前項で構成したOracle Streams環境を拡張します。この例を実行するには、前述の例のいずれか一方のタスクを完了している必要があります。

この例では、dbs3.netデータベースのhrスキーマに次の表を追加します。

この例を完了すると、Oracle Streamsでは、これらの表に対する変更が次の一連のアクションで処理されます。

  1. 取得プロセスがdbs1.netで変更を取得してエンキューします。

  2. 伝播によって、dbs1.netのキューからdbs2.netのキューに変更が伝播されます。

  3. 伝播によって、dbs2.netのキューからdbs3.netのキューに変更が伝播されます。

  4. dbs3.netの適用プロセスが、変更をdbs3.netで適用します。

この例を完了すると、countries表、locations表およびregions表は前項でdbs3.netでインスタンス化されているため、dbs3.netデータベースのhrスキーマにはオリジナルの表がすべて含まれることになります。

図20-2に、表が追加された環境の概要を示します。

図20-2 環境内のdbs3.netへのオブジェクトの追加

図20-2の説明が続きます。
図20-2「環境内のdbs3.netへのオブジェクトの追加」の説明

次の手順を実行して、前述の表をdbs3.netデータベースにレプリケートします。

  1. 出力およびスプール結果の表示

  2. dbs3.netでの適用プロセスの停止

  3. dbs3.netでの追加する表に対する適用プロセスの構成

  4. dbs2.netでの追加する表に対する表の伝播ルールの指定

  5. dbs1.netでの追加する4つの表のインスタンス化のための準備

  6. dbs3.netでのdbs1.netの表のインスタンス化

  7. dbs3.netでの適用プロセスの起動

  8. スプール結果のチェック


注意:

このマニュアルをオンラインで参照している場合、この注意の後にある「BEGINNING OF SCRIPT」の行から次の「END OF SCRIPT」の行までのテキストをテキスト・エディタにコピーし、テキストを編集してご使用の環境用のスクリプトを作成できます。環境内のすべてのデータベースに接続可能なコンピュータで、SQL*Plusを使用してスクリプトを実行します。

/************************* BEGINNING OF SCRIPT ******************************

手順1: 出力およびスプール結果の表示

SET ECHO ONを実行し、スクリプトのスプール・ファイルを指定します。このスクリプトの実行後に、スプール・ファイルにエラーがないかをチェックします。

*/

SET ECHO ON
SPOOL streams_addobjs.out

/*

手順2: dbs3.netでの適用プロセスの停止

dbs3.netへのオブジェクトの追加が完了するまで、追加するオブジェクトの適用プロセスによって、これらのオブジェクトの変更が適用されないようにする必要があります。そのために、ソース・データベースで取得プロセスを停止できます。または、dbs2.netからdbs3.netへの変更の伝播を停止できます。さらに、dbs3.netで適用プロセスを停止することもできます。この例では、dbs3.netで適用プロセスを停止します。

strmadminユーザーとしてdbs3.netに接続します。

*/

CONNECT strmadmin@dbs3.net

/*

dbs3.netで適用プロセスを停止します。

*/

BEGIN
  DBMS_APPLY_ADM.STOP_APPLY(
    apply_name  => 'apply');
END;
/

/*

手順3: dbs3.netでの追加する表に対する適用プロセスの構成

追加する表に変更を適用するように、dbs3.netで適用プロセスを構成します。

*/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_RULES(
    table_name      => 'hr.departments',
    streams_type    => 'apply',
    streams_name    => 'apply',
    queue_name      => 'strmadmin.streams_queue',
    include_dml     => TRUE,
    include_ddl     => TRUE,
    source_database => 'dbs1.net',
    inclusion_rule  => TRUE);
END;
/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_RULES(
    table_name      => 'hr.employees',
    streams_type    => 'apply',
    streams_name    => 'apply',
    queue_name      => 'strmadmin.streams_queue',
    include_dml     => TRUE,
    include_ddl     => TRUE,
    source_database => 'dbs1.net',
    inclusion_rule  => TRUE);
END;
/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_RULES(
    table_name      => 'hr.job_history',
    streams_type    => 'apply',
    streams_name    => 'apply',
    queue_name      => 'strmadmin.streams_queue',
    include_dml     => TRUE,
    include_ddl     => TRUE,
    source_database => 'dbs1.net',
    inclusion_rule  => TRUE);
END;
/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_RULES(
    table_name      => 'hr.jobs',
    streams_type    => 'apply',
    streams_name    => 'apply',
    queue_name      => 'strmadmin.streams_queue',
    include_dml     => TRUE,
    include_ddl     => TRUE,
    source_database => 'dbs1.net',
    inclusion_rule  => TRUE);
END;
/

/*

手順4: dbs2.netでの追加する表に対する表の伝播ルールの指定

strmadminユーザーとしてdbs2.netに接続します。

*/

CONNECT strmadmin@dbs2.net

/*

dbs2.netのキューからdbs3.netのキューへの伝播のルールに表を追加します。

*/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_PROPAGATION_RULES(
    table_name               => 'hr.departments',
    streams_name             => 'dbs2_to_dbs3',
    source_queue_name        => 'strmadmin.streams_queue',
    destination_queue_name   => 'strmadmin.streams_queue@dbs3.net',
    include_dml              => TRUE,
    include_ddl              => TRUE,
    source_database          => 'dbs1.net',
    inclusion_rule           => TRUE);
END;
/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_PROPAGATION_RULES(
    table_name              => 'hr.employees',
    streams_name            => 'dbs2_to_dbs3',
    source_queue_name       => 'strmadmin.streams_queue',
    destination_queue_name  => 'strmadmin.streams_queue@dbs3.net',
    include_dml             => TRUE,
    include_ddl             => TRUE,
    source_database         => 'dbs1.net',
    inclusion_rule          => TRUE);
END;
/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_PROPAGATION_RULES(
    table_name              => 'hr.job_history',
    streams_name            => 'dbs2_to_dbs3',
    source_queue_name       => 'strmadmin.streams_queue',
    destination_queue_name  => 'strmadmin.streams_queue@dbs3.net',
    include_dml             => TRUE,
    include_ddl             => TRUE,
    source_database         => 'dbs1.net',
    inclusion_rule          => TRUE);
END;
/

BEGIN
  DBMS_STREAMS_ADM.ADD_TABLE_PROPAGATION_RULES(
    table_name              => 'hr.jobs',
    streams_name            => 'dbs2_to_dbs3',
    source_queue_name       => 'strmadmin.streams_queue',
    destination_queue_name  => 'strmadmin.streams_queue@dbs3.net',
    include_dml             => TRUE,
    include_ddl             => TRUE,
    source_database         => 'dbs1.net',
    inclusion_rule          => TRUE);
END;
/

/*

手順5: dbs1.netでの追加する4つの表のインスタンス化のための準備

strmadminユーザーとしてdbs1.netに接続します。

*/

CONNECT strmadmin@dbs1.net

/*

表をインスタンス化のために準備します。これらの表は、dbs3.netでインスタンス化されます。この手順では、インスタンス化のために表の最小SCNにマークが付けられます。最小SCNより後のSCNは、インスタンス化に使用できます。この準備は、dbs3.netで関連する伝播および適用プロセスのOracle Streamsデータ・ディクショナリにこれらの表の情報を含めるためにも必要です。


注意:

この手順でPREPARE_TABLE_INSTANTIATIONプロシージャを実行する際、supplemental_loggingパラメータは指定しません。したがって、このパラメータにはデフォルト値(keys)が使用されます。サプリメンタル・ロギングは、これらの表のすべての主キー列、一意キー列、ビットマップ索引列および外部キー列について、手順3ですでに有効化されています。

*/

BEGIN
  DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(
    table_name  => 'hr.departments');
END;
/

BEGIN
  DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(
    table_name  => 'hr.employees');
END;
/

BEGIN
  DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(
    table_name  => 'hr.job_history');
END;
/

BEGIN
  DBMS_CAPTURE_ADM.PREPARE_TABLE_INSTANTIATION(
    table_name  => 'hr.jobs');
END;
/

/*

手順6: dbs3.netでのdbs1.netの表のインスタンス化

この例では、データ・ポンプを使用して次の表のネットワーク・インポートを実行します。

ネットワーク・インポートとは、エクスポート・ダンプ・ファイルを使用せずに、データ・ポンプでdbs1.netからこれらの表をインポートすることを意味します。


参照:

インポートを実行する方法の詳細は、『Oracle Databaseユーティリティ』を参照してください。

strmadminユーザーとしてdbs3.netに接続します。

*/

CONNECT strmadmin@dbs3.net

/*

この例では、DBMS_DATAPUMPパッケージを使用して表のインポートを実行します。簡略化するために、どのAPIコールからの例外も捕捉されません。ただし、例外ハンドラを定義し、障害発生時にGET_STATUSをコールしてエラーの詳細情報を取得することをお薦めします。インポートを監視する場合は、インポート・データベースでDBA_DATAPUMP_JOBSデータ・ディクショナリ・ビューを問い合せます。

*/

SET SERVEROUTPUT ON
DECLARE
  h1        NUMBER;         -- Data Pump job handle
  sscn      NUMBER;         -- Variable to hold current source SCN
  job_state VARCHAR2(30);   -- To keep track of job state
  js        ku$_JobStatus;  -- The job status from GET_STATUS
  sts       ku$_Status;     -- The status object returned by GET_STATUS
  job_not_exist    exception;
  pragma exception_init(job_not_exist, -31626);
BEGIN
-- Create a (user-named) Data Pump job to do a table-level import.
  h1 := DBMS_DATAPUMP.OPEN(
          operation   => 'IMPORT',
          job_mode    => 'TABLE',
          remote_link => 'DBS1.NET',
          job_name    => 'dp_sing3');
-- A metadata filter is used to specify the schema that owns the tables
-- that will be imported.
  DBMS_DATAPUMP.METADATA_FILTER(
    handle    => h1,
    name      => 'SCHEMA_EXPR',
    value     => '=''HR''');
-- A metadata filter is used to specify the tables that will be imported.
  DBMS_DATAPUMP.METADATA_FILTER(
    handle    => h1,
    name      => 'NAME_EXPR',
    value     => 'IN(''DEPARTMENTS'', ''EMPLOYEES'',
                     ''JOB_HISTORY'', ''JOBS'')');
-- Get the current SCN of the source database, and set the FLASHBACK_SCN
-- parameter to this value to ensure consistency between all of the
-- objects included in the import.
  sscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER@dbs1.net();
  DBMS_DATAPUMP.SET_PARAMETER(
    handle => h1,
    name   => 'FLASHBACK_SCN',
    value  => sscn);
-- Start the job.
  DBMS_DATAPUMP.START_JOB(h1);
-- The import job should be running. In the following loop, the job
-- is monitored until it completes.
  job_state := 'UNDEFINED';
  BEGIN
    WHILE (job_state != 'COMPLETED') AND (job_state != 'STOPPED') LOOP
      sts:=DBMS_DATAPUMP.GET_STATUS(
             handle  => h1,
             mask    => DBMS_DATAPUMP.KU$_STATUS_JOB_ERROR +
                        DBMS_DATAPUMP.KU$_STATUS_JOB_STATUS +
                        DBMS_DATAPUMP.KU$_STATUS_WIP,
             timeout => -1);
      js := sts.job_status;
      DBMS_LOCK.SLEEP(10);
      job_state := js.state;
    END LOOP;
  -- Gets an exception when job no longer exists
    EXCEPTION WHEN job_not_exist THEN
      DBMS_OUTPUT.PUT_LINE('Data Pump job has completed');
      DBMS_OUTPUT.PUT_LINE('Instantiation SCN: ' ||sscn);
  END;
END;
/

/*

手順7: dbs3.netでの適用プロセスの起動

dbs3.netで適用プロセスを起動します。これは、手順2で停止した適用プロセスです。

strmadminユーザーとしてdbs3.netに接続します。

*/

CONNECT strmadmin@dbs3.net

/*

dbs3.netで適用プロセスを起動します。

*/

BEGIN
  DBMS_APPLY_ADM.START_APPLY(
    apply_name  => 'apply');
END;
/

/*

手順8: スプール結果のチェック

streams_addobjs.outスプール・ファイルをチェックして、このスクリプトの完了後にすべてのアクションが正常に終了していることを確認します。

*/

SET ECHO OFF
SPOOL OFF

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

hr.employees表に対するDML変更

「既存のOracle Streamsレプリケーション環境へのオブジェクトの追加」で説明した例を完了した後に、dbs1.netデータベースのhrスキーマ内の表に対してDML変更およびDDL変更を行うことができます。これらの変更は、dbs3.netにレプリケートされます。dbs3.netでこれらの表をチェックして、変更がレプリケートされていることを確認できます。

たとえば、次の手順を実行して、dbs1.nethr.employees表に対してDML変更を行います。次に、dbs3.nethr.employees表を問い合せて、変更がレプリケートされていることを確認します。


手順1: hr.employees表に対するDML変更

次の変更を行います。

CONNECT hr@dbs1.net
Enter password: password

UPDATE hr.employees SET job_id='ST_MAN' WHERE employee_id=143;
COMMIT;

手順2: dbs3.netでのhr.employees表の問合せ

前述の手順で行った変更が取得、伝播および適用されるまで待ってから、次の問合せを実行して、dbs1.nethr.employees表に対して行ったUPDATE変更がdbs3.nethr.employees表に適用されていることを確認します。

CONNECT hr@dbs3.net
Enter password: password

SELECT job_id FROM hr.employees WHERE employee_id=143;

job_idの値がST_MANと表示されるはずです。

既存のOracle Streamsレプリケーション環境へのデータベースの追加

この例では、既存の構成にデータベースを追加して、前項で構成したOracle Streams環境を拡張します。この例では、dbs2.netのキューからhrスキーマ全体に対する変更を受信するために、既存のOracle Database dbs5.netを追加します。

図20-3に、データベースが追加された環境の概要を示します。

図20-3 環境へのOracle Database dbs5.netの追加

図20-3の説明が続きます。
図20-3「環境へのOracle Database dbs5.netの追加」の説明

この例を完了するには、次の前提条件を満たしている必要があります。

次の手順を実行して、dbs5.netをOracle Streams環境に追加します。

  1. 出力およびスプール結果の表示

  2. dbs5.netでのhrスキーマ内のすべての表の削除

  3. dbs5.netでのユーザーの設定

  4. dbs5.netでのANYDATAキューの作成

  5. dbs5.netからdbs1.netへのデータベース・リンクの作成

  6. dbs5.netでの適用プロセスの構成

  7. dbs5.netでの適用プロセスの適用ユーザーとしてのhrの指定

  8. hrユーザーへの適用プロセスのルール・セットに対するEXECUTE権限の付与

  9. dbs2.netとdbs5.netの間のデータベース・リンクの作成

  10. dbs2.netとdbs5.netの間の伝播の構成

  11. dbs1.netでのhrスキーマのインスタンス化のための準備

  12. dbs5.netでのdbs1.netの表のインスタンス化

  13. dbs5.netでの適用プロセスの起動

  14. スプール結果のチェック


注意:

このマニュアルをオンラインで参照している場合、この注意の後にある「BEGINNING OF SCRIPT」の行から次の「END OF SCRIPT」の行までのテキストをテキスト・エディタにコピーし、テキストを編集してご使用の環境用のスクリプトを作成できます。環境内のすべてのデータベースに接続可能なコンピュータで、SQL*Plusを使用してスクリプトを実行します。

/************************* BEGINNING OF SCRIPT ******************************

手順1: 出力およびスプール結果の表示

SET ECHO ONを実行し、スクリプトのスプール・ファイルを指定します。このスクリプトの実行後に、スプール・ファイルにエラーがないかをチェックします。

*/

SET ECHO ON
SPOOL streams_adddb.out

/*

手順2: dbs5.netでのhrスキーマ内のすべての表の削除

この例では、データ・ポンプを使用してdbs1.netからdbs5.netに表をインポートすることによって、hrスキーマ内の表をインスタンス化する方法について説明します。この例でのインスタンス化を正常に実行するために、dbs5.netでこれらの表を削除する必要があります。

hrとしてdbs5.netに接続します。

*/

CONNECT hr@dbs5.net

/*

dbs5.netデータベースのhrスキーマ内のすべての表を削除します。


注意:

この手順を実行してhrスキーマ内のすべての表を削除した場合、この例の残りの項の手順を実行して、dbs5.nethrスキーマを再インスタンス化する必要があります。hrスキーマがOracle Databaseに存在しない場合、Oracleマニュアル・セットの一部の例が失敗する可能性があります。

*/

DROP TABLE hr.countries CASCADE CONSTRAINTS;
DROP TABLE hr.departments CASCADE CONSTRAINTS;
DROP TABLE hr.employees CASCADE CONSTRAINTS;
DROP TABLE hr.job_history CASCADE CONSTRAINTS;
DROP TABLE hr.jobs CASCADE CONSTRAINTS;
DROP TABLE hr.locations CASCADE CONSTRAINTS;
DROP TABLE hr.regions CASCADE CONSTRAINTS;

/*

手順3: dbs5.netでのユーザーの設定

SYSTEMユーザーとしてdbs5.netに接続します。

*/

CONNECT system@dbs5.net

/*

Oracle Streams管理者strmadminを作成し、このユーザーに必要な権限を付与します。これらの権限によって、ユーザーは、キューの管理、Oracle Streamsに関連するパッケージのサブプログラムの実行、ルール・セットおよびルールの作成、データ・ディクショナリ・ビューおよびキュー表の問合せによるOracle Streams環境の監視を行うことができるようになります。このユーザーには、異なる名前を指定できます。


注意:

ACCEPTコマンドを、スクリプト内の1行に指定する必要があります。


参照:

Oracle Streams管理者を構成する方法の詳細は、『Oracle Streams概要および管理』を参照してください。

*/

ACCEPT password PROMPT 'Enter password for user: ' HIDE

GRANT DBA TO strmadmin IDENTIFIED BY &password;

ACCEPT streams_tbs PROMPT 'Enter Oracle Streams administrator tablespace on dbs5.net: ' HIDE

ALTER USER strmadmin DEFAULT TABLESPACE &streams_tbs
                     QUOTA UNLIMITED ON &streams_tbs;

/*

手順4: dbs5.netでのANYDATAキューの作成

Oracle Streams管理者として追加するデータベースに接続します。この例では、dbs5.netに接続します。

*/

CONNECT strmadmin@dbs5.net

/*

SET_UP_QUEUEプロシージャを実行して、dbs5.netstreams_queueというキューを作成します。このキューはANYDATAキューとして動作し、このデータベースに適用される変更を保持します。

SET_UP_QUEUEプロシージャを実行すると、次のアクションが実行されます。

*/

EXEC  DBMS_STREAMS_ADM.SET_UP_QUEUE();

/*

手順5: dbs5.netからdbs1.netへのデータベース・リンクの作成

dbs5.netからdbs1.netへのデータベース・リンクを作成します。このデータベース・リンクは、この例の後半で、手順2で削除したデータベース・オブジェクトをインスタンス化するために使用します。この例では、DBMS_DATAPUMPパッケージを使用して、dbs1.netデータベースから直接これらのデータベース・オブジェクトのネットワーク・インポートを実行します。この例ではネットワーク・インポートを実行するため、ダンプ・ファイルは不要です。

または、ソース・データベースdbs1.netでエクスポートを実行し、エクスポート・ダンプ・ファイルを接続先データベースdbs5.netに転送して、接続先データベースでエクスポート・ダンプ・ファイルをインポートすることもできます。この場合、この手順で作成するデータベース・リンクは不要です。

*/

CREATE DATABASE LINK dbs1.net CONNECT TO strmadmin IDENTIFIED BY &password
   USING 'dbs1.net';

/*

手順6: dbs5.netでの適用プロセスの構成

dbs5.netにOracle Streams管理者として接続したままで、hrスキーマに変更を適用するように適用プロセスを構成します。

*/

BEGIN
  DBMS_STREAMS_ADM.ADD_SCHEMA_RULES(
    schema_name     => 'hr',
    streams_type    => 'apply',
    streams_name    => 'apply',
    queue_name      => 'strmadmin.streams_queue',
    include_dml     => TRUE,
    include_ddl     => TRUE,
    source_database => 'dbs1.net',
    inclusion_rule  => TRUE);
END;
/

/*

手順7: dbs5.netでの適用プロセスの適用ユーザーとしてのhrの指定

この例では、hrユーザーが、このデータベースで適用プロセスによって変更が適用されるすべてのデータベース・オブジェクトを所有します。したがって、hrはこれらのデータベース・オブジェクトを変更するために必要な権限をすでに持っており、hrを適用ユーザーにすることが有効です。

前述の手順で適用プロセスを作成したときに、適用プロセスを作成したプロシージャをOracle Streams管理者strmadminが実行したため、デフォルトでは、strmadminが適用ユーザーとして指定されています。hrを適用ユーザーとして指定するかわりに、strmadminを適用ユーザーのままにしておくこともできますが、この場合、変更が適用されるすべてのデータベース・オブジェクトに対する権限、および適用プロセスで使用されるすべてのユーザー・プロシージャを実行する権限をstrmadminに付与する必要があります。適用プロセスが複数のスキーマ内のデータベース・オブジェクトに変更を適用する環境では、Oracle Streams管理者を適用ユーザーとして使用する方が有効な場合があります。


参照:

Oracle Streams管理者を構成する方法の詳細は、『Oracle Streams概要および管理』を参照してください。

*/

BEGIN
  DBMS_APPLY_ADM.ALTER_APPLY(
    apply_name => 'apply',
    apply_user => 'hr');
END;
/

/*

手順8: hrユーザーへの適用プロセスのルール・セットに対するEXECUTE権限の付与

前述の手順でhrユーザーを適用ユーザーとして指定したため、hrユーザーには、適用プロセスで使用されるポジティブ・ルール・セットに対するEXECUTE権限が必要です。

*/

DECLARE
   rs_name  VARCHAR2(64);   -- Variable to hold rule set name
BEGIN
  SELECT RULE_SET_OWNER||'.'||RULE_SET_NAME
    INTO rs_name
    FROM DBA_APPLY
    WHERE APPLY_NAME='APPLY';
  DBMS_RULE_ADM.GRANT_OBJECT_PRIVILEGE(
    privilege   => SYS.DBMS_RULE_ADM.EXECUTE_ON_RULE_SET,
    object_name => rs_name,
    grantee     => 'hr');
END;
/

/*

手順9: dbs2.netとdbs5.netの間のデータベース・リンクの作成

strmadminユーザーとしてdbs2.netに接続します。

*/

CONNECT strmadmin@dbs2.net

/*

変更が伝播されるデータベースへのデータベース・リンクを作成します。この例では、データベースdbs2.netdbs5.netに変更を伝播します。

*/

CREATE DATABASE LINK dbs5.net CONNECT TO strmadmin IDENTIFIED BY &password
   USING 'dbs5.net';

/*

手順10: dbs2.netとdbs5.netの間の伝播の構成

dbs2.netにOracle Streams管理者として接続したままで、dbs2.netのキューからdbs5.netのキューへの伝播を構成およびスケジュールします。hrスキーマに対する変更はdbs1.netで発生したことに注意してください。

*/

BEGIN
  DBMS_STREAMS_ADM.ADD_SCHEMA_PROPAGATION_RULES(
    schema_name             => 'hr',
    streams_name            => 'dbs2_to_dbs5',
    source_queue_name       => 'strmadmin.streams_queue',
    destination_queue_name  => 'strmadmin.streams_queue@dbs5.net',
    include_dml             => TRUE,
    include_ddl             => TRUE,
    source_database         => 'dbs1.net',
    inclusion_rule          => TRUE,
    queue_to_queue          => TRUE);
END;
/

/*

手順11: dbs1.netでのhrスキーマのインスタンス化のための準備

strmadminユーザーとしてdbs1.netに接続します。

*/

CONNECT strmadmin@dbs1.net

/*

hrスキーマをインスタンス化のために準備します。このスキーマ内の表は、dbs5.netでインスタンス化されます。この準備は、dbs5.netで関連する伝播および適用プロセスのOracle Streamsデータ・ディクショナリに、hrスキーマおよびそのスキーマ内のオブジェクトの情報を含めるために必要です。

*/

BEGIN
  DBMS_CAPTURE_ADM.PREPARE_SCHEMA_INSTANTIATION(
    schema_name          => 'hr',
    supplemental_logging => 'keys');
END;
/

/*

手順12: dbs5.netでのdbs1.netの表のインスタンス化

この例では、データ・ポンプを使用して次の表のネットワーク・インポートを実行します。

ネットワーク・インポートとは、エクスポート・ダンプ・ファイルを使用せずに、データ・ポンプでdbs1.netからこれらの表をインポートすることを意味します。


参照:

インポートを実行する方法の詳細は、『Oracle Databaseユーティリティ』を参照してください。

strmadminユーザーとしてdbs5.netに接続します。

*/

CONNECT strmadmin@dbs5.net

/*

この例では、DBMS_DATAPUMPパッケージを使用して表のインポートを実行します。簡略化するために、どのAPIコールからの例外も捕捉されません。ただし、例外ハンドラを定義し、障害発生時にGET_STATUSをコールしてエラーの詳細情報を取得することをお薦めします。インポートを監視する場合は、インポート・データベースでDBA_DATAPUMP_JOBSデータ・ディクショナリ・ビューを問い合せます。

*/

SET SERVEROUTPUT ON
DECLARE
  h1        NUMBER;         -- Data Pump job handle
  sscn      NUMBER;         -- Variable to hold current source SCN
  job_state VARCHAR2(30);   -- To keep track of job state
  js        ku$_JobStatus;  -- The job status from GET_STATUS
  sts       ku$_Status;     -- The status object returned by GET_STATUS
  job_not_exist    exception;
  pragma exception_init(job_not_exist, -31626);
BEGIN
-- Create a (user-named) Data Pump job to do a table-level import.
  h1 := DBMS_DATAPUMP.OPEN(
          operation   => 'IMPORT',
          job_mode    => 'TABLE',
          remote_link => 'DBS1.NET',
          job_name    => 'dp_sing4');
-- A metadata filter is used to specify the schema that owns the tables
-- that will be imported.
  DBMS_DATAPUMP.METADATA_FILTER(
    handle    => h1,
    name      => 'SCHEMA_EXPR',
    value     => '=''HR''');
-- Get the current SCN of the source database, and set the FLASHBACK_SCN
-- parameter to this value to ensure consistency between all of the
-- objects included in the import.
  sscn := DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER@dbs1.net();
  DBMS_DATAPUMP.SET_PARAMETER(
    handle => h1,
    name   => 'FLASHBACK_SCN',
    value  => sscn);
-- Start the job.
  DBMS_DATAPUMP.START_JOB(h1);
-- The import job should be running. In the following loop, the job
-- is monitored until it completes.
  job_state := 'UNDEFINED';
  BEGIN
    WHILE (job_state != 'COMPLETED') AND (job_state != 'STOPPED') LOOP
      sts:=DBMS_DATAPUMP.GET_STATUS(
             handle  => h1,
             mask    => DBMS_DATAPUMP.KU$_STATUS_JOB_ERROR +
                        DBMS_DATAPUMP.KU$_STATUS_JOB_STATUS +
                        DBMS_DATAPUMP.KU$_STATUS_WIP,
             timeout => -1);
      js := sts.job_status;
      DBMS_LOCK.SLEEP(10);
      job_state := js.state;
    END LOOP;
  -- Gets an exception when job no longer exists
    EXCEPTION WHEN job_not_exist THEN
      DBMS_OUTPUT.PUT_LINE('Data Pump job has completed');
      DBMS_OUTPUT.PUT_LINE('Instantiation SCN: ' ||sscn);
  END;
END;
/

/*

手順13: dbs5.netでの適用プロセスの起動

Oracle Streams管理者としてdbs5.netに接続します。

*/

CONNECT strmadmin@dbs5.net

/*

エラーが発生した場合に適用プロセスが無効化されないように、disable_on_errorパラメータをnに設定して、dbs5.netで適用プロセスを起動します。

*/

BEGIN
  DBMS_APPLY_ADM.SET_PARAMETER(
    apply_name  => 'apply',
    parameter   => 'disable_on_error',
    value       => 'N');
END;
/

BEGIN
  DBMS_APPLY_ADM.START_APPLY(
    apply_name  => 'apply');
END;
/

/*

手順14: スプール結果のチェック

streams_adddb.outスプール・ファイルをチェックして、このスクリプトの完了後にすべてのアクションが正常に終了していることを確認します。

*/

SET ECHO OFF
SPOOL OFF

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

hr.departments表に対するDML変更

「既存のOracle Streamsレプリケーション環境へのデータベースの追加」で説明した例を完了した後に、dbs1.netデータベースのhrスキーマ内の表に対してDML変更およびDDL変更を行うことができます。これらの変更は、dbs5.netにレプリケートされます。dbs5.netでこれらの表をチェックして、変更がレプリケートされていることを確認できます。

たとえば、次の手順を実行して、dbs1.nethr.departments表に対してDML変更を行います。次に、dbs5.nethr.departments表を問い合せて、変更がレプリケートされていることを確認します。


手順1: hr.departments表に対するDML変更

次の変更を行います。

CONNECT hr@dbs1.net
Enter password: password

UPDATE hr.departments SET location_id=2400 WHERE department_id=270;
COMMIT;

手順2: dbs5.netでのhr.departments表の問合せ

前述の手順で行った変更が取得、伝播および適用されるまで待ってから、次の問合せを実行して、dbs1.nethr.departments表に対して行ったUPDATE変更がdbs5.nethr.departments表に適用されていることを確認します。

CONNECT hr@dbs5.net
Enter password: password

SELECT location_id FROM hr.departments WHERE department_id=270;

location_idの値が2400と表示されるはずです。