LogMiner救命稻草_找回误删除数据
LogMiner日志挖掘技术在有些时候可以被比作是命悬一线的救命稻草,比方说误删除数据(如delete执行不当),可以通过LogMiner挖掘日志文件将这些数据补插回来 使用LogMiner预览:o LogMiner的原理就是找出日志文件(redo file),所对应的UNDO.如你新增1W行数据,在redo里以insert形式体现,对应的undo即为delete 简易的实验过程以下模拟delete误删除全表的数据,如果通过LogMiner挖日志将数据找回 ? 1. 启用数据库的Supplemental Logging<span style="font-size:14px;">SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;</span> LogMiner需要最小级别的Supplemental Logging ? 2. 准备测试表和测试数据SQL> create table t1 (a number,b char(2)); SQL> create table t2 (c number,d char(2)); SQL> insert into t1 values(1,'r1'); SQL> insert into t1 values(2,'r2'); SQL> insert into t1 values(3,'r3'); SQL> insert into t2 values(1,'t2'); SQL> commit; SQL> SELECT * FROM T1; A B ---------- -- 1 r1 2 r2 3 r3 SQL> archive log list; Database log mode Archive Mode Automatic archival Enabled Archive destination /home/oracle/arch Oldest online log sequence 57 Next log sequence to archive 59 Current log sequence 59 <<<<<<==== SQL> alter system archive log current; ? 3. 添加日志至挖掘列表并开始挖掘? <p>SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '/home/oracle/arch/1_59_847657195.dbf',OPTIONS => DBMS_LOGMNR.NEW);</p><p>PL/SQL procedure successfully completed</p><p>SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS =>DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG); ? PL/SQL procedure successfully completed</p>
每次添加或移除日志到列表都需要重新执行START_LOGMNR 查询视图V$LOGMNR_CONTENTSSQL> select scn,?????? timestamp,?????? (xidusn || '.' || xidslt || '.' || xidsqn) as xid,?????? info,?????? seg_owner,?????? seg_name,?????? operation,?????? sql_redo,?????? sql_undo ? from v$logmnr_contents ?where seg_name in ('T1','T2') / SCN TIMESTAMP XID SEG_OWNER SEG_NAME OPERATION SQL_REDO SQL_UNDO ---------- ----------- ----------------- -------------- ---------- -------------- ------------------------------------------------------ -------------------------------------------------------------------------------- 1212893 2015/1/10 1 4.1.550 SYS T1 DDL create table t1 (a number,b char(2)); 1212907 2015/1/10 1 10.12.537 SYS T2 DDL create table t2 (c number,d char(2)); 1212913 2015/1/10 1 5.40.556 SYS T1 INSERT insert into "SYS"."T1"("A","B") values ('1','r1'); delete from "SYS"."T1" where "A" = '1' and "B" = 'r1' and ROWID = 'AAANBSAABAAAP 1212913 2015/1/10 1 5.40.556 SYS T1 INSERT insert into "SYS"."T1"("A","B") values ('2','r2'); delete from "SYS"."T1" where "A" = '2' and "B" = 'r2' and ROWID = 'AAANBSAABAAAP 1212913 2015/1/10 1 5.40.556 SYS T1 INSERT insert into "SYS"."T1"("A","B") values ('3','r3'); delete from "SYS"."T1" where "A" = '3' and "B" = 'r3' and ROWID = 'AAANBSAABAAAP 1212913 2015/1/10 1 5.40.556 SYS T2 INSERT insert into "SYS"."T2"("C","D") values ('1','t2'); delete from "SYS"."T2" where "C" = '1' and "D" = 't2' and ROWID = 'AAANBTAABAAAP ? 删除测试表数据SQL> DELETE FROM T1;<<<=====删除全表数据 3 rows deleted SQL> COMMIT; Commit complete SQL> SELECT * FROM T1; A B ---------- -- SQL> ALTER SYSTEM ARCHIVE LOG CURRENT; System altered ? 新增日志列表,重新开始挖掘SQL> EXECUTE DBMS_LOGMNR.ADD_LOGFILE(LOGFILENAME => '/home/oracle/arch/1_60_847657195.dbf',OPTIONS => DBMS_LOGMNR.ADDFILE); PL/SQL procedure successfully completed SQL> EXECUTE DBMS_LOGMNR.START_LOGMNR(OPTIONS =>DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG); PL/SQL procedure successfully completed
查询V$LOGMNR_CONTENTSselect scn,timestamp,(xidusn || '.' || xidslt || '.' || xidsqn) as xid,info,seg_owner,seg_name,operation,sql_redo,sql_undo from v$logmnr_contents where seg_name in ('T1','T2') / SCN TIMESTAMP XID SEG_OWNER SEG_NAME OPERATION SQL_REDO SQL_UNDO ---------- ----------- -------------- ---------------- ----------- ------------- -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- 1212893 2015/1/10 1 4.1.550 SYS T1 DDL create table t1 (a number,b char(2)); 1212907 2015/1/10 1 10.12.537 SYS T2 DDL create table t2 (c number,d char(2)); 1212913 2015/1/10 1 5.40.556 SYS T1 INSERT insert into "SYS"."T1"("A",'r1'); delete from "SYS"."T1" where "A" = '1' and "B" = 'r1' and ROWID = 'AAANBSAABAAAP 1212913 2015/1/10 1 5.40.556 SYS T1 INSERT insert into "SYS"."T1"("A",'r2'); delete from "SYS"."T1" where "A" = '2' and "B" = 'r2' and ROWID = 'AAANBSAABAAAP 1212913 2015/1/10 1 5.40.556 SYS T1 INSERT insert into "SYS"."T1"("A",'r3'); delete from "SYS"."T1" where "A" = '3' and "B" = 'r3' and ROWID = 'AAANBSAABAAAP 1212913 2015/1/10 1 5.40.556 SYS T2 INSERT insert into "SYS"."T2"("C",'t2'); delete from "SYS"."T2" where "C" = '1' and "D" = 't2' and ROWID = 'AAANBTAABAAAP 1213003 2015/1/10 1 5.47.556 SYS T1 DELETE delete from "SYS"."T1" where "A" = '1' and "B" = 'r1' and ROWID = 'AAANBSAABAAAP insert into "SYS"."T1"("A",'r1'); 1213003 2015/1/10 1 5.47.556 SYS T1 DELETE delete from "SYS"."T1" where "A" = '2' and "B" = 'r2' and ROWID = 'AAANBSAABAAAP insert into "SYS"."T1"("A",'r2'); 1213003 2015/1/10 1 5.47.556 SYS T1 DELETE delete from "SYS"."T1" where "A" = '3' and "B" = 'r3' and ROWID = 'AAANBSAABAAAP insert into "SYS"."T1"("A",'r3'); 9 rows selected
执行SQL_UNDO字段的SQL即可SQL> insert into "SYS"."T1"("A",'r1'); 1 row inserted SQL> insert into "SYS"."T1"("A",'r2'); 1 row inserted SQL> insert into "SYS"."T1"("A",'r3'); 1 row inserted SQL> commit; Commit complete SQL> SQL> select * from t1; A B ---------- -- 1 r1 2 r2 3 r3 至此,被误删除的数据就找回来了. 关闭LogMinerSQL> EXECUTE DBMS_LOGMNR.end_logmnr; PL/SQL procedure successfully completed (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |