首页 > 代码库 > 表误删记录恢复操作

表误删记录恢复操作

表误删记录恢复操作

 

 

最近处理了个用户误删delete table 的故障,这里做了一个简单的汇总,文章内容整理自pub 里的各位大师的精粹,我这里偷个懒直接拿来用下。

基本处理思路:

1.如果还没有提交,用rollback。(应该不大可能。)
2.
如果提交时间超过5分钟以上且小于undo_retention的设置,可以使用回闪功能。具体限制和操作可以参考:http://blog.itpub.net/post/468/15464
3.
如果上述两条都不满足,可以使用logminerredo中恢复,logminer的使用限制和描述可以参考:http://blog.itpub.net/post/468/13436

这里有一个使用logminer的简单的例子:http://blog.itpub.net/post/468/11764
4.
如果这个日志已经重用且没有启用归档模式,那么你只能从备份中恢复了

 

 

 

2.使用闪回恢复表数据

2.1----flashback table

主要是是用undo 表空间的内容

 

注意:需要启用表的row movement

 

----格式化时间

SQL> alter session set nls_date_format=‘yyyy-mm-dd hh24:mi:ss‘;

SQL> select sysdate from dual;

SYSDATE

-------------------

2014-07-27 20:23:37

 

----enable row movement

Alter table xxx enable row movement

 

----根据scn闪回表:

SQL> flashback table kel.t1 to scn 896744; 

 

---根据时间点闪回表:

SQL> flashback table kel.t1 to timestamp to_timestamp(‘2014-07-28 00:18:00‘,‘yyyy-mm-dd hh24:mi:ss‘);

 

 

2.2----flashback query

flashback query只能看到某一个时间点的对象的状态,而不能看到某个时间段内的状态变化。

 

select * from tb as of timestamp to_timestamp(‘2014-07-27 20:23:37‘,‘yyyy-mm-dd hh24:mi:ss‘);

 

 

2.3-----flashback drop

用于恢复用户误删除的对象,包括表、索引等,依赖于tablespace recycle bin,表空间回收站

 

初始化参数recyclebin参数用于控制是否启用recyclebin功能,缺省是ON

recycle bin中,oracle可以区分不同用户的同名的表。

recycle bin的维护:

 

1只能用于非系统表空间和本地管理的表空间

2、如果对象创建在本地管理的表空间,而关联对象,比如索引创建在字典管理的表空间上,则恢复时字段管理的表空间关联对象不能被恢复

3、对象是否能恢复成功,取决于对象空间是否被覆盖重用

4不能对recycle bin中的内容进行DMLDDL的操作,只能做查询操作

5对象的参考约束不能被恢复,也就是外键约束需要重建

 

手动清除recycle bin的空间:

purge tablespace kel

 

 

db_flashback_retention_target Default value        1440 (minutes)

闪回查询使用的是undo 信息

 

 

UNDO_RETENTION  理解:

 

 The UNDO_RETENTION parameter is ignored for a fixed size undo tablespace. The database may overwrite unexpired undo information when tablespace space becomes low.

如果undo 表空间大小是固定的,则oracle会忽略 undo_retention参数的设置,在undo 空间不足的情况下,oracle可能会覆盖未过期的undo信息。

 

 For an undo tablespace with the AUTOEXTEND option enabled, the database attempts to honor the minimum retention period specified by UNDO_RETENTION. When space is low, instead of overwriting unexpired undo information, the tablespace auto-extends. If the MAXSIZE clause is specified for an auto-extending undo tablespace, when the maximum size is reached, the database may begin to overwrite unexpired undo information.

undo 是自动扩展的,oracle会尽可能的保证 undo_retention设置的undo保留时间;当undo空间不够使oracle 会优先自动扩展undo 表空间,而不是去覆盖未过期的undo信息,如果undo tbs 设置了 maxsize  参数,则在达到undo最大空间时,oracle可能就会去覆盖那些未过期的undo信息。

 

 

 

注意:对于在system表空间的中对象,使用闪回drop无效,因为被drop的对象不会被放在 recyclebin中:

 

----确认是否启用recyclebin功能

SQL> show parameter recyclebin 

 

----可以通过视图来进行查看recycle bin中的对象列表:

select object_name as recycle_name,original_name from recyclebin; 

 

----可以像查看普通表一样,来查看recycle bin中对象的内容:

select count(*) from "BIN$/ti6DA4axIDgQKjAbgFLmA==$0";  

 

要使用flashback drop功能恢复误删除的表,需要做以下几点:

1确认已删除的表在recycle bin

2、使用flashback table来进行恢复

如果同名的表在recycle bin中存在,可以恢复到需要的那个表:

select count(*) from "BIN$/ti6DA4cxIDgQKjAbgFLmA==$0";--查看哪个是想恢复的表  

 

---恢复表

flashback table "BIN$/ti6DA4exIDgQKjAbgFLmA==$0" to before drop;

 

---恢复表并且重命名为kel1 

flashback table kel to before drop rename to kel1; 

 

 

 

 

 

 

 

3.使用oracle logminer 来进行数据恢复

logmnr其实是非常有用的一个恢复数据的工具,今天有人提到恢复700万的数据,我也做过几万条财务数据的恢复,借此小结一下。

--创建一个表来保存提取出来的sql
create table logmnr_content tablespace tools as select scn,cscn,TIMESTAMP,sql_undo from v$logmnr_contents where 1=0;

--
通过dba_objects查到表对应的 object_id and data_object_id ,用来在log中提取该表相关的sql_undo
select object_id,data_object_id from dba_objects where object_name = ???

--
通过在os中找到的归档日志范围,进行联机提取
undo sql 插入一个表中,比如我的日志序号范围是 5813 5850
为了防止临时空间不足,一个一个归档日志文件处理。


begin
for i in 8..24 loop

dbms_logmnr.add_logfile(LogFileName=>‘/disk2/oradata/arch/crmcn/crmcn_1_‘||i||‘.arc‘);
dbms_logmnr.start_logmnr(Options => sys.dbms_logmnr.DICT_FROM_ONLINE_CATALOG);
dbms_logmnr.start_logmnr();

insert into logmnr_content(scn,cscn,TIMESTAMP,sql_undo )
select scn,cscn,TIMESTAMP,sql_undo from v$logmnr_contents
where DATA_OBJD# = 52528;

commit;
dbms_logmnr.end_logmnr();

end loop;
end

/



--
将提取出来的sql通过动态sql执行插入表

declare
sql_str varchar2(4000);
begin
for c in (select * from logmnr_content) loop
sql_str := replace(c.sql_undo,‘;‘,‘‘);
execute immediate sql_str;
end loop;
commit;
end;


注意:如果在这段日志中还有其他对该表的操作的话,可以结合操作类型 OPERATION提交scn cscn来判断到底是不是该恢复的这部分数据。