基于LOGMINER 的表DML误操作恢复

 

经常遇到开发人员错误删除,修改,插入等误操作,事后又不知道具体操作哪些数据,希望把恢复到某某时间点,在数据库开归档并有备份的情况的下有一下方法

1 闪回数据库(需要开启flashback)

2 异机数据库不完全恢复(可基于部分表空间)

3 LOGMINER 日志挖掘(需要设置supplemental logging)

DML误操作,如果flashback没有开启,只有选择后两种方法,如果数据库较大对于第二种方法将比较笨重,需要准备新的机器,安装软件,拷贝备份,执行恢复。在开启supplemental logging(建议数据库开启supplemental logging最小模式,对日志量影响较小)情况下则可以选择LOGMINER

关于使用logminer 需要开启supplemental logging 官方文档有明确说明

Database-Level Supplemental Logging

There are two types of database-level supplemental logging: minimal supplemental logging and identification key logging, as described in the following sections. Minimal supplemental logging does not impose significant overhead on the database generating the redo log files. However, enabling database-wide identification key logging can impose overhead on the database generating the redo log files. Oracle recommends that you at least enable minimal supplemental logging for LogMiner

 

---挖掘过程

创建用户

create user logmnr_user identified by logmnr_user;

grant connect,resource,dba to logmnr_user;

alter user logmnr_user default tablespace TBS_XINHUA40_MZMX_1

复制源表

  create table LOGMNR_USER.D405 nologging as select * from FANGCHENG40.D405 where 1=2;

  alter table LOGMNR_USER.D405 add r_rowid varchar2(1000);

  create index LOGMNR_USER.D405_ROWID on LOGMNR_USER.D405(r_rowid);

把源表的rowid 作为新表的一个字段,方便快速更新

  insert /*+ append */ into LOGMNR_USER.D405(D405_01,

                                                    D405_02,

                                                    D405_03,

                                                    D405_04,

                                                    D405_05,

                                                    D405_06,

                                                    D405_07,

                                                    D405_08,

                                                    D405_09,

                                                    D405_10,

                                                    r_rowid) Select D405_01,

                                                    D405_02,

                                                    D405_03,

                                                    D405_04,

                                                    D405_05,

                                                    D405_06,

                                                    D405_07,

                                                    D405_08,

                                                    D405_09,

                                                    D405_10,

                                                    rowid

                                               From FANGCHENG40.D405;

  commit;

 

exec  dbms_stats.gather_table_stats(ownname => 'LOGMNR_USER',tabname => 'D405',granularity => 'ALL',cascade => true);

修改参数

alter system set utl_file_dir='/home/oracle' scope=spfile;

shutdown immediate

startup

生成字典

exec dbms_logmnr_d.build('dictionary.ora','/home/oracle');

添加需要的日志

查询需要添加的日志

select name from v$archived_log a where a.FIRST_TIME>=to_date('&DT','yyyy-mm-dd HH24:mi:ss')

添加日志

 

exec dbms_logmnr.add_logfile(LogFileName=>'/data3/archivelog/1_56140_690352144.dbf',Options=>dbms_logmnr.new);

exec dbms_logmnr.add_logfile(LogFileName=>'/data3/archivelog/1_56141_690352144.dbf',Options=>dbms_logmnr.addfile);

exec dbms_logmnr.add_logfile(LogFileName=>'/data3/archivelog/1_56142_690352144.dbf',Options=>dbms_logmnr.addfile);

exec dbms_logmnr.add_logfile(LogFileName=>'/data3/archivelog/1_56143_690352144.dbf',Options=>dbms_logmnr.addfile);

exec dbms_logmnr.add_logfile(LogFileName=>'/data3/archivelog/1_56144_690352144.dbf',Options=>dbms_logmnr.addfile);

exec dbms_logmnr.add_logfile(LogFileName=>'/data3/archivelog/1_56145_690352144.dbf',Options=>dbms_logmnr.addfile);

exec dbms_logmnr.add_logfile(LogFileName=>'/data3/archivelog/1_56146_690352144.dbf',Options=>dbms_logmnr.addfile);

挖日志

exec dbms_logmnr.start_logmnr(dictfilename=>'/home/oracle/dictionary.ora');

logmnr的数据暂时保存在一个表里面,免得再次查询时候不用再次添加归档日志

create table logmnr_user.tab_logmnr_contents  nologging as select * from v$logmnr_contents where 1=2;

insert /*+ append */ into logmnr_user.tab_logmnr_contents select * from v$logmnr_contents;

commit;

结束日志挖掘

exec dbms_logmnr.end_logmnr;

---处理数据阶段

检测是否发生过DDL

select operation

from LOGMNR_USER.TAB_LOGMNR_CONTENTS

WHERE

SEG_NAME = 'D405' AND

SEG_OWNER = 'FANGCHENG40'

group by operation

  处理数据

根据新增加的R_ROWIDUPDATE DELETE

 

  declare i int;

begin

  i:=0;

for aa in (select replace(replace(SQL_UNDO,'"FANGCHENG40"','"LOGMNR_USER"'),'ROWID','R_ROWID') sql_undo

from LOGMNR_USER.TAB_LOGMNR_CONTENTS

WHERE

SEG_NAME = 'D405' AND

SEG_OWNER = 'FANGCHENG40'

and operation in ('INSERT','UPDATE','DELETE')

and TIMESTAMP>=to_TIMESTAMP('2013-12-02 09:17:00','yyyy-mm-dd hh24:mi:ss')

order by to_char(TIMESTAMP,'yyyy-mm-dd hh24:mi:ss') desc) loop

execute immediate replace(aa.sql_undo,';','');

i:=i+1;

end loop;

dbms_output.put_line(to_char(i));

end;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15747463/viewspace-1062487/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/15747463/viewspace-1062487/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值