読者です 読者をやめる 読者になる 読者になる

kenken0807_DBメモ

つば九郎が好きなDBAです。Oracle Standard Editionでの運用やツールとかとかの備忘録。特に記載がない場合はoracle11gR2です。時々MySQL

Oracle オンラインREDOログとアーカイブログの解析ツール

前回記述したブログを元に解析ツールを作成した。

kenken0807.hatenablog.com

Oracle-ArchiveLog-Analyzer

github.com

MySQLmysqlbinlogのような感じでLogMinerを使用してトランザクションごとにコミット順にテキストフォーマットで表示する。

インストール

perlスクリプトなのでDBD::Oracleをいれる
cpanm DBD::Oracle
git clone https://github.com/kenken0807/Oracle-ArchiveLog-Analyzer.git

使用方法

  • オプション情報
$ perl Oracle-ArchiveLog-Analyzer.pl
Usage: perl Oracle-ArchiveLog-Analyzer.pl [options] log-files

Options:
  --start-position [SCN] Start reading REDO log at SCN. (START_SCN >= #)
  --stop-position  [SCN] Stop reading REDO log at SCN.  (COMMIT_SCN <= #)
  --start-datetime ['YYYY/MM/DD HH24:MI:SS'] Start reading REDO log at first event having a datetime equal. (START_TIMESTAMP  >= 'YYYY/MM/DD HH24:MI:SS')
  --stop-datetime  ['YYYY/MM/DD HH24:MI:SS'] Stop reading REDO log at first event having a datetime equal. (COMMIT_TIMESTAMP <= 'YYYY/MM/DD HH24:MI:SS')
  --select Show EXPLAIN SELECT STATEMENTS
  --table [TABLENAME] To extract transactions the table has been used (ex."'USER_MASTER','CODE_MASTER'")
Connect Options:
  --host hostname [default localhost]
  --port port [default 1521]
  --sid  sid [default orcl]
  --user user must be 'system' [default system]
  --pass password
  --checkuser FORMAT is "'username','username'...." (ex. --checkuser "'ORCLUSER','ORA'")
Detail:
  Set log-files(archivelog or online redolog) at Current Dir or Fullpath

--start-position・・トランザクションが開始したSCNを起点
--stop-position・・トランザクションがコミットしたSCNを終点
--start-datetime・・トランザクションが開始した時間を起点
--stop-datetime・・トランザクションがコミットした時間を終点
--checkuser・・表示させたいトランザクションを実行したユーザ名を指定する
--table・・指定するとそのテーブルに対して実行された更新のみ取得

--user・・接続するユーザ名を選択(デフォルトsystem)
別ユーザで実行する場合は以下権限を付与すれば可能

GRANT SELECT ANY TRANSACTION to orauser;
GRANT EXECUTE_CATALOG_ROLE to orauser;
GRANT SELECT ON _v$LOGMNR_CONTENTS to orauser;
  • 実行する
    • 2016/02/18 14:41:27~2016/02/18 15:05:00間でORAUSERスキーマが実行した更新処理を表示する
$ perl Oracle-ArchiveLog-Analyzer.pl  --sid orcl --pass xxxx \ 
                                      --checkuser "'ORAUSER'" \
                                      --start-datetime '2016/02/18 14:41:27' \ 
                                      --stop-datetime '2016/02/18 15:05:00'  \
                                      /opt/app/oracle/online-redo/redo02.log

-- START_TIME: 2016/02/18 14:41:27    COMMIT_TIME: 2016/02/18 14:41:42
-- START_SCN: 47902287496      COMMIT_SCN: 47902287503
-- TRANSACTION ID: 09000700172A0600
set transaction read write;
update "ORAUSER"."TT" set "ID2" = '999' where "ID2" = '666';
commit;


-- START_TIME: 2016/02/18 15:04:43    COMMIT_TIME: 2016/02/18 15:04:43
-- START_SCN: 47902288848      COMMIT_SCN: 47902288878
-- TRANSACTION ID: 0A00120003D60B00
create table TEST (id int primary key);


-- START_TIME: 2016/02/18 15:04:53    COMMIT_TIME: 2016/02/18 15:04:53
-- START_SCN: 47902288882      COMMIT_SCN: 47902288883
-- TRANSACTION ID: 0A0006000FD70B00
set transaction read write;
insert into "ORAUSER"."TEST"("ID") values ('999');
commit;


-- START_TIME: 2016/02/18 15:05:00    COMMIT_TIME: 2016/02/18 15:05:00
-- START_SCN: 47902288895      COMMIT_SCN: 47902288924
-- TRANSACTION ID: 0700070050CD0700
truncate table TEST;
  • --select をつけると実行されたDML文をSELECT文に書き換えて表示
$ perl Oracle-ArchiveLog-Analyzer.pl  --sid orcl --pass xxxx \
                                      --checkuser "'ORAUSER'"  \
                                      --start-datetime '2016/02/18 14:41:27' \ 
                                      --stop-datetime '2016/02/18 15:04:53'  \
                                      --select /opt/app/oracle/online-redo/redo02.log  

-- START_TIME: 2016/02/18 14:41:27    COMMIT_TIME: 2016/02/18 14:41:42
-- START_SCN: 47902287496      COMMIT_SCN: 47902287503
-- TRANSACTION ID: 09000700172A0600
set transaction read write;
update "ORAUSER"."TT" set "ID2" = '999' where "ID2" = '666';
commit;

-- EXPLAIN SELECT:
-- select count(*) from "ORAUSER"."TT" where "ID2" = '666';


-- START_TIME: 2016/02/18 15:04:43    COMMIT_TIME: 2016/02/18 15:04:43
-- START_SCN: 47902288848      COMMIT_SCN: 47902288878
-- TRANSACTION ID: 0A00120003D60B00
create table TEST (id int primary key);


-- START_TIME: 2016/02/18 15:04:53    COMMIT_TIME: 2016/02/18 15:04:53
-- START_SCN: 47902288882      COMMIT_SCN: 47902288883
-- TRANSACTION ID: 0A0006000FD70B00
set transaction read write;
insert into "ORAUSER"."TEST"("ID") values ('999');
commit;

-- EXPLAIN SELECT:
-- select count(*) from "ORAUSER"."TEST" where "ID" = '999' ;
  • 実行されたSQL文ではなく変更があった行をLogMinerの機能でSQL文に書き換えた表示となる
    ・ 実際に実行されたSQL
SQL>delete from tt;
10行が削除されました。
SQL>commit;

・ 表示されるもの

-- START_TIME: 2016/02/23 17:25:57    COMMIT_TIME: 2016/02/23 17:25:57
-- START_SCN: 47902717945      COMMIT_SCN: 47902717954
-- TRANSACTION ID: 0A001E002FDC0B00
set transaction read write;
delete from "ORAUSER"."TT" where "ID" = '1' and "ID2" = '1';
delete from "ORAUSER"."TT" where "ID" = '2' and "ID2" = '2';
delete from "ORAUSER"."TT" where "ID" = '3' and "ID2" = '3';
delete from "ORAUSER"."TT" where "ID" = '4' and "ID2" = '4';
delete from "ORAUSER"."TT" where "ID" = '5' and "ID2" = '5';
delete from "ORAUSER"."TT" where "ID" = '6' and "ID2" = '6';
delete from "ORAUSER"."TT" where "ID" = '7' and "ID2" = '7';
delete from "ORAUSER"."TT" where "ID" = '8' and "ID2" = '8';
delete from "ORAUSER"."TT" where "ID" = '9' and "ID2" = '9';
delete from "ORAUSER"."TT" where "ID" = '10' and "ID2" = '10';
commit;

これで調査するのには捗りそう。
これで独自のレプリケーション機能でも作ろうかな。と思ったけどOracleにはMviewやらいろんな機能が多くてそこは加味してないので。。