您好,登錄后才能下訂單哦!
LogMiner是Oracle數據庫提供的一個工具,它用于分析重做日志和歸檔日志所記載的事務操作。
Logminer是oracle從8i開始提供的用于分析重做日志信息的工具,它包括DBMS_LOGMNR和DBMS_LOGMNR_D兩個package。它既能分析redo log file,也能分析歸檔后的archive log file。在分析日志的過程中需要使用數據字典,一般先生成數據字典文件后使用,10g版本還可以使用在線數據字典。
Logminer也可以分析其它數據庫的重做日志文件,但是必須使用重做日志所在數據庫的數據字典,否則會出現無法識別的亂碼。另外被分析數據庫的操作系統平臺最好和當前Logminer所在數據庫的運行平臺一樣,且block size相同。
LogMiner的功能
1)確定數據庫的邏輯損壞時間
通過LogMiner可以準確定位該誤操作的執行時間和SCN值,然后通過基于時間恢復或者基于SCN恢復可以完全恢復該表數據。
SQL> select scn_to_timestamp(2599788) from dual;
scn_to_timestamp(2599788)
-------------------
2016-05-01 06:06:01
SQL>select timestamp_to_scn(to_timestamp('2016-5-1 6:06:06','yyyy-mm-dd hh34:mi:ss')) FROM dual;
TIMESTAMP_TO_SCN(TO_TIMESTAMP('2016-5-16:06:06','YYYY-MM-DDHH24:MI:SS'))
------------------------------------------------------------------------
2599788
2)確定事務級要執行的精細邏輯恢復操作
通過LogMiner可以取得任何用戶的DML操作及相應的UNDO操作,通過執行UNDO操作可以取消用戶的錯誤操作。
3)執行后續審計
通過LogMiner可以跟蹤Oracle數據庫的所有DML、DDL和DCL操作,從而取得執行這些操作的時間順序、執行這些操作的用戶等信息。
追加日志
重做日志用于實現例程恢復和介質恢復,這些操作所需要的數據被自動記錄在重做日志中。但是,重做應用可能還需要記載其他列信息到重做日志中,記錄其他列的日志過程被稱為追加日志。
默認情況下,Oracle數據庫沒有開啟追加日志,從而導致默認情況下LogMiner無法支持以下特征:
1)索引簇、鏈行和遷移行;
2)直接路徑插入;
3)摘取LogMiner字典到重做日志;
4)跟蹤DDL;
5)生成鍵列的SQL_REDO和SQL_UNDO信息;
6)LONG和LOB數據類型。
----如何修改追加日志數據模式:
SYS@test> select supplemental_log_data_min from v$database;
SUPPLEME
--------
NO
SYS@test> alter database add supplemental log data;
Database altered.
SYS@test> select supplemental_log_data_min from v$database;
SUPPLEME
--------
YES
----關閉追加日志
SYS@test> alter database drop supplemental log data;
Database altered.
SYS@test> select supplemental_log_data_min from v$database;
SUPPLEME
--------
NO
SYS@test> create user shall identified by shall;
User created.
SYS@test> grant connect,resource to shall;
Grant succeeded.
SHALL@test> create table test(id number,name varchar2(20));
Table created.
SHALL@test> begin
2 for i in 1..100000 loop
3 insert into test values(i,'zhong');
4 end loop;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed.
SHALL@test> select count(*) from test;
COUNT(*)
----------
100000
SHALL@test> select * from test where id = 999;
ID NAME
---------- --------------------
999 zhong
SHALL@test> delete test;
100000 rows deleted.
SHALL@test> commit;
Commit complete.
SHALL@test> select * from test;
no rows selected
SYS@test> select supplemental_log_data_min from v$database;
SUPPLEME
--------
NO
SYS@test> select member from v$logfile;
MEMBER
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/orcl/redo01_1.log
/u01/app/oracle/oradata/orcl/redo02_1.log
/u01/app/oracle/oradata/orcl/redo03_1.log
SYS@test> exec dbms_logmnr.add_logfile ('/u01/app/oracle/oradata/orcl/redo01_1.log');
PL/SQL procedure successfully completed.
SYS@test> exec dbms_logmnr.add_logfile ('/u01/app/oracle/oradata/orcl/redo02_1.log');
PL/SQL procedure successfully completed.
SYS@test> exec dbms_logmnr.add_logfile ('/u01/app/oracle/oradata/orcl/redo03_1.log');
PL/SQL procedure successfully completed.
----如果剛做了誤操作,日志未切換,可以只添加當前redo
SYS@test> select group#,status from v$log;
GROUP# STATUS
---------- ----------------
1 INACTIVE
2 INACTIVE
3 CURRENT
SYS@test> col member for a50
SYS@test> select group#,member,type from v$logfile;
GROUP# MEMBER TYPE
---------- -------------------------------------------------- -------
1 /u01/app/oracle/oradata/orcl/redo01_1.log ONLINE
2 /u01/app/oracle/oradata/orcl/redo02_1.log ONLINE
3 /u01/app/oracle/oradata/orcl/redo03_1.log ONLINE
SYS@test> exec dbms_logmnr.start_logmnr(options=>dbms_logmnr.dict_from_online_catalog);
PL/SQL procedure successfully completed.
SYS@test> select sql_redo from v$logmnr_contents where lower(sql_redo) like '%delete%' and seg_name='TEST';
redo數據如下:
SQL_REDO
--------------------------------------------------------------------------------
delete from "SHALL"."TEST" where "ID" = '42016' and "NAME" = 'zhong' and ROWID =
'AAAWGEAAEAAAOSfABL';
delete from "SHALL"."TEST" where "ID" = '42017' and "NAME" = 'zhong' and ROWID =
'AAAWGEAAEAAAOSfABM';
delete from "SHALL"."TEST" where "ID" = '42018' and "NAME" = 'zhong' and ROWID =
'AAAWGEAAEAAAOSfABN';
delete from "SHALL"."TEST" where "ID" = '42019' and "NAME" = 'zhong' and ROWID =
undo數據如下:
SYS@test> select sql_redo from v$logmnr_contents where lower(sql_undo) like '%delete%' and seg_name='TEST';
SQL_REDO
--------------------------------------------------------------------------------
insert into "SHALL"."TEST"("ID","NAME") values ('5039','zhong');
insert into "SHALL"."TEST"("ID","NAME") values ('5040','zhong');
insert into "SHALL"."TEST"("ID","NAME") values ('5041','zhong');
insert into "SHALL"."TEST"("ID","NAME") values ('5042','zhong');
insert into "SHALL"."TEST"("ID","NAME") values ('5043','zhong');
insert into "SHALL"."TEST"("ID","NAME") values ('5044','zhong');
insert into "SHALL"."TEST"("ID","NAME") values ('5045','zhong');
insert into "SHALL"."TEST"("ID","NAME") values ('5046','zhong');
SYS@test> set linesize 200
SYS@test> set pagesize 10000
SYS@test> create table shall as select sql_redo from v$logmnr_contents where lower(sql_undo) like '%delete%' and seg_name='TEST';
SYS@test> select * from shall;
SYS@test> EXECUTE DBMS_LOGMNR.END_LOGMNR;
PL/SQL procedure successfully completed.
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。