表误删记录恢复操作 最近处理了个用户误删delete table 的故障,这里做了一个简单的汇总,文章内容整理自pub 里的各位大师的精粹,我这里偷个懒直接拿来用下。 基本处理思路: 1.如果还没有提交,用rollback。(应该不大可能。) 2.如果提交时间超过5分钟以
表误删记录恢复操作
最近处理了个用户误删delete table 的故障,这里做了一个简单的汇总,文章内容整理自pub 里的各位大师的精粹,我这里偷个懒直接拿来用下。
基本处理思路:
1.如果还没有提交,用rollback。(应该不大可能。)
2.如果提交时间超过5分钟以上且小于undo_retention的设置,可以使用回闪功能。具体限制和操作可以参考:http://blog.itpub.net/post/468/15464
3.如果上述两条都不满足,可以使用logminer从redo中恢复,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中的内容进行DML和DDL的操作,只能做查询操作
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 来判断到底是不是该恢复的这部分数据。