この章では、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
と表示されるはずです。