OracleユーティリティのLogMinerについて、机上の知識はあるものの、実務経験が無いため、実際の動きを検証しました。
LogMinerは、REDOログファイルやアーカイブログファイルに記録された更新情報(SQLなど)を分析できるツールです。
ただし、LogMinerを使えばすぐ分析できるわけではなく、事前にサプリメンタル・ロギング(REDOログファイルに分析用の追加情報を出力する機能)を有効にする必要があります。
なお、サプリメンタル・ロギングを有効にする場合、有効範囲とロギングレベルを指定する必要があります。
有効範囲
データベースレベルか表レベルで指定できます。
データベースレベルの場合、DB全体に対して有効になります。
表レベルの場合、特定の表に対して有効になります。
データベースレベルで指定する場合
alter database [add | drop] supplemental log data [(ALL | PRIMARY KEY | UNIQUE | FOREIGN KEY) columns];
表レベルで指定する場合
alter <スキーマ名>.<表名> [add | drop] supplemental log data (ALL | PRIMARY KEY | UNIQUE | FOREIGN KEY) columns;
※本検証はデータベースレベルで検証します
ロギングレベル
最小レベルか識別キーレベルで指定できます。
ロギングレベルに応じてREDOログファイルに追加される情報も増えます。
最小サプリメンタル・ロギング
LogMiner(LogMinerの仕組みを使用している製品)を使用するにあたり、必要最低限の追加情報(ログ情報)をREDOログファイルに出力します。
表レベルでは設定できません。
識別キー・ロギング
PRIMARY KEY
主キーを持つ表に対して、更新されるたびにすべての主キー列をREDOログファイルに出力します。
データベースレベル、表レベルともに設定できます。(データベースレベルで有効した場合、同時に最小レベルも有効になります)
UNIQUE
一意キーを持つ表に対して、一意キー列のいずれかが更新されるたびにその一意キーに属するすべての列をREDOログファイルに出力します。
データベースレベル、表レベルともに設定できます。(データベースレベルで有効した場合、同時に最小レベルも有効になります)
FOREIGN KEY
外部キーを持つ表に対して、外部キー列のいずれかが更新されるたびにその外部キーに属するすべての列をREDOログファイルに出力します。
データベースレベル、表レベルともに設定できます。(データベースレベルで有効した場合、同時に最小レベルも有効になります)
ALL
行が更新されるたびにすべての列をREDOログファイルに出力します。
データベースレベル、表レベルともに設定できます。(データベースレベルで有効した場合、同時に最小レベルも有効になります)
余談ですが、サプリメンタル・ロギングはOracle GoldenGate(LogMinerの仕組みを使用している製品)などDB間でデータ連携するときにも使用しています。
LogMinerを使用する目的は公式マニュアルではざっくり下記のように記載されています。
・アプリケーションレベルのエラー(不適切な行削除や行更新、オブジェクトの削除など)など、論理破損が発生した時期やリカバリSQLの特定
・依存関係のあるトランザクションのリカバリSQLの特定
・SQLの実行履歴から実行したSQLの傾向分析(どの表で更新や挿入が頻発しているかなど)
・事後監査(DBで実行されたDMLやDDL、実行順序、実行者などの追跡など)
特にアプリケーションレベルのエラーはフラッシュバック操作すればいいんじゃない?という疑問もありますが、高速リカバリ領域を構成していない(構成できない)場合などはLogMinerが使えそうですね。
■検証環境
OS:Oracle Linux 6.5
GI:Oracle Grid Infrastructure 12c Release 1 (12.1.0.2.0) Enterprise Edition
DB:Oracle Database 12c Release 1 (12.1.0.2.0) Enterprise Edition
※2ノードRAC(管理者管理型DB)
■前提
なし
■検証パターン
①最小サプリメンタル・ロギング
②識別キー(PRIMARY KEY)サプリメンタル・ロギング
③識別キー(FOREIGN KEY)サプリメンタル・ロギング
④識別キー(ALL)サプリメンタル・ロギング
※UNIQUEは手元に手ごろな表がなかったので未検証
■検証
①最小サプリメンタル・ロギング
ロギングレベルを最小サプリメンタル・ロギングにした場合、REDOログファイルに出力される内容を検証します
【検証手順】
1. 最小サプリメンタルロギング設定
2. 分析対象のREDOログファイル特定
3. LogMinerディクショナリ・ファイル作成
4. 分析対象のREDOログファイル追加
5. LogMiner起動
6. テストデータ更新
7. 分析
8. LogMiner終了
9. 最小サプリメンタルロギング削除
【作業ログ】
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
NO NO NO NO NO
SQL> alter database add supplemental log data;
データベースが変更されました。
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
YES NO NO NO NO
2. 分析対象のREDOログファイル特定
SQL> select
2 l.GROUP#, l.THREAD#, l.SEQUENCE#, l.STATUS, lf.MEMBER
3 from
4 v$log l, v$logfile lf
5 where
6 l.GROUP# = lf.GROUP#
7 order by
8 l.GROUP#, l.THREAD#;
GROUP# THREAD# SEQUENCE# STATUS MEMBER
---------- ---------- ---------- --------------- ----------------------------------------
1 1 43 INACTIVE +DATA/ORCL/ONLINELOG/redo01.log
2 1 44 CURRENT +DATA/ORCL/ONLINELOG/redo02.log
3 2 39 CURRENT +DATA/ORCL/ONLINELOG/redo03.log
4 2 38 INACTIVE +DATA/ORCL/ONLINELOG/redo04.log
3. LogMinerディクショナリ・ファイル作成
LogMinerディクショナリは、REDOログファイルのREDOデータをユーザに表示する際、オブジェクトIDをオブジェクト名に変換するためのファイルです(マップみたいなイメージ)
LogMinerディクショナリには3種類ありますが、本検証ではオンライン・カタログを使用するため、LogMinerディクショナリ・ファイル作成は割愛します
-オンライン・カタログ
-REDOログファイル埋め込み
-フラットファイル(非推奨)
4. 分析対象のREDOログファイル追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo02.log', OPTIONS => DBMS_LOGMNR.NEW);
PL/SQLプロシージャが正常に完了しました。
★RACなのでスレッド2の方も追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo03.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
★ログスイッチ等でREDOログファイルが切り替わっても対応できるよう、CURRENT以外のREDOログ・ファイルも追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo01.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo04.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
5. LogMiner起動
SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR(Options => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY);
PL/SQLプロシージャが正常に完了しました。
6. テストデータ更新(別セッション)
別TeraTermを立ち上げ、別セッションでテストデータを更新します
SQL> select * from emp where EMPNO = 7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 800 20
SQL> update emp set SAL = 9999 where EMPNO = 7369;
1行が更新されました。
SQL> commit;
コミットが完了しました。
SQL> select * from emp where EMPNO = 7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 9999 20
【参考】
一回ハマったのですが、DBMS_LOGMNR.START_LOGMNR()したセッションを終了してしまうと後続のv$logmnr_contentsへ問い合わせた際、下記エラーが発生します
------------------------------------------------------------
行8でエラーが発生しました。:
ORA-01306: dbms_logmnr.start_logmnr()は、v$logmnr_contentsから選択する前に起動する必要があります。
------------------------------------------------------------
※上記が発生した場合、ADD_LOGFILE()からやり直す必要があります
7. 分析
SQL> SELECT
2 SCN, TO_CHAR(TIMESTAMP, 'YYYY/MM/DD HH24:MI:SS') AS TM_STAMP, OPERATION, SQL_REDO, SQL_UNDO
3 FROM
4 V$LOGMNR_CONTENTS
5 WHERE
6 USERNAME = 'SCOTT'
7 ORDER BY
8 SCN DESC;
SCN TM_STAMP OPERATION SQL_REDO SQL_UNDO
---------- -------------------- ---------- ------------------------------------------------------------ ------------------------------------------------------------
6727554 2022/11/11 10:28:46 UPDATE update "SCOTT"."EMP" set "SAL" = '9999' where "SAL" = '800' update "SCOTT"."EMP" set "SAL" = '800' where "SAL" = '9999'
and ROWID = 'AAAWwdAAGAAAADFAAA'; and ROWID = 'AAAWwdAAGAAAADFAAA';
★SQL_REDO列のWHERE句がEMPNOではなく、SALとROWIDに変わっていました
8. LogMiner終了
SQL> EXECUTE DBMS_LOGMNR.END_LOGMNR();
PL/SQLプロシージャが正常に完了しました。
9. 最小サプリメンタルロギング削除
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
YES NO NO NO NO
SQL> alter database drop supplemental log data;
データベースが変更されました。
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
NO NO NO NO NO
②識別キー(PRIMARY KEY)サプリメンタル・ロギング
ロギングレベルを識別キー(PRIMARY KEY)サプリメンタル・ロギングにした場合、REDOログファイルに出力される内容を検証します
【検証手順】
1. 識別キー(PRIMARY KEY)サプリメンタル・ロギング設定
2. 分析対象のREDOログファイル特定
3. LogMinerディクショナリ・ファイル作成
4. 分析対象のREDOログファイル追加
5. LogMiner起動
6. テストデータ更新
7. 分析
8. LogMiner終了
9. 識別キー(PRIMARY KEY)サプリメンタル・ロギング削除
【作業ログ】
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
NO NO NO NO NO
SQL> alter database add supplemental log data (primary key) columns;
データベースが変更されました。
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
IMPLICIT YES NO NO NO
★識別キーサプリメンタル・ロギングを有効にした際、同時に最小サプリメンタル・ロギングも有効になっているため、SUPPLEMENTAL_LOG_DATA_MIN列もIMPLICITになっています
2. 分析対象のREDOログファイル特定
SQL> select
2 l.GROUP#, l.THREAD#, l.SEQUENCE#, l.STATUS, lf.MEMBER
3 from
4 v$log l, v$logfile lf
5 where
6 l.GROUP# = lf.GROUP#
7 order by
8 l.GROUP#, l.THREAD#;
GROUP# THREAD# SEQUENCE# STATUS MEMBER
---------- ---------- ---------- --------------- ----------------------------------------
1 1 43 INACTIVE +DATA/ORCL/ONLINELOG/redo01.log
2 1 44 CURRENT +DATA/ORCL/ONLINELOG/redo02.log
3 2 39 CURRENT +DATA/ORCL/ONLINELOG/redo03.log
4 2 38 INACTIVE +DATA/ORCL/ONLINELOG/redo04.log
3. LogMinerディクショナリ・ファイル作成
本検証ではオンライン・カタログを使用するため、LogMinerディクショナリ・ファイル作成は割愛します
4. 分析対象のREDOログファイル追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo02.log', OPTIONS => DBMS_LOGMNR.NEW);
PL/SQLプロシージャが正常に完了しました。
★RACなのでスレッド2の方も追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo03.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
★ログスイッチ等でREDOログファイルが切り替わっても対応できるよう、CURRENT以外のREDOログ・ファイルも追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo01.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo04.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
5. LogMiner起動
SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR(Options => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY);
PL/SQLプロシージャが正常に完了しました。
6. テストデータ更新(別セッション)
別TeraTermを立ち上げ、別セッションでテストデータを更新します
PRIMARY KEY制約(EMPNO列)があるレコードを更新してみます
SQL> select * from emp where EMPNO = 7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 9999 20
SQL> update emp set SAL = 10000 where EMPNO = 7369;
1行が更新されました。
SQL> commit;
コミットが完了しました。
SQL> select * from emp where EMPNO = 7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 10000 20
7. 分析
SQL> SELECT
2 SCN, TO_CHAR(TIMESTAMP, 'YYYY/MM/DD HH24:MI:SS') AS TM_STAMP, OPERATION, SQL_REDO, SQL_UNDO
3 FROM
4 V$LOGMNR_CONTENTS
5 WHERE
6 USERNAME = 'SCOTT'
7 ORDER BY
8 SCN DESC;
SCN TM_STAMP OPERATION SQL_REDO SQL_UNDO
---------- -------------------- ---------- ------------------------------------------------------------ ------------------------------------------------------------
6729463 2022/11/11 10:39:21 UPDATE update "SCOTT"."EMP" set "SAL" = '10000' where "EMPNO" = '73 update "SCOTT"."EMP" set "SAL" = '9999' where "EMPNO" = '736
69' and "SAL" = '9999' and ROWID = 'AAAWwdAAGAAAADFAAA'; 9' and "SAL" = '10000' and ROWID = 'AAAWwdAAGAAAADFAAA';
★最小サプリメンタル・ロギングではEMPNOはWHERE句に含まれていませんでしたが、SQL_REDO列のWHERE句がEMPNOとSALとROWIDに変わっていました
8. LogMiner終了
SQL> EXECUTE DBMS_LOGMNR.END_LOGMNR();
PL/SQLプロシージャが正常に完了しました。
9. 識別キー(PRIMARY KEY)サプリメンタル・ロギング削除
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
IMPLICIT YES NO NO NO
SQL> alter database drop supplemental log data (primary key) columns;
データベースが変更されました。
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
NO NO NO NO NO
③識別キー(FOREIGN KEY)サプリメンタル・ロギング
ロギングレベルを識別キー(FOREIGN KEY)サプリメンタル・ロギングにした場合、REDOログファイルに出力される内容を検証します
【検証手順】
1. 識別キー(FOREIGN KEY)サプリメンタル・ロギング設定
2. 分析対象のREDOログファイル特定
3. LogMinerディクショナリ・ファイル作成
4. 分析対象のREDOログファイル追加
5. LogMiner起動
6. テストデータ更新
7. 分析
8. LogMiner終了
9. 識別キー(FOREIGN KEY)サプリメンタル・ロギング削除
【作業ログ】
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
NO NO NO NO NO
SQL> alter database add supplemental log data (foreign key) columns;
データベースが変更されました。
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
IMPLICIT NO NO YES NO
2. 分析対象のREDOログファイル特定
SQL> select
2 l.GROUP#, l.THREAD#, l.SEQUENCE#, l.STATUS, lf.MEMBER
3 from
4 v$log l, v$logfile lf
5 where
6 l.GROUP# = lf.GROUP#
7 order by
8 l.GROUP#, l.THREAD#;
GROUP# THREAD# SEQUENCE# STATUS MEMBER
---------- ---------- ---------- --------------- ----------------------------------------
1 1 43 INACTIVE +DATA/ORCL/ONLINELOG/redo01.log
2 1 44 CURRENT +DATA/ORCL/ONLINELOG/redo02.log
3 2 39 CURRENT +DATA/ORCL/ONLINELOG/redo03.log
4 2 38 INACTIVE +DATA/ORCL/ONLINELOG/redo04.log
3. LogMinerディクショナリ・ファイル作成
本検証ではオンライン・カタログを使用するため、LogMinerディクショナリ・ファイル作成は割愛します
4. 分析対象のREDOログファイル追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo02.log', OPTIONS => DBMS_LOGMNR.NEW);
PL/SQLプロシージャが正常に完了しました。
★RACなのでスレッド2の方も追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo03.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
★ログスイッチ等でREDOログファイルが切り替わっても対応できるよう、CURRENT以外のREDOログ・ファイルも追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo01.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo04.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
5. LogMiner起動
SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR(Options => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY);
PL/SQLプロシージャが正常に完了しました。
6. テストデータ更新(別セッション)
別TeraTermを立ち上げ、別セッションでテストデータを更新します
外部キー制約(DEPTNO列)がある列の値を更新してみます
SQL> select * from emp where EMPNO = 7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 10000 20
SQL> update emp set DEPTNO = 10 where EMPNO = 7369;
1行が更新されました。
SQL> commit;
コミットが完了しました。
SQL> select * from emp where EMPNO = 7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 10000 10
7. 分析
SQL> SELECT
2 SCN, TO_CHAR(TIMESTAMP, 'YYYY/MM/DD HH24:MI:SS') AS TM_STAMP, OPERATION, SQL_REDO, SQL_UNDO
3 FROM
4 V$LOGMNR_CONTENTS
5 WHERE
6 USERNAME = 'SCOTT'
7 ORDER BY
8 SCN DESC;
SCN TM_STAMP OPERATION SQL_REDO SQL_UNDO
---------- -------------------- ---------- ------------------------------------------------------------ ------------------------------------------------------------
6733768 2022/11/11 11:00:45 UPDATE update "SCOTT"."EMP" set "DEPTNO" = '10' where "DEPTNO" = '2 update "SCOTT"."EMP" set "DEPTNO" = '20' where "DEPTNO" = '1
0' and ROWID = 'AAAWwdAAGAAAADFAAA'; 0' and ROWID = 'AAAWwdAAGAAAADFAAA';
★SQL_REDO列のWHERE句がEMPNOではなく、DEPTNOとROWIDに変わっていました
8. LogMiner終了
SQL> EXECUTE DBMS_LOGMNR.END_LOGMNR();
PL/SQLプロシージャが正常に完了しました。
9. 識別キー(FOREIGN KEY)サプリメンタル・ロギング削除
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
IMPLICIT NO NO YES NO
SQL> alter database drop supplemental log data (foreign key) columns;
データベースが変更されました。
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
NO NO NO NO NO
④識別キー(ALL)サプリメンタル・ロギング
ロギングレベルを識別キー(ALL)サプリメンタル・ロギングにした場合、REDOログファイルに出力される内容を検証します
【検証手順】
1. 識別キー(ALL)サプリメンタル・ロギング設定
2. 分析対象のREDOログファイル特定
3. LogMinerディクショナリ・ファイル作成
4. 分析対象のREDOログファイル追加
5. LogMiner起動
6. テストデータ更新
7. 分析
8. LogMiner終了
9. 識別キー(ALL)サプリメンタル・ロギング削除
【作業ログ】
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
NO NO NO NO NO
SQL> alter database add supplemental log data (all) columns;
データベースが変更されました。
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
IMPLICIT NO NO NO YES
2. 分析対象のREDOログファイル特定
SQL> select
2 l.GROUP#, l.THREAD#, l.SEQUENCE#, l.STATUS, lf.MEMBER
3 from
4 v$log l, v$logfile lf
5 where
6 l.GROUP# = lf.GROUP#
7 order by
8 l.GROUP#, l.THREAD#;
GROUP# THREAD# SEQUENCE# STATUS MEMBER
---------- ---------- ---------- --------------- ----------------------------------------
1 1 43 INACTIVE +DATA/ORCL/ONLINELOG/redo01.log
2 1 44 CURRENT +DATA/ORCL/ONLINELOG/redo02.log
3 2 39 CURRENT +DATA/ORCL/ONLINELOG/redo03.log
4 2 38 INACTIVE +DATA/ORCL/ONLINELOG/redo04.log
3. LogMinerディクショナリ・ファイル作成
本検証ではオンライン・カタログを使用するため、LogMinerディクショナリ・ファイル作成は割愛します
4. 分析対象のREDOログファイル追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo02.log', OPTIONS => DBMS_LOGMNR.NEW);
PL/SQLプロシージャが正常に完了しました。
★RACなのでスレッド2の方も追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo03.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
★ログスイッチ等でREDOログファイルが切り替わっても対応できるよう、CURRENT以外のREDOログ・ファイルも追加
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo01.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '+DATA/ORCL/ONLINELOG/redo04.log', OPTIONS => DBMS_LOGMNR.ADDFILE);
PL/SQLプロシージャが正常に完了しました。
5. LogMiner起動
SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR(Options => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG + DBMS_LOGMNR.COMMITTED_DATA_ONLY);
PL/SQLプロシージャが正常に完了しました。
6. テストデータ更新(別セッション)
別TeraTermを立ち上げ、別セッションでテストデータを更新します
SQL> select * from emp where EMPNO = 7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 10000 10
SQL> update emp set SAL = 800 where EMPNO = 7369;
1行が更新されました。
SQL> commit;
コミットが完了しました。
SQL> select * from emp where EMPNO = 7369;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- ---------- ---------- -------- ---------- ---------- ----------
7369 SMITH CLERK 7902 80-12-17 800 10
7. 分析
SQL> SELECT
2 SCN, TO_CHAR(TIMESTAMP, 'YYYY/MM/DD HH24:MI:SS') AS TM_STAMP, OPERATION, SQL_REDO, SQL_UNDO
3 FROM
4 V$LOGMNR_CONTENTS
5 WHERE
6 USERNAME = 'SCOTT'
7 ORDER BY
8 SCN DESC;
SCN TM_STAMP OPERATION SQL_REDO SQL_UNDO
---------- -------------------- ---------- ------------------------------------------------------------ ------------------------------------------------------------
6736256 2022/11/11 11:11:53 UPDATE update "SCOTT"."EMP" set "SAL" = '800' where "EMPNO" = '7369 update "SCOTT"."EMP" set "SAL" = '10000' where "EMPNO" = '73
' and "ENAME" = 'SMITH' and "JOB" = 'CLERK' and "MGR" = '790 69' and "ENAME" = 'SMITH' and "JOB" = 'CLERK' and "MGR" = '7
2' and "HIREDATE" = TO_DATE('80-12-17', 'RR-MM-DD') and "SAL 902' and "HIREDATE" = TO_DATE('80-12-17', 'RR-MM-DD') and "S
" = '10000' and "COMM" IS NULL and "DEPTNO" = '10' and ROWID AL" = '800' and "COMM" IS NULL and "DEPTNO" = '10' and ROWID
= 'AAAWwdAAGAAAADFAAA'; = 'AAAWwdAAGAAAADFAAA';
★SQL_REDO列のWHERE句がEMP表のすべての列とROWIDに変わっていました
8. LogMiner終了
SQL> EXECUTE DBMS_LOGMNR.END_LOGMNR();
PL/SQLプロシージャが正常に完了しました。
9. 識別キー(ALL)サプリメンタル・ロギング削除
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
IMPLICIT NO NO NO YES
SQL> alter database drop supplemental log data (all) columns;
データベースが変更されました。
SQL> select supplemental_log_data_min, supplemental_log_data_pk, supplemental_log_data_ui, supplemental_log_data_fk, supplemental_log_data_all from v$database;
SUPPLEMENTAL_LOG_DATA_MIN SUPPLEMENTAL_LOG_DATA_PK SUPPLEMENTAL_LOG_DATA_UI SUPPLEMENTAL_LOG_DATA_FK SUPPLEMENTAL_LOG_DATA_ALL
------------------------- ------------------------- ------------------------- ------------------------- -------------------------
NO NO NO NO NO
■参考資料
使用例1: LogMinerを使用した特定のユーザーによる変更の追跡
LogMinerディクショナリ・オプション
DBMS_LOGMNR
データベース・レベルのサプリメンタル・ロギング