ロジカルレプリケーションの仕組み
トランザクショナルなデータベースでは、必ずトランザクションログと呼ばれるデータベースへの変更を記録するファイルが出力されています。これは、トランザクションのロールバックで使用されたり、障害発生時のデータベースのリストアのために使用されています。先述したロジカルレプリケーションは、このトランザクションログの内容を解析して変更された内容をSQLとして連携先のデータベースに伝えることによってデータ同期を行う仕組みです。簡単に言うと「異なる種類のデータベースでも同じSQLを実行していれば、同じデータになります」ということです。
レプリケーションソフトウェアは連携元(ソース)データベースのトランザクションログを解析して変更SQLを抽出し、そのSQLを連携先(ターゲット)データベースで実行するということを繰り返しています。これにより、ニアリアルタイムでのデータ同期を実現しています。
Oracleのトランザクションログに含まれる情報
では、具体的にトランザクションログには、どのような情報が含まれているのでしょうか?
ここでは、代表的なデータベースであるOracleを例にOracleのトランザクションログ・REDOログの内容を解析してみましょう。
Oracleには、REDOログの解析を行うためにLogMinerという機能があるのをご存じだと思います。LogMinerは、データベース上で実行されるすべてのアクティビティの完全な記録であるREDOログの内容を見やすい形で見せてくれます。ただし、REDOログの中にテーブル名やカラム名などのオブジェクト名が含まれている訳ではないのでLogMiner実行時には、データ・ディクショナリにアクセスをして名称などを取得する必要があります。
最終的には、データベースで実行される各論理操作を動的なビューV$LOGMNR_CONTENTSとして確認することが出来ます。このビューの中には、変更のロールバックに使用出来る SQL UNDO文と元の操作が詳細に記述されたSQL REDO文が含まれています。
Oracleのマニュアルによれば、LogMinerで出来ることは、以下とあります。
- アプリケーション・レベルで発生したエラーなどデータベースの論理的破損が発生した時期を特定。
- DML文の事後監査、コミットされたトランザクション、アップデートしたユーザー。
- リカバリを行うために必要なSQLを特定。
- どの表にどんな更新が多いかなどの統計情報を取得し、チューニング時の優先順位を決定することができる。
LogMinerを使用してトランザクションログを覗く
次に実際にOracleの便利な機能であるLogMinerを使用して、どのような形でトランザクションログの内容が見えるのか確認してみましょう。今回使用したデータは、有名なOracleのデモデータEMP/DEPT/SALGRADE表です。デモデータは、以下のようになっています。
LogMiner検証手順
1. SUPPLEMENTAL LOGGINGの設定
A. 現在の設定状態を確認
SQL> select SUPPLEMENTAL_LOG_DATA_MIN from v$database;
SUPPLEMENTAL_LOG_DATA_MIN
------------------------------
NO
B. デフォルトでは無効なので有効化
SQL> alter database add supplemental log data;
データベースが変更されました。
C. 実際に変更されたか確認
SQL> select SUPPLEMENTAL_LOG_DATA_MIN from v$database;
SUPPLEMENTAL_LOG_DATA_MIN
------------------------------
YES
2. REDOログ切替
A. 現在のREDOログを確認
SQL> SELECT L.GROUP#, F.MEMBER, L.STATUS
FROM V$LOG L, V$LOGFILE F WHERE L.GROUP#=F.GROUP#;
GROUP# MEMBER STATUS
--------------------------------------------------------------
1 /oradata/ora11g/redo1/redo01_1.log INACTIVE
1 /oradata/ora11g/redo2/redo01_2.log INACTIVE
2 /oradata/ora11g/redo1/redo02_1.log INACTIVE
2 /oradata/ora11g/redo2/redo02_2.log INACTIVE
3 /oradata/ora11g/redo1/redo03_1.log CURRENT
3 /oradata/ora11g/redo2/redo03_2.log CURRENT
B. REDOログの切替
SQL> ALTER SYSTEM SWITCH LOGFILE;
3. LogMiner起動
A. 分析対象REDOログを指定(今回は、オンラインREDOログ)
SQL> execute dbms_logmnr.add_logfile(logfilename => -
> '/home/ora102/oracle/oradata/ora102/redo01.log' -
> ,options => dbms_logmnr.new);
PL/SQLプロシージャが正常に完了しました。
B. LogMiner起動
SQL> execute dbms_logmnr.start_logmnr(options => -
> dbms_logmnr.dict_from_online_catalog);
PL/SQLプロシージャが正常に完了しました。
これで準備OKです。実際にデータを更新してLogMinerでどのように見えるのか確認してみましょう。
・EMPテーブル更新
SQL> DELETE FROM EMP WHERE EMPNO=7844;
SQL> ROLLBACK;
SQL> UPDATE EMP SET SAL=SAL*1.1 WHERE EMPNO=7844;
SQL> DELETE FROM EMP WHERE DEPTNO=20;
SQL> COMMIT;
・SALGRADEテーブル更新
SQL> DELETE FROM SALGRADE WHERE GRADE=5;
SQL> ROLLBACK;
SQL> UPDATE SALGRADE SET HISAL=20000 WHERE GRADE=5;
SQL> COMMIT;
V$LOGMNR_CONTENTSを参照すると
下表のSQL列が実際に実行したSQLでV$LOGMNR_CONTENTSビューのSQL_REDO列を横に並べました。
実際に実行したSQLとV$LOGMNR_CONTENTSを見比べてみると、全てのSQL_REDOで表現されたSQLは、ROWIDがWHERE句で指定されており、SAL=SAL*1.1のような計算式は、固定値に変換されて生成されています。
DELETE FROM EMP WHERE DEPTNO=20;のような複数のレコードが更新されるようなSQLを実行すると、更新される一行一行を更新するSQLが更新されるレコード数だけ現れました。また、DEPTNO=20としてしかWHERE句で指定していませんが、その他のカラムの条件も付加されて生成されています。
さてこの情報を使って異種データベース間のレプリケーションは、実現出来るでしょうか?
答えは、NOです。なぜなら、こんなSQL文を異種データベースで実行してもエラーになってしまいます。また、ROWIDは、Oracle独自の仮想列で他のデータベースでは使用出来ません。しかし、SQL_REDOでは、ROWIDを使用することで一意に更新するレコードを特定しています。それでは、次回もご期待ください。
【異なるデータベース間のデータ同期が出来るわけ】連載一覧
- どんなデータベースがあるの
- データレプリケーションツール「Attunity Replicate」
- ロジカルレプリケーションの仕組み
- Oracleのトランザクションログに含まれる情報
- LogMinerを使用してトランザクションログを覗く
- LogMiner検証手順
- V$LOGMNR_CONTENTSを参照する
- SUPPLEMENTAL LOGGING
- V$LOGMNR_CONTENTSを参照する(追加設定後)
- Oracle以外でも同じか?