マルチマスタレプリケーション で作った環境について、 いくつか管理コマンドを実施してみます。
マルチマスタレプリケーション環境では、 それぞれのサイトがマスター・サイトです。
マスター・サイトのうち、マスター・グループを定義したサイトをマスター定義サイトと言います。
何かの管理の都合で他のマスター・サイトをマスター定義サイトとしたい場合は、この処理を行います。
このような状態になっているとき、SDB2 をマスター定義サイトにしてみます。
dba_repsites に問い合わせます。master.sql として書きました。
#pre{{
select gname, dblink, masterdef from dba_repsites; }}
#pre{{
SCOTT_REPG SDB1.SUGIMURA.CC Y SCOTT_REPG SDB2.SUGIMURA.CC N
SQL> }}
SDB1.SUGIMURA.CC がマスター定義サイトになっていることがわかります。
SDB1 で DBMS_REPCAT.RELOCATE_MASTERDEF を実行します。
#pre{{ BEGIN
DBMS_REPCAT.RELOCATE_MASTERDEF ( gname => 'scott_repg', old_masterdef => 'sdb1.sugimura.cc', new_masterdef => 'sdb2.sugimura.cc', notify_masters => TRUE, include_old_masterdef => TRUE);
END; / }}
移っていることが確認できました。
#pre{{ SQL> @master
GNAME DBLINK MAS
SCOTT_REPG SDB1.SUGIMURA.CC N SCOTT_REPG SDB2.SUGIMURA.CC Y
SQL> }}
ここでは元に戻しておきます。SDB2 で実行します。
#pre{{ BEGIN
DBMS_REPCAT.RELOCATE_MASTERDEF ( gname => 'scott_repg', old_masterdef => 'sdb2.sugimura.cc', new_masterdef => 'sdb1.sugimura.cc', notify_masters => TRUE, include_old_masterdef => TRUE);
END; / }}
マスター定義サイトではない、SDB2 を削除してみます。
remove.sql を書きます。
#pre{{ BEGIN
DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY ( gname => 'scott_repg');
END; /
BEGIN
DBMS_REPCAT.REMOVE_MASTER_DATABASES ( gname => 'scott_repg', master_list => 'sdb2.sugimura.cc');
END; / }}
SDB1 で実行します。
#pre{{
消えました。
#pre{{ SQL> @master
GNAME DBLINK MAS
SCOTT_REPG SDB1.SUGIMURA.CC Y
SQL> }}
その後しばらくたってから dba_repcatlog を見て、 空であることを確認すれば削除終了です。
#pre{{
レコードが選択されませんでした。
SQL> }}
なかなか空にならないときは、急かすことも可能です。 下記のプロシージャを何度か実行します。
#pre{{ BEGIN
DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN ( gname => 'scott_repg', all_sites => TRUE);
END; / }}
これは問題の切り分けが必要ならば、 all_sites を FALSE にしてそれぞれのサイトで呼んでもいいでしょう。
削除がちゃんと終わったらレプリケーションを再開しておかないと、 表への更新ができなくなります。
#pre{{
*行1でエラーが発生しました。: ORA-23326: オブジェクト・グループ"PUBLIC"."SCOTT_REPG"は静止中です。
SQL> }}
DBMS_REPCAT.RESUME_MASTER_ACTIVITY を呼んで再開します。
#pre{{ BEGIN
DBMS_REPCAT.RESUME_MASTER_ACTIVITY ( gname => 'scott_repg');
END; / }}
外してみた SDB2 を再度追加してみます。SDB1 で実行します。
#pre{{ BEGIN
DBMS_REPCAT.ADD_MASTER_DATABASE ( gname => 'scott_repg', master => 'sdb2.sugimura.cc', use_existing_objects => TRUE, copy_rows => FALSE, propagation_mode => 'ASYNCHRONOUS');
END; / }}
実行すると怒られました。
#pre{{ BEGIN
行1でエラーが発生しました。: ORA-23374: オブジェクト・グループ"PUBLIC"."SCOTT_REPG"はすでに存在しています。 ORA-06512: "SYS.DBMS_SYS_ERROR", 行95 ORA-06512: "SYS.DBMS_REPCAT_MAS", 行2227 ORA-06512: "SYS.DBMS_REPCAT", 行146 ORA-06512: 行2 }}
SDB2 側で dba_repsites を見てみます。
#pre{{
SCOTT_REPG SDB2.SUGIMURA.CC N SCOTT_REPG SDB1.SUGIMURA.CC Y
SQL> }}
なぜか消えずに残っています。 DBMS_REPCAT.DROP_MASTER_REPGROUP を呼んで、 SDB2 では初めからなかったことにしてみます。 SDB2 で実行します。
#pre{{ BEGIN
DBMS_REPCAT.DROP_MASTER_REPGROUP ( gname => 'scott_repg', drop_contents => FALSE, all_sites => FALSE);
END; / }}
dba_repsites を確認してみます。
#pre{{ SQL> @master
レコードが選択されませんでした。
SQL> }}
これで再度追加してみました。SDB1 で実行します。
#pre{{ BEGIN
DBMS_REPCAT.ADD_MASTER_DATABASE ( gname => 'scott_repg', master => 'sdb2.sugimura.cc', use_existing_objects => TRUE, copy_rows => FALSE, propagation_mode => 'ASYNCHRONOUS');
END; / }}
それぞれで dba_repsites を確認してみます。
#pre{{
SCOTT_REPG SDB1.SUGIMURA.CC Y SCOTT_REPG SDB2.SUGIMURA.CC N
SQL> }}
#pre{{
SCOTT_REPG SDB2.SUGIMURA.CC N SCOTT_REPG SDB1.SUGIMURA.CC Y
SQL> }}
無事追加できました。
レプリケーションを再開して終了です。
#pre{{ BEGIN
DBMS_REPCAT.RESUME_MASTER_ACTIVITY ( gname => 'scott_repg');
END; / }}
静止状態にあるので、再開して完了です。
#pre{{ BEGIN
DBMS_REPCAT.RESUME_MASTER_ACTIVITY ( gname => 'scott_repg');
END; / }}
静止なのか再開されているのかを知るには、 dba_repgroup を見ます。
#pre{{
select gname, status from dba_repgroup; }}
#pre{{ BEGIN
DBMS_REPCAT.SUSPEND_MASTER_ACTIVITY ( gname => 'scott_repg');
END; / }}
NORMAL → QUIESCING → QUIESCED と移るようです。
静止するには何かと時間が掛かるようなので、 両ノードの状態を見ながら気長に待ちましょう。
#pre{{
SCOTT_REPG QUIESCED
SQL> }}
あまりにも QUIESCING の状態が長ければ、 DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN を実行すれば大丈夫です。 ここでは all_sites => FALSE にして、 それぞれのサイトで実行しました。
#pre{{ BEGIN
DBMS_REPCAT.DO_DEFERRED_REPCAT_ADMIN ( gname => 'scott_repg', all_sites => FALSE);
END; / }}
#pre{{ BEGIN
DBMS_REPCAT.RESUME_MASTER_ACTIVITY ( gname => 'scott_repg');
END; / }}
#pre{{
SCOTT_REPG NORMAL
SQL> }}