第6回:Oracle 同期型マルチマスタレプリケーションについて

技術者向け・データベースの技術情報発信

はじめに

皆様、こんにちは。マルチDBソリューション部の三浦です。

第1回目の「Oracle 同期型マルチマスタレプリケーションのデータ競合について」では、非同期型のマルチマスタレプリケーションはリアルタイムでの同期ではない為、両サイトでデータ更新された場合、データ競合発生の可能性があることを説明させて頂きました。

データ競合が発生した場合の解決方法などをご紹介させて頂きましたが、そもそもデータ競合を最も効率良く防ぐ方法は、非同期型ではなく同期型にすることです。 そこで、今回は、実際に同期型のマルチマスタレプリケーションを構築しデータ競合が本当に発生しないのか、確認してみたいと思います。

同期型のマルチマスタレプリケーションの作成

【前提条件】

ⅰ.非同期型のマルチマスタレプリケーションが構築されている環境へ、同期型を追加で構築します。

ⅱ.今回の環境では、以下の通り作成しています。
・マスターサイト名:MASTER
・レプリケーショングループ:REP_GROUP2
・テーブル所有者:TEST
・テーブル名   :REP_TABLE2

なお、非同期型の構築手順が記載されているホワイトペーパーは以下の通りですので、興味がある方はご確認下さい。

http://www.oracle.com/technetwork/jp/ondemand/database/db-technique/replipractice-520823-ja.pdf
※構築方法は、59ページ以降に記載されています。
【作成】

ⅰ.TESTユーザ及びレプリケーションするテーブルを作成 [作業:マスター定義サイト]
SQL> create user test identified by oracle default tablespace users quota unlimited on users;

ユーザーが作成されました。

SQL>
SQL> grant create session,create table to test;

権限付与が成功しました。

SQL>
SQL> conn test
パスワードを入力してください:
接続されました。
SQL>
SQL> create table rep_table2(no number constraint pk_rep_table2 primary key,name varchar2(20));

表が作成されました。

SQL>
SQL> insert into rep_table2 values(1,'aaaaaaaaa');

1行が作成されました。

SQL> insert into rep_table2 values (2,'bbbbbbbbbbbb');

1行が作成されました。

SQL> insert into rep_table2 values(3,'ccccccccc');

1行が作成されました。

SQL> commit;

コミットが完了しました。
ⅱ. TESTユーザを作成 [作業:マスターサイト]
SQL> create user test identified by oracle default tablespace users quota unlimited on users;

ユーザーが作成されました。

SQL>
SQL> grant create session,create table to test;

権限付与が成功しました。
ⅲ.レプリケーショングループの作成 [作業:マスター定義サイト]
非同期型とは別のレプリケーショングループ「REP_GROUP2」を作成します。
SQL> conn repadmin
パスワードを入力してください:
接続されました。
SQL> 
SQL> BEGIN
  2  DBMS_REPCAT.CREATE_MASTER_REPGROUP (
  3  gname => 'rep_group2');
  4  END;
  5  /

PL/SQLプロシージャが正常に完了しました。
ⅳ. レプリケーショングループへのテーブル追加 [作業:マスター定義サイト]
ⅱで作成したレプリケーショングループ「REP_GROUP2」へ、テーブル「REP_TABLE2」を加えます。
SQL> BEGIN
  2  DBMS_REPCAT.CREATE_MASTER_REPOBJECT (
  3  gname => 'rep_group2',
  4  type => 'TABLE',
  5  oname => 'REP_TABLE2',
  6  sname => 'test');
  7  END;
  8  /

PL/SQLプロシージャが正常に完了しました。
ⅴ. マスターサイトを追加 [作業:マスター定義サイト]
マスター定義サイト側で、マスターサイトを追加します。
SQL> BEGIN
  2  DBMS_REPCAT.ADD_MASTER_DATABASE (
  3  gname => 'rep_group2',
  4  master => 'MASTER',
  5  propagation_mode => 'synchronous');
  6  END;
  7  /

PL/SQLプロシージャが正常に完了しました。
※同期型を指定する場合は、propagation_modeへ「synchronous」を指定する必要があります。
ⅵ. レプリケーションサポートの作成 [作業:マスター定義サイト]
SQL> BEGIN
  2  DBMS_REPCAT.GENERATE_REPLICATION_SUPPORT (
  3  sname => 'TEST',
  4  oname => 'REP_TABLE2',
  5  type => 'TABLE');
  6  END;
  7  /

PL/SQLプロシージャが正常に完了しました。
ⅶ. レプリケーションの開始 [作業:マスター定義サイト]
SQL> BEGIN
  2  DBMS_REPCAT.RESUME_MASTER_ACTIVITY (
  3  gname => 'rep_group2');
  4  END;
  5  /

PL/SQLプロシージャが正常に完了しました。
これで、同期型のマルチマスタレプリケーションは構築されました。

補足として、構築時にエラーが発生した場合は、以下のテーブルでエラー原因を特定できることがあります。

・テーブル:DBA_REPCATLOG
例) マスターサイトへTESTユーザを作成しなかった場合
SQL> select REQUEST,MESSAGE from dba_repcatlog;

REQUEST                                      MESSAGE
--------------------------------------------------------       -----------------------------------------------
GENERATE_INTERNAL_PKG_SUPPORT        ORA-23308: オブジェクトTEST.REP_TABLE2が存在しないか、無効です。
DROP_MASTER_REPOBJECT                       ORA-23308: オブジェクトTEST.REP_TABLE2が存在しないか、無効です。
CREATE_MASTER_REPOBJECT                   ORA-01918: ユーザー'TEST'は存在しません

データ競合の確認

では続いて、本当にデータ競合が発生しないのか、確認してみましょう。
ⅰ. マスター定義サイト側でUPDATEを実施 (未COMMIT)
当然ですが、問題なくUPDATEができました。
SQL> update rep_table2 set name = 'aaa' where no = 1;

1行が更新されました。
ⅱ. マスターサイト側で同じレコードへUPDATEを実施
UPDATE文のコマンドが返ってきません。
SQL> update rep_table2 set name = 'bbb' where no = 1;
上記から、マスターサイト側では、マスター定義サイト側のトランザクション終了を待機している状態であり、同期型は2フェーズ・コミット・プロトコルを使用していることが分かります。

その為、確かにデータ競合は発生しない仕組みになっています。