LogMnr-誤DML後使用logmnr對資料進行恢復

tangyunoracle發表於2012-04-25
開發人員錯誤的DML是個頭痛的問題,如果是11g可以採用LogMinor進行異機恢復。[@more@]

誤DML後使用logmnr對資料進行恢復
SQL> conn tangyun/tangyun
Connected.
SQL> select table_name from user_tables;

TABLE_NAME
------------------------------
TANGYUN_TEST
MLOG$_T_PART
T_PART
LOGMNR
LOGMNR_REDO
MV_T_PART
TANGYUN

7 rows selected.
---------建立一張測試表,這裡為了輸出結果較明顯,表記錄不要太多
SQL> create table ty_log as select * from tangyun_test where rownum<=10;

Table created.

SQL> select count(1) count# from ty_log;

COUNT#
----------
9

SQL> delete from ty_log where tid<=5;

5 rows deleted.

SQL> commit;

Commit complete.

SQL> select * from v$log;

GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------------
1 1 130 52428800 2 NO CURRENT 896827 10-7月 -11
2 1 128 52428800 1 YES INACTIVE 894997 10-7月 -11
3 1 129 52428800 1 YES INACTIVE 896123 10-7月 -11

-----切換當前日誌,如果日誌已經被歸檔,則需要分析的是歸檔日誌,不過方法一樣
SQL> alter system switch logfile;

System altered.

SQL> select * from v$log;

GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------------
1 1 130 52428800 2 YES ACTIVE 896827 10-7月 -11
2 1 131 52428800 1 NO CURRENT 897105 10-7月 -11
3 1 129 52428800 1 YES INACTIVE 896123 10-7月 -11

SQL> col member format a60
SQL> select member from v$logfile;

MEMBER
------------------------------------------------------------
+DGSYSTEM/tgyun/onlinelog/group_1.257.747535069
+DGSYSTEM/tgyun/onlinelog/group_2.258.747535071
+DGSYSTEM/tgyun/onlinelog/group_3.259.747535075
+DGSYSTEM/tgyun/onlinelog/group_1.268.754483583

SQL> begin
2 sys.dbms_logmnr.add_logfile(logfilename => '+DGSYSTEM/tgyun/onlinelog/group_1.257.747535069',options => sys.dbms_logmnr.new);
3 end;
4 /

PL/SQL procedure successfully completed.

--------使用線上字典
SQL> begin
2 sys.dbms_logmnr.start_logmnr(options =>sys.dbms_logmnr.dict_from_online_catalog);
3 end;
4 /

PL/SQL procedure successfully completed.
SQL> begin
2 sys.dbms_logmnr.end_logmnr();
3 end;
4 /
PL/SQL procedure successfully completed.
SQL> col sql_redo format a60
SQL> col sql_undo format a60
SQL> select sql_redo,sql_undo from v$logmnr_contents where table_name='TY_LOG';

SQL_REDO SQL_UNDO
------------------ -------------------------------------
create table ty_log as select * from tangyun_test where rown
um<=10;
---------------從輸出結果沒有看到任何的DML語句
------檢視SUPPLEMENTAL LOG DATA引數
SQL> SELECT SUPPLEMENTAL_LOG_DATA_MIN,SUPPLEMENTAL_LOG_DATA_PK,SUPPLEMENTAL_LOG_DATA_UI FROM V$DATABASE;

SUPPLEME SUP SUP
-------- --- ---
NO NO NO
--------10g版本預設SUPPLEMENTAL LOG DATA引數均為關閉
--------開啟SUPPLEMENTAL LOG DATA引數
SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
Database altered.
/*==============開啟和關閉最小日誌=========================================================================
SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;

Database altered.

SQL> SELECT SUPPLEMENTAL_LOG_DATA_MIN,SUPPLEMENTAL_LOG_DATA_PK,SUPPLEMENTAL_LOG_DATA_UI FROM V$DATABASE;

SUPPLEME SUP SUP
-------- --- ---
YES NO NO

SQL> alter database drop supplemental log data;

Database altered.

SQL>
SQL>
SQL> SELECT SUPPLEMENTAL_LOG_DATA_MIN,SUPPLEMENTAL_LOG_DATA_PK,SUPPLEMENTAL_LOG_DATA_UI FROM V$DATABASE;

SUPPLEME SUP SUP
-------- --- ---
NO NO NO

*/===================================================================================================
--------開啟SUPPLEMENTAL LOG DATA引數後重新做測試

SQL> drop table ty_log purge;

Table dropped.

SQL> create table tylog as select * from tangyun_test;

Table created.

SQL> select count(1) from tylog;

COUNT(1)
----------
9

SQL> delete from tylog where tid<=5;

5 rows deleted.

SQL> commit;

Commit complete.

SQL> select * from v$log;

GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------------
1 1 130 52428800 2 YES INACTIVE 896827 10-7月 -11
2 1 131 52428800 1 NO CURRENT 897105 10-7月 -11
3 1 129 52428800 1 YES INACTIVE 896123 10-7月 -11

SQL> select member from v$logfile;

MEMBER
------------------------------------------------------------
+DGSYSTEM/tgyun/onlinelog/group_1.257.747535069
+DGSYSTEM/tgyun/onlinelog/group_2.258.747535071
+DGSYSTEM/tgyun/onlinelog/group_3.259.747535075
+DGSYSTEM/tgyun/onlinelog/group_1.268.754483583

SQL> alter system switch logfile;

System altered.

SQL> select * from v$log;

GROUP# THREAD# SEQUENCE# BYTES MEMBERS ARC STATUS FIRST_CHANGE# FIRST_TIME
---------- ---------- ---------- ---------- ---------- --- ---------------- ------------- --------------
1 1 130 52428800 2 YES INACTIVE 896827 10-7月 -11
2 1 131 52428800 1 YES ACTIVE 897105 10-7月 -11
3 1 132 52428800 1 NO CURRENT 897498 10-7月 -11

SQL> col filename format a60
SQL> select filename from v$logmnr_logs;

no rows selected

SQL> begin
2 sys.dbms_logmnr.add_logfile(logfilename => '+DGSYSTEM/tgyun/onlinelog/group_2.258.747535071',options => sys.dbms_logmnr.new);
3 end;
4 /

PL/SQL procedure successfully completed.

SQL> select filename from v$logmnr_logs;

FILENAME
------------------------------------------------------------
+DGSYSTEM/tgyun/onlinelog/group_2.258.747535071

SQL> begin
2 sys.dbms_logmnr.start_logmnr(options =>sys.dbms_logmnr.dict_from_online_catalog);
3 end;
4 /

PL/SQL procedure successfully completed.


SQL> select sql_redo,sql_undo from v$logmnr_contents where table_name='TYLOG';

SQL_REDO SQL_UNDO
------------------------------------------------------------ ------------------------------------------------------------
create table tylog as select * from tangyun_test;
insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('01','T delete from "TANGYUN"."TYLOG" where "TID" = '01' and "TNAME"
ANGYUN'); = 'TANGYUN' and ROWID = 'AAANBSAAFAAAABMAAA';

insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('02','T delete from "TANGYUN"."TYLOG" where "TID" = '02' and "TNAME"
EST'); = 'TEST' and ROWID = 'AAANBSAAFAAAABMAAB';

insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('03','S delete from "TANGYUN"."TYLOG" where "TID" = '03' and "TNAME"
HXJ'); = 'SHXJ' and ROWID = 'AAANBSAAFAAAABMAAC';

insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('04','S delete from "TANGYUN"."TYLOG" where "TID" = '04' and "TNAME"

SQL_REDO SQL_UNDO
------------------------------------------------------------ ------------------------------------------------------------
HSNC'); = 'SHSNC' and ROWID = 'AAANBSAAFAAAABMAAD';

insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('05',' delete from "TANGYUN"."TYLOG" where "TID" = '05' and "TNAME"
湯雲'); = '湯雲' and ROWID = 'AAANBSAAFAAAABMAAE';

insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('06','T delete from "TANGYUN"."TYLOG" where "TID" = '06' and "TNAME"
GYUN'); = 'TGYUN' and ROWID = 'AAANBSAAFAAAABMAAF';

insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('08','t delete from "TANGYUN"."TYLOG" where "TID" = '08' and "TNAME"
est_RMAN'); = 'test_RMAN' and ROWID = 'AAANBSAAFAAAABMAAG';


SQL_REDO SQL_UNDO
------------------------------------------------------------ ------------------------------------------------------------
insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('10','r delete from "TANGYUN"."TYLOG" where "TID" = '10' and "TNAME"
man'); = 'rman' and ROWID = 'AAANBSAAFAAAABMAAH';

insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('13','R delete from "TANGYUN"."TYLOG" where "TID" = '13' and "TNAME"
MAN'); = 'RMAN' and ROWID = 'AAANBSAAFAAAABMAAI';

delete from "TANGYUN"."TYLOG" where "TID" = '01' and "TNAME" insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('01','T
= 'TANGYUN' and ROWID = 'AAANBSAAFAAAABMAAA'; ANGYUN');

delete from "TANGYUN"."TYLOG" where "TID" = '02' and "TNAME" insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('02','T
= 'TEST' and ROWID = 'AAANBSAAFAAAABMAAB'; EST');

SQL_REDO SQL_UNDO
------------------------------------------------------------ ------------------------------------------------------------

delete from "TANGYUN"."TYLOG" where "TID" = '03' and "TNAME" insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('03','S
= 'SHXJ' and ROWID = 'AAANBSAAFAAAABMAAC'; HXJ');

delete from "TANGYUN"."TYLOG" where "TID" = '04' and "TNAME" insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('04','S
= 'SHSNC' and ROWID = 'AAANBSAAFAAAABMAAD'; HSNC');

delete from "TANGYUN"."TYLOG" where "TID" = '05' and "TNAME" insert into "TANGYUN"."TYLOG"("TID","TNAME") values ('05','
= '湯雲' and ROWID = 'AAANBSAAFAAAABMAAE'; 湯雲');


15 rows selected.


-------這裡如果資料量很大的情況下我們可以把分析結果存放在另外一張表中進行處理

SQL> create table ty_undo as select replace(sql_undo,'"','') sql_undo from v$logmnr_contents where table_name='TYLOG' and lower(sql_undo) like 'insert into%';

Table created.

SQL> select * from ty_undo;

SQL_UNDO
--------------------------------------------------------------------------------
insert into TANGYUN.TYLOG(TID,TNAME) values ('01','TANGYUN');
insert into TANGYUN.TYLOG(TID,TNAME) values ('02','TEST');
insert into TANGYUN.TYLOG(TID,TNAME) values ('03','SHXJ');
insert into TANGYUN.TYLOG(TID,TNAME) values ('04','SHSNC');
insert into TANGYUN.TYLOG(TID,TNAME) values ('05','湯雲');

SQL> SELECT SUPPLEMENTAL_LOG_DATA_MIN,SUPPLEMENTAL_LOG_DATA_PK,SUPPLEMENTAL_LOG_DATA_UI FROM V$DATABASE;

SUPPLEME SUP SUP
-------- --- ---
YES NO NO


--------可見,在10g中預設情況下LOGMNR已經不是一個可靠的資料獲取的方式,希望透過這種方式獲取丟失資料,則需要提前設定SUPPLEMENTAL LOG DATA。

其他參考語句:
begin
sys.dbms_logmnr.add_logfile(logfilename => '+DGSYSTEM/tgyun/onlinelog/group_2.258.747535071',options => sys.dbms_logmnr.addfile);
end;


begin
sys.dbms_logmnr.add_logfile(logfilename => '+DGSYSTEM/tgyun/onlinelog/group_2.258.747535071',options => sys.dbms_logmnr.removefile);
end;

ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
ALTER DATABASE DROP SUPPLEMENTAL LOG DATA;

11g以上版本預設SUPPLEMENTAL LOG DATA為開啟狀態

參考文件:
http://ctchina.blog.sohu.com/128878209.html

http://yangtingkun.itpub.net/post/468/464865

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24930246/viewspace-1058003/,如需轉載,請註明出處,否則將追究法律責任。

相關文章