ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 记一次使用flashback恢复数据,警惕自己不要浮躁,还是太嫩了 [转]

记一次使用flashback恢复数据,警惕自己不要浮躁,还是太嫩了 [转]

原创 Linux操作系统 作者:todayboy 时间:2011-09-15 16:50:56 0 删除 编辑

    周五晚十点多,同事突然来电称操作CMS后台的时候不小心删除了很多记录(其实应该是这个CMS的逻辑问题),大概了解了情况以后,能初步判断为p_web表的2万多条数据被delete了,事发时间大概在9:30左右,这种场景几乎就是“专门”为flashback而设的了。

于是马上翻开书找到flashback那节书,先鄙视一下自己,以前所学的都还给书本了。

确认一下可以flashback的极限是多少

 
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
 
1 select 
2     min(start_timestamp) 
3 from 
4     flashback_transaction_query 
5 where 
6     table_name='P_WEB' 
7     and table_owner='CMS'

结果是前天的下午3点,比预期中的时间要长很多啊。

由于p_web表数据量不大,还不到100M,赶紧做个“备份”,免得突然犯浑把剩下的2万多条记录都整丢了,那就可以跳楼了:

 
1 create table p_web_bad
2 as 
3 select * from p_web;

使用flashback query将9:20的数据放在一个p_web_20100507_0920表里面,让同事看看效果先:

 
1 create table p_web_20100507_0920 
2 as 
3 select 
4     * 
5 from 
6     p_web 
7 as of timestamp to_date('2010-05-07 21:20:00','yyyy-mm-dd hh24:mi:ss');

其实我也是笨,脱离了表现层的数据能看出什么呢?除了“感觉”上是正确的一点说服力也没有。

同事说这个数据没问题。为了进一步确定事发的准确时间点,使用flashback transaction query 将自8:30以来的所有undo操作列出,这样可以找出什么时候开始删除的了。

 
01 create table p_web_undo_20100507_2030 
02 as
03 select 
04     start_timestamp,operation,undo_sql 
05 from 
06     flashback_transaction_query 
07 where 
08     table_name='P_WEB' 
09     and table_owner='CMS' 
10     and start_timestamp>to_date('2010-05-07 20:30:00','yyyy-mm-dd hh24:mi:ss')
11 order by 
12     start_timestamp desc

经过一个简单的查询从start_timestamp 能查出是21:39:04开始删除的,只要将flashback到21:38:00问题就OK了啦。

 
1 flashback table p_web 
2     to timestamp to_date('2010-05-07 21:38:00','yyyy-mm-dd hh24:mi:ss');

此时,报了一个错:

 
1 ORA-08189: cannot flashback the table because row movement is not enabled

小问题,enable row movement 就是了

 
1 alter table p_web enable row movement;

我再闪(flashback):

 
1 flashback table p_web 
2     to timestamp to_date('2010-05-07 21:38:00','yyyy-mm-dd hh24:mi:ss');

shit!竟然出现了flashback的克星:

 
1 ora-01555 snapshot too old

明明前面查到可以flashback的时间很长的啊,莫非是前面几个大create table把undo内容刷走了,这也太快了吧@_@!

先不管了,我同事还在着急的等待,虽然没有催我,但是“弄丢”数据的心情我很清楚。

幸好前面创建了一个p_web_undo_20100507_2030表,里面有一对undo的sql,可以将被delete的数据再insert回去。

于是写了个简单的过程做这件事:

 
01 declare
02     v_undo_sql varchar2(4000);
03     CURSOR cur is select substr(undo_sql,1,length(undo_sql)-1) --将undo_sql最后那个分号去掉
04     from p_web_undo_20100507_2030 where operation='DELETE'; 
05     BEGIN 
06     open cur;
07     loop
08         fetch cur into v_undo_sql;
09         EXIT when cur%NOTFOUND; 
10         execute immediate v_undo_sql;
11         --dbms_output.put_line(v_undo_sql);
12     END LOOP;
13     CLOSE cur;
14 END delete_state ;

经过“漫长”的等待,终于将误删的数据恢复回来了。

 

经过这次数据恢复让我认识到:

1。虽然掌握了基本概念,但是熟练程度还不够,体现在临急翻书上。

2。实际操作经验欠缺,整个过程实际上没多少东西,但是却足足折腾了一个半小时。

3。前瞻性不足,这个数据库是我维护的,对于误操作删除数据这种问题应该要有所觉悟,就这个问题而言,我做的措施仅仅是扩大了undo表空间。

总的来说,就是太嫩了。

 

source:http://www.cnblogs.com/killkill/archive/2010/05/08/1730783.html

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

请登录后发表评论 登录
全部评论

注册时间:2009-02-24

  • 博文量
    75
  • 访问量
    262257