この章では、2つの異なるデータベースにある共有データベース・オブジェクト内のデータを比較する方法を説明します。共有データベース・オブジェクト内の相違データを収束する方法も説明します。
この章は次の項で構成されています。
関連項目:
|
2つ以上のデータベースでデータベース・オブジェクトを共有できます。同じデータベース・オブジェクトのコピーが複数のデータベースに存在している場合、データベース・オブジェクトは共有データベース・オブジェクトです。共有データベース・オブジェクトは、データ・レプリケーションによってメンテナンスできます。たとえば、マテリアライズド・ビューまたはOracle Streamsコンポーネントは、データベース・オブジェクトをレプリケートし、複数のデータベースでそれらをメンテナンスできます。カスタム・アプリケーションも、共有データベース・オブジェクトをメンテナンスできます。通常、レプリケーション環境では、データを含むオブジェクト(表など)と、その他のタイプのデータベース・オブジェクト(索引など)を共有します。
1つのデータベースで共有データベース・オブジェクトに変更が加えられた場合、変更が転送され、データベース・オブジェクトを共有する他の各データベースに加えられます。こうして、レプリケーション環境は各データベースの共有データベース・オブジェクトを同期します。
データを含む共有データベース・オブジェクトは、異なるデータベースで一貫性がなくなることがあります。つまり、データは共有データベース・オブジェクトの異なる・インスタンスで拡散します。たとえば、データベース・オブジェクトが表の場合は、表の1つのインスタンスが表の別のインスタンスよりも多くの行を持つこと、または表の2つのインスタンスが同じ行に異なるデータを持つことがあります。
Oracle Streamsレプリケーション環境で共有データベース・オブジェクトが拡散する場合、通常は次のいずれかの理由です。
データ変更が1つ以上のデータベースで取得されていません。
データ変更は取得されていますが、1つのデータベースから別のデータベースに転送されていません。
データ変更が取得され、1つのデータベースから別のデータベースに転送されましたが、他のデータベースの共有データベース・オブジェクトに対してその変更が加えられていません。
データ拡散の一般的な原因は、ネットワークの問題、不正な構成またはユーザー・エラーです。共有データベース・オブジェクトが、マテリアライズド・ビューを使用するレプリケーション環境で拡散する場合は、マテリアライズド・ビューのリフレッシュに問題がある可能性があります。
DBMS_COMPARISON
パッケージを使用して、異なるデータベースのデータベース・オブジェクトを比較し、差異を識別できます。このパッケージでは、異なるデータベースで一貫するようにデータベース・オブジェクトを収束させることもできます。DBMS_COMPARISON
パッケージは、Oracle Databaseとともに必ずインストールされるOracle提供のPL/SQLパッケージです。
DBMS_COMPARISON
パッケージは、次のタイプのデータベース・オブジェクトの比較および収束を行うことができます。
表
単一表ビュー
マテリアライズド・ビュー
表、単一表ビューおよびマテリアライズド・ビューのシノニム
異なるデータベースにある異なるタイプのデータベース・オブジェクトの比較および収束を行うことができます。たとえば、あるデータベースにある表と、別のデータベースにあるマテリアライズド・ビューの比較および収束を行うことができます。
このマニュアルの例では、共有データベース・オブジェクトが2つのデータベースで同じ名前を持ち、データベース・オブジェクト全体が比較および収束されています。ただし、DBMS_COMPARISON
パッケージは、異なるデータベースにある共有データベース・オブジェクトの差異について柔軟性を提供します。比較されるデータベース・オブジェクトは、必ずしも同じ名前を持つ必要はありません。また、対応する列が同じデータ型である場合、データベース・オブジェクト内で列名が異なっていてもかまいません。共有データベース・オブジェクト全体、または列および行のサブセットの比較および収束を行うことができます。
比較を作成するには、DBMS_COMPARISON
パッケージのCREATE_COMPARISON
プロシージャを使用します。このプロシージャは、共有データベース・オブジェクトの1つ以上の索引列を識別します。DBMS_COMPARISON
パッケージは、索引列として使用できる少なくとも1つの列を識別できる必要があります。指定されたデータベース・オブジェクトに、索引列として使用できる列がない場合、CREATE_COMPARISON
プロシージャはデータベース・オブジェクトの比較を作成できません。
注意: 環境に、拡散した共有データベース・オブジェクトがある場合は、問題の原因を調査して解決する必要があります。DBMS_COMPARISON パッケージは共有データベース・オブジェクトの比較および収束を行うことができますが、これらのデータベース・オブジェクトは拡散しないことをお薦めします。 |
関連項目:
|
2つのデータベースでhr.departments
表を共有するとします。この表を異なるデータベースで比較して、データが一貫しているかどうかを確認します。2つのデータベースで表が拡散している場合は、これらを収束させて一貫させます。
このチュートリアルを実行する前に、次の前提条件を満たします。
ネットワーク接続を構成して、2つのデータベースが相互に通信できるようにします。データベース間のネットワーク接続の構成の詳細は、『Oracle Database 2日でデータベース管理者』を参照してください。
hr
サンプル・スキーマが両方のデータベースにインストールされていることを確認します。 hr
サンプル・スキーマは、Oracle Databaseとともにデフォルトでインストールされます。
この例では、データベースのグローバル名はii1.example.com
およびii2.example.com
ですが、使用している環境で、前提条件を満たす任意の2つのデータベースをかわりに使用できます。
ii1.example.comおよびii2.example.comデータベースのhr.departments表の比較および収束を準備するには:
この例の目的を満たすために、2つのデータベースでhr.departments
表を拡散させます。
コマンドラインでSQL*Plusを開き、ii2.example.com
データベースにhr
ユーザーとして接続してください。
SQL*Plusの起動の詳細は、『Oracle Database 2日でデータベース管理者』を参照してください。
hr.departments
表で、department_id
が 270
と等しい部門を削除します。
DELETE FROM hr.departments WHERE department_id=270; COMMIT;
hr.departments
表で、ある行のデータを変更します。
UPDATE hr.departments SET manager_id=114 WHERE department_id=10; COMMIT;
hr.departments
表に行を挿入します。
INSERT INTO hr.departments VALUES(280, 'Bean Counters', 108, 2700); COMMIT;
SQL*Plusを終了します。
EXIT;
ii1.example.com
データベースからii2.example.com
データベースへのデータベース・リンクを作成します。
データベース・リンクは、ii1.example.com
の管理ユーザーのスキーマからii2.example.com
の管理ユーザーのスキーマに接続する必要があります。両方のデータベースの管理ユーザーは、hr.departments
表にアクセスして変更するために必要な権限と、DBMS_COMPARISON
パッケージのサブプログラムを実行するために必要な権限を持っている必要があります。どのユーザーがこれらの権限を持っているかが不明な場合は、SYSTEM
ユーザーを使用します。また、データベース・リンクの名前とサービス名は、どちらもii2.example.com
である必要があります。詳細は、「チュートリアル: データベース・リンクの作成」を参照してください。
この例は、「チュートリアル: データの比較および収束の準備」で説明したシナリオの続きです。先に進む前に、その項の手順を完了してください。
DBMS_COMPARISON
パッケージのCREATE_COMPARISON
プロシージャを使用して、2つの異なるデータベースにある共有データベース・オブジェクトの比較を定義できます。比較が定義された後で、このパッケージのCOMPARE
ファンクションを使用して、比較で指定したデータベース・オブジェクトを現在の時点で比較できます。 COMPARE
ファンクションは、特定の比較に対して複数回実行できます。ファンクションを実行するたびに、データベース・オブジェクトのスキャンが1回以上行われ、各スキャンが独自のスキャンIDを持ちます。
ii1.example.comおよびii2.example.comデータベースのhr.departments表全体を比較するには:
コマンドラインでSQL*Plusを開き、「チュートリアル: データの比較および収束の準備」で作成したデータベース・リンクを所有する管理ユーザーとしてii1.example.com
データベースに接続します。たとえば、SYSTEM
ユーザーがデータベース・リンクを所有する場合は、SYSTEM
ユーザーとして接続します。
sqlplus system@ii1.example.com
Enter password: password
SQL*Plusの起動の詳細は、『Oracle Database 2日でデータベース管理者』を参照してください。
CREATE_COMPARISON
プロシージャを実行して、hr.departments
表の比較を作成します。
BEGIN DBMS_COMPARISON.CREATE_COMPARISON( comparison_name => 'compare_departments', schema_name => 'hr', object_name => 'departments', dblink_name => 'ii2.example.com'); END; /
新しい比較の名前はcompare_departments
であることに注意してください。この比較は、CREATE_COMPARISON
プロシージャを実行するユーザーが所有します。
COMPARE
ファンクションを実行して、2つのデータベースのhr.departments
表を比較します。
SET SERVEROUTPUT ON DECLARE consistent BOOLEAN; scan_info DBMS_COMPARISON.COMPARISON_TYPE; BEGIN consistent := DBMS_COMPARISON.COMPARE( comparison_name => 'compare_departments', scan_info => scan_info, perform_row_dif => TRUE); DBMS_OUTPUT.PUT_LINE('Scan ID: '||scan_info.scan_id); IF consistent=TRUE THEN DBMS_OUTPUT.PUT_LINE('No differences were found.'); ELSE DBMS_OUTPUT.PUT_LINE('Differences were found.'); END IF; END; / Scan ID: 1 Differences were found. PL/SQL procedure successfully completed.
手順2で作成した比較の名前をcomparison_name
パラメータに指定します。
ファクションは、比較のスキャンIDを出力します。比較に関する情報をデータ・ディクショナリ・ビューに問い合せる場合、およびデータベース・オブジェクトを収束させる場合は、スキャンIDが重要です。
ファンクションは、2つのデータベースで表に差異が見つかったかどうかも出力します。
ファンクションが「違いが見つかりません」
と出力する場合、表は2つのデータベースで一貫しています。
ファンクションが「違いが見つかりました」
と出力する場合は、表が2つのデータベースで拡散しています。
前の手順でファンクションから返されたスキャンIDを記録しておきます。この例では、スキャンIDが1
であると想定します。
手順3で差異が見つかった場合は、次の問合せを実行して、見つかった差異の数を表示します。
COLUMN OWNER HEADING 'Comparison Owner' FORMAT A16 COLUMN COMPARISON_NAME HEADING 'Comparison Name' FORMAT A20 COLUMN SCHEMA_NAME HEADING 'Schema Name' FORMAT A11 COLUMN OBJECT_NAME HEADING 'Object Name' FORMAT A11 COLUMN CURRENT_DIF_COUNT HEADING 'Differences' FORMAT 9999999 SELECT c.OWNER, c.COMPARISON_NAME, c.SCHEMA_NAME, c.OBJECT_NAME, s.CURRENT_DIF_COUNT FROM DBA_COMPARISON c, DBA_COMPARISON_SCAN s WHERE c.COMPARISON_NAME = s.COMPARISON_NAME AND c.OWNER = s.OWNER AND s.SCAN_ID = 1;
問合せのWHERE
句に、手順4で記録したスキャンIDを指定します。
出力は、次のようになります。
Comparison Owner Comparison Name Schema Name Object Name Differences ---------------- -------------------- ----------- ----------- ----------- SYSTEM COMPARE_DEPARTMENTS HR DEPARTMENTS 3
比較されているデータベース・オブジェクトのどの行が異なるかを確認するには、次の問合せを実行します。
COLUMN COLUMN_NAME HEADING 'Index Column' FORMAT A15 COLUMN INDEX_VALUE HEADING 'Index Value' FORMAT A15 COLUMN LOCAL_ROWID HEADING 'Local Row Exists?' FORMAT A20 COLUMN REMOTE_ROWID HEADING 'Remote Row Exists?' FORMAT A20 SELECT c.COLUMN_NAME, r.INDEX_VALUE, DECODE(r.LOCAL_ROWID, NULL, 'No', 'Yes') LOCAL_ROWID, DECODE(r.REMOTE_ROWID, NULL, 'No', 'Yes') REMOTE_ROWID FROM DBA_COMPARISON_COLUMNS c, DBA_COMPARISON_ROW_DIF r, DBA_COMPARISON_SCAN s WHERE c.COMPARISON_NAME = 'COMPARE_DEPARTMENTS' AND r.SCAN_ID = s.SCAN_ID AND s.PARENT_SCAN_ID = 1 AND r.STATUS = 'DIF' AND c.INDEX_COLUMN = 'Y' AND c.COMPARISON_NAME = r.COMPARISON_NAME AND c.OWNER = r.OWNER ORDER BY r.INDEX_VALUE;
WHERE
句には、比較の名前と比較のスキャンIDを指定します。この例では、比較の名前はcompare_departments
で、スキャンIDは1
です。
出力は、次のようになります。
Index Column Index Value Local Row Exists? Remote Row Exists? --------------- --------------- -------------------- -------------------- DEPARTMENT_ID 10 Yes Yes DEPARTMENT_ID 270 Yes No DEPARTMENT_ID 280 No Yes
この出力は、比較される表の索引列と、共有データベース・オブジェクト内で異なっている各行の索引値を示します。この例では、索引列はhr.departments
表の主キー列(department_id
)です。出力は、各行の差異のタイプも示します。
Local
Row
Exists?
とRemote
Row
Exists?
の両方が、ある行に対してYes
の場合、その行はデータベース・オブジェクトの両方のインスタンスに存在しますが、行のデータは異なります。
ある行についてLocal
Row
Exists?
がYes
で、Remote
Row
Exists?
がNo
の場合、その行はローカル・データベース・オブジェクトに存在しますが、リモート・データベース・オブジェクトには存在しません。
ある行についてLocal
Row
Exists?
がNo
で、Remote
Row
Exists?
がYes
の場合、その行はリモート・データベース・オブジェクトに存在しますが、ローカル・データベース・オブジェクトには存在しません。
この例は、「チュートリアル: 2つの異なるデータベース内のデータの比較」で説明したシナリオの続きです。先に進む前に、その項の手順を完了してください。
共有データベース・オブジェクトが2つの異なるデータベースで拡散した場合は、DBMS_COMPARISON
パッケージのCONVERGE
プロシージャを使用して、データベース・オブジェクトの2つのインスタンスを収束させることができます。CONVERGE
プロシージャを正常に実行すると、共有データベース・オブジェクトが2つのデータベースで一貫します。CONVERGE
プロシージャを実行するには、次の情報を指定する必要があります。
DBMS_COMPARISON
パッケージのCREATE_COMPARISON
プロシージャを使用して作成した既存の比較の名前
収束させる比較のスキャンID
スキャンIDには、収束させる差異に関する情報が含まれます。この例では、比較の名前はcompare_departments
で、スキャンIDは 1
です。
また、CONVERGE
プロシージャを実行する際には、共有データベース・オブジェクトが収束するときに「優先」されるデータベースを指定する必要があります。ローカル・データベースが優先されることを指定した場合は、データが異なるときに、ローカル・データベースのデータベース・オブジェクト内のデータでリモート・データベースのデータベース・オブジェクト内のデータが置換されます。リモート・データベースが優先されることを指定した場合は、データが異なるときに、リモート・データベースのデータベース・オブジェクト内のデータでローカル・データベースのデータベース・オブジェクト内のデータが置換されます。この例では、ローカル・データベースii1.example.com
が優先されます。
ii1.example.comおよびii2.example.comデータベースのhr.departments表の相違データを収束させるには:
コマンドラインでSQL*Plusを開き、「チュートリアル: データの比較および収束の準備」で作成したデータベース・リンクを所有する管理ユーザーとしてii1.example.com
データベースに接続します。たとえば、SYSTEM
ユーザーがデータベース・リンクを所有する場合は、SYSTEM
ユーザーとして接続します。
sqlplus system@ii1.example.com
Enter password: password
SQL*Plusの起動の詳細は、『Oracle Database 2日でデータベース管理者』を参照してください。
CONVERGE
プロシージャを実行して、2つのデータベースのhr.departments
表を収束させます。
SET SERVEROUTPUT ON DECLARE scan_info DBMS_COMPARISON.COMPARISON_TYPE; BEGIN DBMS_COMPARISON.CONVERGE( comparison_name => 'compare_departments', scan_id => 1, scan_info => scan_info, converge_options => DBMS_COMPARISON.CMP_CONVERGE_LOCAL_WINS); DBMS_OUTPUT.PUT_LINE('Local Rows Merged: '||scan_info.loc_rows_merged); DBMS_OUTPUT.PUT_LINE('Remote Rows Merged: '||scan_info.rmt_rows_merged); DBMS_OUTPUT.PUT_LINE('Local Rows Deleted: '||scan_info.loc_rows_deleted); DBMS_OUTPUT.PUT_LINE('Remote Rows Deleted: '||scan_info.rmt_rows_deleted); END; / Local Rows Merged: 0 Remote Rows Merged: 2 Local Rows Deleted: 0 Remote Rows Deleted: 1 PL/SQL procedure successfully completed.
CONVERGE
プロシージャは、指定されたスキャンで比較されるデータベース・オブジェクトの部分を同期し、行われた変更に関する情報を返します。一部のスキャンは、データベース・オブジェクトのサブセットを比較することがあります。この例では、指定されたスキャンは表全体を比較しました。このため、比較スキャンの完了後に新しい差異が追加されていないと想定すると、表全体が同期されています。
この例では、プロシージャでconverge_options
パラメータがDBMS_COMPARISON.CMP_CONVERGE_LOCAL_WINS
に設定されているためローカル表が優先されます。つまり、2つのデータベースで異なる行については、ローカル・データベースの行によって、リモート・データベースの対応する行が置換されます。一部の行がリモート・データベースに存在し、ローカル・データベースには存在しない場合は、リモート・データベースの余分な行が削除されます。リモート・データベースを優先する場合は、プロシージャでconverge_options
パラメータをDBMS_COMPARISON.CMP_CONVERGE_REMOTE_WINS
に設定します。
また、Oracle Streamsレプリケーション環境の一部である共有データベース・オブジェクトに対してCONVERGE
プロシージャを実行する場合は、プロシージャによって行われた変更を他のデータベースにレプリケートしたくないことがあります。この場合は、CONVERGE
プロシージャで、次のパラメータを変更がレプリケートされない値に設定できます。
local_converge_tag
remote_converge_tag
これらのパラメータのいずれかがNULL
以外の値に設定されている場合、収束中に変更を行うセッションでタグが設定されます。local_converge_tag
パラメータはセッション中にローカル・データベースにタグを設定しますが、remote_converge_tag
パラメータはセッション中にリモート・データベースにタグを設定します。CONVERGE
プロシージャによって行われた変更をレプリケートしない場合は、これらのパラメータを、Oracle Streams取得プロセスおよび同期取得が変更を取得しないようにする値に設定します。