この章では、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に示すように、dbs1.netのhrスキーマには次の表が含まれています。
countries
departments
employees
job_history
jobs
locations
regions
この例では有向ネットワークを使用しています。これは、ソース・データベースで取得された変更が、1つ以上の中間データベースを介して他のデータベースに伝播されることを意味します。ここでは、dbs1.netデータベースから中間データベースdbs2.netを介して、dbs3.netデータベースに変更が伝播します。この構成は、有向ネットワークでのキューによる転送の一例です。また、dbs1.netデータベースからdbs2.netデータベースに変更が伝播され、そこで変更がOracle Database Gatewayを介してdbs4.netデータベースに直接適用されます。
この環境内の一部のデータベースには、特定の表がありません。データベースが表の中間データベースではなく、その表が含まれていない場合、そのデータベースには表に対する変更を伝播する必要はありません。たとえば、departments、employees、job_historyおよびjobsの各表は、dbs3.netには存在しません。したがって、これらの表に対する変更はdbs2.netからdbs3.netには伝播しません。
この例では、Oracle Streamsを使用して次の一連のアクションが実行されます。
取得プロセスは、dbs1.netデータベースでhrスキーマ内のすべての表に対するDML変更とDDL変更を取得し、その変更をエンキューします。この例では、7つの表のうち4つに対する変更のみが接続先データベースに伝播されますが、「既存のOracle Streamsレプリケーション環境へのオブジェクトの追加」を示す例では、hrスキーマ内の残りの表が接続先データベースに追加されます。
dbs1.netデータベースからは、これらの変更がメッセージの形式でdbs2.netのキューに伝播します。
dbs2.netでは、jobs表に対するDML変更がassignments表(jobsの直接のマッピング)に対するDML変更に変換されてから適用されます。hrスキーマ内の他の表に対する変更は、dbs2.netでは適用されません。
dbs3.netのキューは、dbs1.netのcountries、locationsおよびregions表で発生した変更をdbs2.netのキューから受信するため、これらの変更はdbs2.netからdbs3.netに伝播します。この構成は、有向ネットワークの一例です。
dbs3.netの適用プロセスは、countries、locationsおよびregionsの各表に変更を適用します。
dbs4.netはSybaseデータベースであり、dbs1.netで発生したjobs表に対する変更をdbs2.netのキューから受信するため、これらの変更はOracle Database Gateway経由でdbs4.netのデータベース・リンクを使用してdbs2.netからリモートで適用されます。この構成は、異機種間サポートの一例です。
この章の例を開始する前に、前提条件となる次の作業を完了する必要があります。
環境内のすべてのデータベースについて、次の初期化パラメータを指定の値に設定します。
GLOBAL_NAMES: Oracle Streams環境の各データベースで、このパラメータをTRUEに設定する必要があります。
COMPATIBLE: このパラメータは10.2.0以上に設定する必要があります。
STREAMS_POOL_SIZE: 環境内の各データベースで、このパラメータを適切な値に設定します(オプション)。このパラメータにはOracle Streamsプールのサイズを指定します。Oracle Streamsプールには、バッファ・キュー内のメッセージが格納されます。また、Oracle Streamsプールはパラレル取得およびパラレル適用時の内部通信に使用されます。MEMORY_TARGET、MEMORY_MAX_TARGETまたはSGA_TARGET初期化パラメータを0(ゼロ)以外の値に設定した場合、Oracle Streamsプールのサイズは自動的に管理されます。
|
参照: Oracle Streams環境で重要なその他の初期化パラメータについては、『Oracle Streams概要および管理』を参照してください。 |
取得される変更を生成するデータベースは、ARCHIVELOGモードで実行している必要があります。この例では、dbs1.netで変更が生成されるため、dbs1.netはARCHIVELOGモードで実行する必要があります。
|
参照: ARCHIVELOGモードでデータベースを実行する方法の詳細は、『Oracle Database管理者ガイド』を参照してください。 |
dbs2.net上のOracle Database Gatewayを、Sybaseデータベースdbs4.netと通信するように構成します。
|
参照: 『Oracle Database Heterogeneous Connectivity管理者ガイド』 |
Sybaseデータベースdbs4.netでhrユーザーを設定します。
|
参照: Sybaseデータベース内でユーザーと表を作成する方法については、Sybaseマニュアルを参照してください。 |
dbs4.net Sybaseデータベースで、dbs1.net Oracle Databaseからhr.jobs表をインスタンス化します。
ネットワークとOracle Netを、次のデータベースが相互に通信できるように構成します。
dbs1.netとdbs2.net
dbs2.netとdbs3.net
dbs2.netとdbs4.net
dbs3.netとdbs1.net(オプションのデータ・ポンプ・ネットワークのインスタンス化のため)
|
参照: 『Oracle Database Net Services管理者ガイド』 |
レプリケーション環境の各Oracle DatabaseでOracle Streams管理者を作成します。この例では、データベースはdbs1.net、dbs2.netおよびdbs3.netです。この例では、Oracle Streams管理者のユーザー名がstrmadminであると想定しています。
|
参照: Oracle Streams管理者を作成する方法は、『Oracle Streams概要および管理』を参照してください。 |
次の手順を実行して、3つのOracle Databaseと1つのSybaseデータベースを含むOracle Streamsレプリケーション環境にキューおよびデータベース・リンクを作成します。
|
注意: このマニュアルをオンラインで参照している場合、この注意の後にある「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.netでstreams_queueというキューを作成します。このキューはANYDATAキューとして動作し、他のデータベースに伝播される取得された変更を保持します。
SET_UP_QUEUEプロシージャを実行すると、次のアクションが実行されます。
streams_queue_tableというキュー表の作成。このキュー表は、Oracle Streams管理者(strmadmin)が所有し、このユーザーのデフォルトの記憶域を使用します。
Oracle Streams管理者(strmadmin)が所有するstreams_queueというキューの作成。
キューの起動。
*/ EXEC DBMS_STREAMS_ADM.SET_UP_QUEUE(); /*
変更が取得されるデータベースから変更が伝播されるデータベースへのデータベース・リンクを作成します。この例では、変更が取得されるデータベースは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.netでstreams_queueというキューを作成します。このキューはANYDATAキューとして動作し、このデータベースに適用される変更および他のデータベースに伝播される変更を保持します。
SET_UP_QUEUEプロシージャを実行すると、次のアクションが実行されます。
streams_queue_tableというキュー表の作成。このキュー表は、Oracle Streams管理者(strmadmin)が所有し、このユーザーのデフォルトの記憶域を使用します。
Oracle Streams管理者(strmadmin)が所有するstreams_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.netのhr.jobs表に対する変更をdbs2.netのhr.assignments表に対する変更に変換するルールベースの変換について説明します。この例での変換を正常に実行するために、dbs2.netにhr.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.netでstreams_queueというキューを作成します。このキューはANYDATAキューとして動作し、このデータベースに適用される変更を保持します。
SET_UP_QUEUEプロシージャを実行すると、次のアクションが実行されます。
streams_queue_tableというキュー表の作成。このキュー表は、Oracle Streams管理者(strmadmin)が所有し、このユーザーのデフォルトの記憶域を使用します。
Oracle Streams管理者(strmadmin)が所有するstreams_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.netでhrスキーマを再インスタンス化する必要があります。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 ******************************/
この例では、Oracle Streamsを使用してhrスキーマ内の表のレプリケーションを行う2つの方法について説明します。
「1つのデータベースからのデータを共有する簡単な構成」では、簡単な方法での環境の構成を示します。この例では、DBMS_STREAMS_ADMパッケージを使用して、取得プロセス、伝播および適用プロセスと、それらに関連付けられたルール・セットを作成します。DBMS_STREAMS_ADMパッケージを使用すると、最も簡単にOracle Streams環境を構成できます。
「1つのデータベースからのデータを共有する柔軟な構成」では、より柔軟な方法でのこの環境の構成を示します。この例では、DBMS_CAPTURE_ADMパッケージを使用して取得プロセスを作成し、DBMS_PROPAGATION_ADMパッケージを使用して伝播を作成し、DBMS_APPLY_ADMパッケージを使用して適用プロセスを作成します。また、この例では、DBMS_RULES_ADMパッケージを使用して、これらの取得プロセス、伝播および適用プロセスに関連付けられたルール・セットを作成および移入します。DBMS_STREAMS_ADMパッケージのかわりにこれらのパッケージを使用すると、より多くの構成オプションを使用でき、柔軟性が向上します。
|
注意: これらの例では、同じOracle Streams環境を構成する2つの異なる方法を示します。したがって、特定の分散データベース・システムに、いずれかの例のみを実行する必要があります。両方の例を実行すると、オブジェクトがすでに存在することを示すエラーが発生します。 |
次の手順を実行して、主にDBMS_STREAMS_ADMパッケージを使用して、取得、伝播および適用の定義を指定します。
|
注意: このマニュアルをオンラインで参照している場合、この注意の後にある「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.netでhrスキーマ全体に対する変更を取得するように取得プロセスを構成します。この手順では、指定したスキーマ内の表に対する変更が取得プロセスによって取得され、指定したキューにエンキューされるように指定します。
また、この手順では、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.netにhr.jobs表がすでに存在します。dbs2.netでは、この表の名前はassignmentsですが、この表はdbs1.netのjobs表と同じ形式で、同じデータを含んでいます。また、この例では、dbs4.netはSybaseデータベースです。Oracle Streams環境内の他のすべての表が、データ・ポンプ・インポートを使用して他の接続先データベースでインスタンス化されます。
hr.jobs表はdbs2.netおよびdbs4.netにすでに存在するため、この例では、dbs1.netでDBMS_FLASHBACKパッケージのGET_SYSTEM_CHANGE_NUMBERファンクションを使用して、データベースの現行のSCNを取得します。このSCNは、dbs2.netでDBMS_APPLY_ADMパッケージのSET_TABLE_INSTANTIATION_SCNプロシージャを実行するために使用されます。このプロシージャを2回実行して、dbs2.netおよびdbs4.netでhr.jobs表にインスタンス化SCNを設定します。
SET_TABLE_INSTANTIATION_SCNプロシージャを使用すると、適用プロセスで無視される表のLCRと、適用プロセスで適用される表のLCRを制御できます。ソース・データベースからの表に関するLCRのコミットSCNが、接続先データベースでその表のインスタンス化SCN以下であれば、接続先データベースの適用プロセスではLCRが廃棄されます。それ以外の場合は、適用プロセスによってLCRが適用されます。
この例では、dbs2.netの適用プロセスは、この手順で取得したSCNの後にコミットされたSCNを持つhr.jobs表にトランザクションを適用します。
|
注意: この例では、dbs1.net、dbs2.netおよびdbs4.netのhr.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.netのjobs表に対するDML文によって発生する行変更をdbs2.netのassignments表に対する行変更に変換するルールベースの変換ファンクションを作成します。
次のファンクションを実行すると、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.netのjobs表から変更を受信することに注意してください。
*/
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プロセスおよび伝播について構成したルールに基づいて、環境内の他のデータベースにこれらの変更がレプリケートされていることを確認できます。
/*************************** END OF SCRIPT ******************************/
次の手順を実行して、より柔軟な方法を使用して、取得、伝播および適用の定義を指定します。この方法では、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データ・ディクショナリ・ビューを問い合せます。 |
この例の手順は次のとおりです。
|
注意: このマニュアルをオンラインで参照している場合、この注意の後にある「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.netでhrスキーマ全体を取得する取得プロセスおよびルールを作成します。
*/
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.netでdbs1.netのhrスキーマをインスタンス化のために準備します。この手順では、インスタンス化のためにスキーマ内の表の最小SCNにマークが付けられます。最小SCNより後のSCNは、インスタンス化に使用できます。
また、この手順では、hrスキーマ内の表のすべての主キー列、一意キー列、ビットマップ索引列および外部キー列のサプリメンタル・ロギングを有効にします。サプリメンタル・ロギングによって、表に対する変更の追加の情報がREDOログに記録されます。適用プロセスでは、一意の行の識別や競合解消など、一部の操作を実行するために、この追加情報が必要です。この環境では、dbs1.netデータベースでのみ変更が取得されるため、hrスキーマ内の表に対してサプリメンタル・ロギングを指定する必要があるのはこのデータベースのみです。
|
注意: この手順は、「1つのデータベースからのデータを共有する簡単な構成」では不要です。簡単な構成の例では、手順3でDBMS_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.netにhr.jobs表がすでに存在します。dbs2.netでは、この表の名前はassignmentsですが、この表はdbs1.netのjobs表と同じ形式で、同じデータを含んでいます。また、この例では、dbs4.netはSybaseデータベースです。Oracle Streams環境内の他のすべての表が、データ・ポンプ・インポートを使用して他の接続先データベースでインスタンス化されます。
hr.jobs表はdbs2.netおよびdbs4.netにすでに存在するため、この例では、dbs1.netでDBMS_FLASHBACKパッケージのGET_SYSTEM_CHANGE_NUMBERファンクションを使用して、データベースの現行のSCNを取得します。このSCNは、dbs2.netでDBMS_APPLY_ADMパッケージのSET_TABLE_INSTANTIATION_SCNプロシージャを実行するために使用されます。このプロシージャを2回実行して、dbs2.netおよびdbs4.netでhr.jobs表にインスタンス化SCNを設定します。
SET_TABLE_INSTANTIATION_SCNプロシージャを使用すると、適用プロセスで無視される表のLCRと、適用プロセスで適用される表のLCRを制御できます。ソース・データベースからの表に関するLCRのコミットSCNが、接続先データベースでその表のインスタンス化SCN以下であれば、接続先データベースの適用プロセスではLCRが廃棄されます。それ以外の場合は、適用プロセスによってLCRが適用されます。
この例では、dbs2.netの適用プロセスは、この手順で取得したSCNの後にコミットされたSCNを持つhr.jobs表にトランザクションを適用します。
|
注意: この例では、dbs1.net、dbs2.netおよびdbs4.netのhr.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.netのjobs表に対するDML文によって発生する行変更をdbs2.netのassignments表に対する行変更に変換するルールベースの変換ファンクションを作成します。
次のファンクションを実行すると、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.netのjobs表から変更を受信することに注意してください。この手順では、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プロセスおよび伝播について構成したルールに基づいて、環境内の他のデータベースにこれらの変更がレプリケートされていることを確認できます。
/*************************** END OF SCRIPT ******************************/
「1つのデータベースからのデータを共有するスクリプトの例」で説明したいずれかの例を完了した後に、dbs1.netデータベースのhrスキーマ内の表に対してDML変更およびDDL変更を行うことができます。これらの変更は、Oracle Streamsプロセスおよび伝播について構成したルールに基づいて、環境内の他のデータベースにレプリケートされます。他のデータベースをチェックして、変更がレプリケートされていることを確認できます。
たとえば、次の手順を実行して、dbs1.netのhr.jobsおよびhr.locations表に対してDML変更を行います。また、dbs1.netのhr.locations表に対してDDL変更を行うこともできます。
これらの変更を行った後に、dbs2.netでhr.assignments表を問い合せて、dbs1.netのこの表に対して行ったDML変更がレプリケートされていることを確認できます。dbs2.netの適用プロセスに構成したルールベースの変換によって、hr.jobs表に対するDML変更がhr.assignments表に対するDML変更に変換されていることに注意してください。dbs3.netでhr.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.netのhr.jobs表に対して行ったUPDATE変更がdbs2.netのhr.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.netのhr.locations表に対して行ったINSERT変更がdbs3.netで適用されていることを確認します。
CONNECT hr@dbs3.net
Enter password: password
SELECT * FROM hr.locations WHERE location_id=3300;
前述の手順でdbs1.netのhr.locations表に挿入した行が表示されるはずです。
次に、hr.locations表の定義を表示して、ALTER TABLE変更が正常に伝播および適用されていることを確認します。
DESC hr.locations
表の5列目がstate_or_provinceであるはずです。
この例では、レプリケート・オブジェクトを既存のデータベースに追加して、前項で構成したOracle Streams環境を拡張します。この例を実行するには、前述の例のいずれか一方のタスクを完了している必要があります。
この例では、dbs3.netデータベースのhrスキーマに次の表を追加します。
departments
employees
job_history
jobs
この例を完了すると、Oracle Streamsでは、これらの表に対する変更が次の一連のアクションで処理されます。
取得プロセスがdbs1.netで変更を取得してエンキューします。
伝播によって、dbs1.netのキューからdbs2.netのキューに変更が伝播されます。
伝播によって、dbs2.netのキューからdbs3.netのキューに変更が伝播されます。
dbs3.netの適用プロセスが、変更をdbs3.netで適用します。
この例を完了すると、countries表、locations表およびregions表は前項でdbs3.netでインスタンス化されているため、dbs3.netデータベースのhrスキーマにはオリジナルの表がすべて含まれることになります。
図20-2に、表が追加された環境の概要を示します。
次の手順を実行して、前述の表をdbs3.netデータベースにレプリケートします。
|
注意: このマニュアルをオンラインで参照している場合、この注意の後にある「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の表のインスタンス化
この例では、データ・ポンプを使用して次の表のネットワーク・インポートを実行します。
hr.departments
hr.employees
hr.job_history
hr.jobs
ネットワーク・インポートとは、エクスポート・ダンプ・ファイルを使用せずに、データ・ポンプで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 ******************************/
「既存のOracle Streamsレプリケーション環境へのオブジェクトの追加」で説明した例を完了した後に、dbs1.netデータベースのhrスキーマ内の表に対してDML変更およびDDL変更を行うことができます。これらの変更は、dbs3.netにレプリケートされます。dbs3.netでこれらの表をチェックして、変更がレプリケートされていることを確認できます。
たとえば、次の手順を実行して、dbs1.netのhr.employees表に対してDML変更を行います。次に、dbs3.netでhr.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.netのhr.employees表に対して行ったUPDATE変更がdbs3.netのhr.employees表に適用されていることを確認します。
CONNECT hr@dbs3.net
Enter password: password
SELECT job_id FROM hr.employees WHERE employee_id=143;
job_idの値がST_MANと表示されるはずです。
この例では、既存の構成にデータベースを追加して、前項で構成したOracle Streams環境を拡張します。この例では、dbs2.netのキューからhrスキーマ全体に対する変更を受信するために、既存のOracle Database dbs5.netを追加します。
図20-3に、データベースが追加された環境の概要を示します。
この例を完了するには、次の前提条件を満たしている必要があります。
dbs5.netデータベースが存在すること。
dbs2.netおよびdbs5.netデータベースがOracle Netを介して相互に通信できること。
dbs5.netおよびdbs1.netデータベースがOracle Netを介して相互に通信できること(オプションのデータ・ポンプ・ネットワークのインスタンス化のため)。
この章の前述の例のタスクを完了していること。
Oracle Streams環境全体を正常に機能させる場合は、「前提条件」を満たしていること。
この例では、dbs5.netデータベースで新規ユーザーがOracle Streams管理者(strmadmin)として作成され、このユーザーのデータに使用する表領域の指定を求めるプロンプトが表示されます。この例を開始する前に、dbs5.netデータベースでOracle Streams管理者用に新規の表領域を作成するか、または既存の表領域を識別してください。SYSTEM表領域は、Oracle Streams管理者用にしないでください。
次の手順を実行して、dbs5.netをOracle Streams環境に追加します。
|
注意: このマニュアルをオンラインで参照している場合、この注意の後にある「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.netでhrスキーマを再インスタンス化する必要があります。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.netでstreams_queueというキューを作成します。このキューはANYDATAキューとして動作し、このデータベースに適用される変更を保持します。
SET_UP_QUEUEプロシージャを実行すると、次のアクションが実行されます。
streams_queue_tableというキュー表の作成。このキュー表は、Oracle Streams管理者(strmadmin)が所有し、このユーザーのデフォルトの記憶域を使用します。
Oracle Streams管理者(strmadmin)が所有するstreams_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.netがdbs5.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の表のインスタンス化
この例では、データ・ポンプを使用して次の表のネットワーク・インポートを実行します。
hr.countries
hr.departments
hr.employees
hr.job_history
hr.jobs
hr.locations
hr.regions
ネットワーク・インポートとは、エクスポート・ダンプ・ファイルを使用せずに、データ・ポンプで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 ******************************/
「既存のOracle Streamsレプリケーション環境へのデータベースの追加」で説明した例を完了した後に、dbs1.netデータベースのhrスキーマ内の表に対してDML変更およびDDL変更を行うことができます。これらの変更は、dbs5.netにレプリケートされます。dbs5.netでこれらの表をチェックして、変更がレプリケートされていることを確認できます。
たとえば、次の手順を実行して、dbs1.netのhr.departments表に対してDML変更を行います。次に、dbs5.netでhr.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.netのhr.departments表に対して行ったUPDATE変更がdbs5.netのhr.departments表に適用されていることを確認します。
CONNECT hr@dbs5.net
Enter password: password
SELECT location_id FROM hr.departments WHERE department_id=270;
location_idの値が2400と表示されるはずです。