前几天一个线上的生产环境,系统维护人员执行了一个错误update操作,由于涉及到数据量比较大,要紧急恢复,我远程做了支持。下面我总结操作经历和部分操作步骤:
写博客中还有一个小插曲,恢复经历的第二天我就在博客中写了总结,但是web页面我操作失误,把页面后退咯,写好好长时间的博客全都没了,当时很崩溃啊。我有记性了,下次些博客先在word编写。痛苦回忆中…… 
言归正传,当时系统维护人员9:20 分操作数据,我11:00上生产数据库检查数据库状态。
一、我检查数据库闪回是否开启
select log_mode,open_mode,flashback_on from v$database;
返回结果:no 
二、通过scn追溯表 数据
A、 SELECT timestamp_to_scn(to_date('2011-06-25 09:20:00','yyyy-mm-dd hh24:mi:ss')) FROM dual;
获得scn : 145815851
B、 select * from EMALL_USERS as of scn 145815851;
返回结果:scn已经过期
查看归档日志,发现9:20分有3个归档文件
三、通过归档文件查找数据,追溯update的sql_undo操作
A、在paulyibinyi博客中的资料,非常好 的资料:http://space.itpub.net/7199859/viewspace-503895
B、在此也非常感谢戴明明给我帮助,理解sql_undo和sql_redo含义
但是在Logmnr操作过程中,我有一个非常低级的失误,由于sql_undo是通过rowid做逆向操作,我用create table table_name_bank as
select * from table_name. 所以相对应的逆向操作不能完成。 
declare
mysql varchar2(4000);
num number :=0;
begin
for c_tmp in (select sql_undo from tmp_logmnr3 where PERATION='UPDATE' and SQL_UNDO like '%EMALL_TRADE%') loop
mysql := replace(c_tmp.sql_undo,';','');
dbms_output.put_line(mysql);
execute immediate mysql;
num := num + 1;
if mod(num,1000)=0 then
commit;
end if;
end loop;
commit;
exception
when others then
rollback;
end;
/
四、最后用了rman的异地恢复,把数据库恢复到9:30分,找回表数据。
因为自己失误耽搁很长时间,心里上还是有些过意不去。之前写的博客没有备份,具体步骤没有再详细写出。以后有记性了,绝对不能在web页面上些太长信息。