Oracle 11g logminer解析redo日誌
下面的示例是分析線上redo日誌,分析歸檔redo日誌過程也是如此。Toad 裡面也集成了logminer的功能。
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE 11.2.0.4.0 Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
1. 用sys賬號建立一個logminer的使用者,授予sysdba的許可權
create user LOGMINER
identified by "LOGMINER"
default tablespace LCAM_PUB_TBS --表空間依據當前資料庫的情況而定
temporary tablespace TEMP
profile DEFAULT;
grant connect to LOGMINER;
grant resource to LOGMINER;
grant sysdba to LOGMINER;
2. 用logminer使用者執行兩個Oracle指令碼,生成一些logminer的package,確保資料庫開啟輔助日誌
SQL> @F:\app\Administrator\product\11.2.0\dbhome_1\RDBMS\ADMIN\dbmslm.sql
SQL> @F:\app\Administrator\product\11.2.0\dbhome_1\RDBMS\ADMIN\dbmslmd.sql
SQL> select SUPPLEMENTAL_LOG_DATA_MIN from v$database;
SUPPLEME
--------
NO
SQL> alter database add supplemental log data;
SQL> select SUPPLEMENTAL_LOG_DATA_MIN from v$database;
SUPPLEME
--------
YES
3. 用logminer使用者設定utl_file_dir,並且確定有這個目錄存在,有必要建一下資料夾LOGMNR
alter system set utl_file_dir='/oracle/oradata/oradb11/LOGMNR' scope=spfile;
4. 檢視歸檔redo組
Status為current為當前啟用的線上日誌,為了試驗簡潔,我只分析當前的日誌。
SQL> select l.STATUS,s.MEMBER from v$log l,v$logfile s where l.GROUP# = s.GROUP#;
STATUS MEMBER
---------------- --------------------------------------------------
INACTIVE /oracle/oradata/oradb11/redo04.log
CURRENT /oracle/oradata/oradb11/redo05.log
INACTIVE /oracle/oradata/oradb11/redo06.log
5. 在L_PUB上執行測試場景的指令碼(自行找測試使用者)
記錄操作開始時間和結束時間。
select sysdate from dual;--2017/3/6 11:00:19
create table test(id number ,name varchar2(100));
insert into test values(1,'張三');
insert into test values(2,'李四');
commit;
insert into test values(3,'王五');
rollback;
insert into test values(4,'趙六');
insert into test values(5,'馮七');
insert into test values(6,'劉八');
insert into test values(7,'廖九');
commit;
update test set name='劉八八' where id=6;
commit;
delete from test where id=7;
rollback;
delete from test where id=1;
commit;
select sysdate from dual;--2017/3/6 11:02:05
6. 用logminer使用者生成資料字典,需要保證dictionary_location所指定的目錄存在
execute dbms_logmnr_d.build(dictionary_filename =>'dictionary.ora',dictionary_location =>'/oracle/oradata/oradb11/LOGMNR');
7. 用logminer使用者新增分析的redo日誌
第一個日誌options=>dbms_logmnr.new,後面的options=>dbms_logmnr.addfile。
exec dbms_logmnr.add_logfile(logfilename=>'/oracle/oradata/oradb11/redo05.log',options=>dbms_logmnr.new);
dbms_logmnr.add_logfile(logfilename=>'/oracle/oradata/oradb11/redo06.log',options=>dbms_logmnr.addfile);
execute dbms_logmnr.add_logfile(logfilename=>'/oracle/oradata/oradb11/redo06.log',options=>dbms_logmnr.addfile);
8. 用logminer使用者啟動logminer
啟動的方式有多種:
全分析,execute dbms_logmnr.start_logmnr(DictFileName=>'/oracle/oradata/oradb11/LOGMNR/dictionary.ora');
按時間段來分析,execute dbms_logmnr.start_logmnr(startTime => to_date('2017-03-06 11:00:18','yyyy-mm-dd hh24:mi:ss'),endTime => to_date('2017-03-06 11:02:06','yyyy-mm-dd hh24:mi:ss'),DictFileName => '/oracle/oradata/oradb11/LOGMNR/dictionary.ora');
9. 用logminer使用者logminer分析處理的結果只有本session能看到,可以先用表把資料記錄然後分析
Drop table logminer_t purge;
Create table logminer_t as select * from V$LOGMNR_CONTENTS;
10. 用logminer使用者分析後釋放記憶體
execute dbms_logmnr.end_logmnr;
11. 用logminer使用者可以慢慢分析
Select S.SCN,
s.start_scn,
S.COMMIT_SCN,
S.TIMESTAMP,
s.START_TIMESTAMP,
S.COMMIT_TIMESTAMP,
S.OPERATION,
S.ROLLBACK,
S.SEG_OWNER,
S.SEG_NAME,
S.TABLE_NAME,
S.TABLE_SPACE,
S.SQL_REDO,
S.SQL_UNDO
From logminer_t s
where s.SEG_OWNER = 'L_PUB'
and s.table_name = 'TEST'
order by scn;
我們可以捕獲到執行的SQL:
以下是提交事務的SQL,同步的時候可以用到:
with co_scn as(
select start_scn,commit_scn
from logminer_t s
where s.start_scn is not null
and s.commit_scn is not null),
operate_scn as(
Select scn,s.sql_redo From logminer_t s
where s.SEG_OWNER = 'L_PUB'
and s.table_name = 'TEST'
)
Select scn,sql_redo
From operate_scn s, co_scn co
where s.scn >= co.start_scn
and s.scn <= co.commit_scn;
以下是回滾的SQL,同步時可以忽略:
select S.SCN,
S.TIMESTAMP,
S.OPERATION,
S.ROLLBACK,
S.SEG_OWNER,
S.SEG_NAME,
S.TABLE_NAME,
S.SQL_REDO from logminer_t s where pxid in
(select pxid from logminer_t where rollback=1 and SEG_OWNER = 'LCAM_PUB')
order by scn;