1. dict_from_online_catalog mode
dict_from_online_catalog具体操作又分为两种:分析online redo logfile,分析archived logfile.
1.1 分析online redo logfile
准备数据
建表
create table test_logmnr (
id number(5),
name varchar2(20)
);
插值
insert into test_logmnr values (222,'test2');
1.1.1 将redo log 添加到logminer中,注意第一次添加要用
dbms_logmnr.new
SQL> execute dbms_logmnr.add_logfile(LOGFILENAME =>'/oracle/oradata/monster/redo01.log', OPTIONS =>dbms_logmnr.new);
PL/SQL procedure successfully completed.
这里需要说明的是,不一定三个online redo log都加,这里只是个例子,按照需要添加即可
添加redo02.log, 这会就是
dbms_logmnr.addfile了
SQL> execute dbms_logmnr.add_logfile(LOGFILENAME =>'/oracle/oradata/monster/redo02.log', OPTIONS =>dbms_logmnr.addfile);
PL/SQL procedure successfully completed.
添加redo03.log
SQL> execute dbms_logmnr.add_logfile(LOGFILENAME =>'/oracle/oradata/monster/redo03.log', OPTIONS =>dbms_logmnr.addfile);
PL/SQL procedure successfully completed.
1.1.2 开始分析
SQL> execute DBMS_LOGMNR.START_LOGMNR(OPTIONS => dbms_logmnr.dict_from_online_catalog);
PL/SQL procedure successfully completed.
1.1.3 从v$logmnr_contents中查找SQL_REDO和SQL_UNDO
SQL> select TIMESTAMP, SQL_REDO, SQL_UNDO from v$logmnr_contents where USERNAME = 'SCOTT';
TIMESTAMP
-------------------
SQL_REDO
--------------------------------------------------------------------------------
SQL_UNDO
--------------------------------------------------------------------------------
2010/07/15 00:34:31
set transaction read write;
2010/07/15 00:34:31
insert into "SCOTT"."TEST_LOGMNR"("ID","NAME") values ('222','test2');
delete from "SCOTT"."TEST_LOGMNR" where "ID" = '222' and "NAME" = 'test2' and RO
WID = 'AAANymAAEAAAAb0AAC';
2010/07/15 00:34:39
commit;
1.2 分析archived log
1.2.1 存档redo log, 当然前提是数据库处于archive log mod
e
SQL> alter system switch logfile;
也可以用:
SQL> alter system archive log current;
Insert data to test table
insert into test_logmnr values (333,'test3');
1.2.2 确认刚刚生成的archived log , 并确认一下时间,以分辨数据
[oracle@rac02 oracle]$ cd oradata/monster/archive/
[oracle@rac02 archive]$ ls -ltr | tail -2
-rw-r----- 1 oracle oinstall 52027904 Jul 14 22:00 1_433_704572097.arc
-rw-r----- 1 oracle oinstall 16630784 Jul 15 01:56
1_434_704572097.arc
[oracle@rac02 archive]$ date
Thu Jul 15 01:58:13 JST 2010
1.2.3 将archive log添加到logminer
SQL> execute dbms_logmnr.add_logfile(LOGFILENAME =>'/oracle/oradata/monster/archive/
1_434_704572097.arc ', OPTIONS =>dbms_logmnr.new);
PL/SQL procedure successfully completed.
1.2.4 开始分析
SQL> execute DBMS_LOGMNR.START_LOGMNR(OPTIONS => dbms_logmnr.dict_from_online_catalog);
PL/SQL procedure successfully completed.
1.2.5 从v$logmnr_contents中查找SQL_REDO和SQL_UNDO(多余的数据就省掉了)
SQL> select TIMESTAMP, SQL_REDO, SQL_UNDO from v$logmnr_contents where USERNAME = 'SCOTT';
TIMESTAMP
-------------------
SQL_REDO
--------------------------------------------------------------------------------
SQL_UNDO
--------------------------------------------------------------------------------
2010/07/15 01:55:23
set transaction read write;
2010/07/15 01:55:23
insert into "SCOTT"."TEST_LOGMNR"("ID","NAME") values ('333','test3');
delete from "SCOTT"."TEST_LOGMNR" where "ID" = '333' and "NAME" = 'test3' and RO
WID = 'AAANymAAEAAAAb0AAD';
2010/07/15 01:55:24
commit;
2. dict_from_redo_logs mode
准备数据
插值
insert into test_logmnr values (444,'test4');
2.1 添加archived log
我觉得,这个mode比较扯,扯就扯在这个添加archived log的过程上,各位看官自己看吧
2.1.1 准备要添加的archived log
准备好archived log,这个过程会自动存档redo log,至于存档几次,那就不好说啦
SQL> execute dbms_logmnr_d.build(options=> dbms_logmnr_d.store_in_redo_logs);
PL/SQL procedure successfully completed.
由上面的过程引发的存档信息会反映到v$archived_log里,注意红色数字的间隔,按理说archived log的编号是连续的,间隔就代表生成了多个,但间隔又不固定,你说扯不扯,还望高人指点一下迷津啊!
SQL> select name from v$archived_log where dictionary_begin='YES';
NAME
------------------------------------------------------------------------------------------------------------------------
/opt/ora10g/flash_recovery_area/SINGLE/archivelog/2010_07_09/o1_mf_1_
18 _63fplys3_.arc
/opt/ora10g/flash_recovery_area/SINGLE/archivelog/2010_07_18/o1_mf_1_
24 _645vgq4d_.arc
/opt/ora10g/flash_recovery_area/SINGLE/archivelog/2010_07_18/o1_mf_1_
28 _645vyodl_.arc
/opt/ora10g/flash_recovery_area/SINGLE/archivelog/2010_07_18/o1_mf_1_
36 _645x3s23_.arc
/opt/ora10g/flash_recovery_area/SINGLE/archivelog/2010_07_18/o1_mf_1_
38 _645x8v45_.arc
/opt/ora10g/flash_recovery_area/SINGLE/archivelog/2010_07_18/o1_mf_1_
40 _645xd76w_.arc
/opt/ora10g/flash_recovery_area/SINGLE/archivelog/2010_07_18/o1_mf_1_
43 _645xw17j_.arc
/opt/ora10g/flash_recovery_area/SINGLE/archivelog/2010_07_19/o1_mf_1_
46 _646vx8m4_.arc
8 rows selected.
2.1.2 确认要添加的archived log(这次我们添加7月19日的)
SQL> !ls -ltr /opt/ora10g/flash_recovery_area/SINGLE/archivelog/2010_07_19
合計 47520
-rw-r----- 1 oracle dba 39141888 7月 19 06:18 o1_mf_1_45_646vx3lr_.arc
-rw-r----- 1 oracle dba 9451520 7月 19 06:18 o1_mf_1_46_646vx8m4_.arc
2.1.3 添加archived log到logminer
先
加o1_mf_1_46_646vx8m4_.arc
SQL> execute dbms_logmnr.add_logfile(logfilename=> '/opt/ora10g/flash_recovery_area/SINGLE/archivelog/2010_07_19/o1_mf_1_46_646vx8m4_.arc', options=> dbms_logmnr.new);
PL/SQL procedure successfully completed.
这里要注意的是,要先添加o1_mf_1_ 46 _646vx8m4_.arc(即显示在v$archived_log里的), 再添加o1_mf_1_45_646vx3lr_.arc,否则会出错。
为什么我非要多添加一个o1_mf_1_45_646vx3lr_.arc呢?因为我知道,刚刚插入的444,‘test4’数据就在这个archived log中。
再追加o1_mf_1_45_646vx3lr_.arc
SQL> execute dbms_logmnr.add_logfile(logfilename=> '/opt/ora10g/flash_recovery_area/SINGLE/archivelog/2010_07_19/o1_mf_1_45_646vx3lr_.arc', options=> dbms_logmnr.addfile);
PL/SQL procedure successfully completed.
2.1.4 开始分析
SQL> execute dbms_logmnr.start_logmnr(options=> dbms_logmnr.dict_from_redo_logs);
PL/SQL procedure successfully completed.
2.1.5 从 v$logmnr_contents中查找SQL_REDO和SQL_UNDO
SQL> select TIMESTAMP, SQL_REDO, SQL_UNDO from v$logmnr_contents where USERNAME = 'SCOTT';
TIMESTAMP
-------------------
SQL_REDO
--------------------------------------------------------------------------------
SQL_UNDO
--------------------------------------------------------------------------------
2010-07-19 06:17:35
insert into "SCOTT"."TEST_LOGMNR"("ID","NAME") values ('444','test4');
delete from "SCOTT"."TEST_LOGMNR" where "ID" = '444' and "NAME" = 'test4' and RO
WID = 'AAAM6eAAEAAADo8AAF';
2010-07-19 06:17:35
commit;
3. Dictory mode
Dictory mode的优点是可以分析其他DB或是Instance的log. 只要你有那个目标库的数据字典 XXXX.ora文件。缺点就是你必须要有这个 XXXX.ora文件
3.1 set utl_file_dir parameter
utl_file_dir一般默认为空
SQL> show parameter utl_file_dir
NAME TYPE VALUE
------------------------------------ ----------- ----------------------------
utl_file_dir string
想写scope=both => 不行, 想立即生效 => 不行, 乖乖重起DB吧
SQL> alter system set utl_file_dir = '/home/oracle/chou' scope = spfile;
System altered.
设定完后确认一下
SQL> show parameter utl_file_dir
NAME TYPE VALUE
------------------------------------ ----------- ----------------------------
utl_file_dir string /home/oracle/chou
3.2 生成XXXX.ora数据字典文件
dictionary_location必须是先前指定的utl_file_dir值
SQL> execute DBMS_LOGMNR_D.BUILD(
2 dictionary_filename => 'test_logmnr.ora',
3 dictionary_location => '/home/oracle/chou',
4 options => DBMS_LOGMNR_D.STORE_IN_FLAT_FILE);
PL/SQL procedure successfully completed.
确认XXXX.ora文件已生成,还不小呢,足有20MB啊,这只是我的test环境,生产环境那就更大了吧
[oracle@rac02 chou]$ ls -ltr /home/oracle/chou
-rw-r--r-- 1 oracle oinstall 22137597 Jun 30 19:31 test_logmnr.ora
3.3 开始logminer过程
3.3.1 分析online redo log
3.3.1.1 添加redo01.log
SQL> execute dbms_logmnr.add_logfile(LOGFILENAME =>'/oracle/oradata/monster/redo01.log', OPTIONS =>dbms_logmnr.new);
PL/SQL procedure successfully completed.
追加redo02.log
SQL> execute dbms_logmnr.add_logfile(LOGFILENAME =>'/oracle/oradata/monster/redo02.log', OPTIONS =>dbms_logmnr.addfile);
PL/SQL procedure successfully completed.
追加redo03.log
SQL> execute dbms_logmnr.add_logfile(LOGFILENAME =>'/oracle/oradata/monster/redo03.log', OPTIONS =>dbms_logmnr.addfile);
PL/SQL procedure successfully completed.
3.3.1.2 开始分析 (指定
DICTFILENAME很重要 )
SQL> execute DBMS_LOGMNR.START_LOGMNR(
DICTFILENAME => '/home/oracle/chou/test_logmnr.ora' );
PL/SQL procedure successfully completed.
3.3.1.3 从v$logmnr_contents里找SQL
SQL> select TIMESTAMP, SQL_REDO, SQL_UNDO from v$logmnr_contents where USERNAME = 'SCOTT';
TIMESTAMP
-------------------
SQL_REDO
--------------------------------------------------------------------------------
SQL_UNDO
--------------------------------------------------------------------------------
2010/07/15 00:34:31
set transaction read write;
2010/07/15 00:34:31
insert into "SCOTT"."TEST_LOGMNR"("ID","NAME") values ('222','test2');
delete from "SCOTT"."TEST_LOGMNR" where "ID" = '222' and "NAME" = 'test2' and RO
WID = 'AAANymAAEAAAAb0AAC';
2010/07/15 00:34:39
commit;
如果不指定 DICTFILENAME, 会怎样呢,下面为您呈现
开始分析
SQL> execute dbms_logmnr.start_logmnr();
PL/SQL procedure successfully completed.
查找SQL
SQL> select TIMESTAMP, SQL_REDO, SQL_UNDO from v$logmnr_contents where USERNAME = 'SCOTT';
TIMESTAMP
-------------------
SQL_REDO
--------------------------------------------------------------------------------
SQL_UNDO
--------------------------------------------------------------------------------
2010/07/15 00:34:31
set transaction read write;
2010/07/15 00:34:31
insert into "
UNKNOWN "."
OBJ# 56486 "("
COL 1 ","
COL 2 ") values (
HEXTORAW('323232'),HEXTORAW('7465737432') );
delete from "
UNKNOWN "."
OBJ# 56486 " where
"COL 1" = HEXTORAW('323232') and
"COL 2" = HEXTORAW('7465737432') and ROWID = 'AAANymAAEAAAAb0AAC';
2010/07/15 00:34:39
commit;
区别我就不说了吧
3.3.2 分析archived log
3.3.2.1 添加archived log , arc文件的位置有点怪吧,是我瞎copy的
SQL> execute DBMS_LOGMNR.ADD_LOGFILE(
2 LOGFILENAME => '/home/oracle/chou/1_419_704572097.arc',
3 OPTIONS => dbms_logmnr.new);
PL/SQL procedure successfully completed.
3.3.2.2 开始分析
SQL> execute DBMS_LOGMNR.START_LOGMNR(
2 DICTFILENAME => '/home/oracle/chou/test_logmnr.ora');
PL/SQL procedure successfully completed.
3.3.2.3 确认 v$logmnr_contents
SQL> select TIMESTAMP, SQL_REDO, SQL_UNDO from v$logmnr_contents
2 where USERNAME = 'SCOTT' and OPERATION = 'DELETE';
TIMESTAMP
-------------------
SQL_REDO
------------------------------------------------------------------------------------------------------------------------
SQL_UNDO
------------------------------------------------------------------------------------------------------------------------
2010/06/30 19:09:43
delete from "SCOTT"."TEST_LOGMNR" where "ID" = '222' and "NAME" = 'tester1' and ROWID = 'AAANymAAEAAAAb0AAB';
insert into "SCOTT"."TEST_LOGMNR"("ID","NAME") values ('222','tester1');
完了。