logminerの使い方(Oracleの変更履歴を見る方法)

簡単に、Oracleの変更履歴をおさらいしてみる。

    • SQLで変更された場合、変更内容はredoログに書き込まれる
    • redoログは複数ファイルで構成されており、いっぱいになったら、次のファイルに書き込まれる、これは循環する

redoログは状態を持っており、以下で調べられる

select * from v$log

状態は、

status 意味
CURRENT 現在書き込み中のファイル
ACTIVE 次にcheckpointが来たらデータ書き込みされる状態のファイル
INACTIVE 現在何もしていない状態のファイル
    • 次のredoログファイルに移った時、前に書かれた内容は上書きで消される(NOARCHIVELOGモード)か、アーカイブログとして出力される(ARCHIVELOGモード)

動作モードはこうやって確認

select log_mode from v$database;

なので、非一貫性バックアップなどに使える

大事な事なので2回言いました。

    • 変更履歴を見たい時は、redoログを見ればイイ

でも、redoログやアーカイブログはバイナリファイルだからそのまま開いても見れない

    • redoログやアーカイブログを見たい場合は、logminerを使う
    • 普通のredoログはじつは見えない

LogMinerで分析するログ・ファイルを生成するには、その前にサプリメンタル・ロギングを有効にする必要があります。先に言えよ。

-- 有効化
alter database add supplemental log data;
-- 確認方法(yes か、impliciteが返ると有効)
select supplemental_log_data_min from v$database;

必要なもの
・inactive状態(?)で、supplemental logが有効なredoログ(か、アーカイブログ)
・オブジェクト一覧のIDと名前を記録したディクショナリ情報
(フラットファイルか、redoログに直接書きこむか、DB内のデータディクショナリを使うか3択)

    • 簡単な使い方

ディクショナリを用意する、これはフラットファイルに出力する例、マニュアルをよく見るとわかるが、この方法をOracleは推奨していない。

SQL> exec sys.DBMS_LOGMNR_D.BUILD( -
  DICTIONARY_FILE_NAME => 'dict.ora' , -
  DICTIONARY_LOCATION  => 'c:\output\', - 
  OPTIONS => SYS.DBMS_LOGMNR_D.STORE_IN_FLAT_FILE
);

※DICTIONARY_LOCATIONは、実はUTL_FILE_DIRで指定したところにしか出せない。これが、デフォルトだと「設定されたない」かつ、設定するにはデータベースの再起動が必要(10gでは、11gも同じだと思う)なので、注意。
調査したいredoログ(またはアーカイブログ)を設定

SQL> exec sys.DBMS_LOGMNR.ADD_LOGFILE( -
  LOGFILE => 'c:\logfile\redo3.log' , -
  OPTIONS => SYS.DBMS_LOGMNR.NEW
);

logminerの開始
これは、コミットされたトランザクションのみを出力する(ディクショナリにフラットファイルを使用する)例

SQL> exec sys.DBMS_LOGMNR.START_LOGMNR( -
  OPTIONS => COMMITTED_DATA_ONLY , -
  DICTFILENAME => 'c:\output\dict.ora'
);

redoログの中身を調べる
v$logmnr_contentsの中に読める形で入っているので、selectする

select scn, timestamp, sql_redo
  from v$logmnr_contents
 where sql_redo like '%update XXXX%' -- 探したい条件

logminerの終了
終了する。

SQL> sys.DBMS_LOGMNR.END_LOGMNR();

基本的な使い方は、このとおりで、後はマニュアルを見ればわかると思う。
敷居が高いと思っていたが、一度やってみると、思ったほど難しいとは思いませんでした、というか、食わず嫌いしていました。