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


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

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

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

    select 
        min(start_timestamp) 
    from 
        flashback_transaction_query 
    where 
        table_name='P_WEB' 
        and table_owner='CMS'

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

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

    create table p_web_bad
    as 
    select * from p_web; 

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

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

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

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

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

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

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

    此时,报了一个错:

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

    小问题,enable row movement 就是了

    alter table p_web enable row movement;

    我再闪(flashback):

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

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

    ora-01555 snapshot too old

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

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

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

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

    declare
        v_undo_sql varchar2(4000);
        CURSOR cur is select substr(undo_sql,1,length(undo_sql)-1) --将undo_sql最后那个分号去掉
        from p_web_undo_20100507_2030 where operation='DELETE'; 
        BEGIN 
        open cur;
        loop
            fetch cur into v_undo_sql;
            EXIT when cur%NOTFOUND; 
            execute immediate v_undo_sql;
            --dbms_output.put_line(v_undo_sql);
        END LOOP;
        CLOSE cur;
    END delete_state ;

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

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

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

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

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

    总的来说,就是太嫩了。

  • 相关阅读:
    你知道怎么离线安装全局 node 模块吗?
    关于开发视图
    你知道 JavaScript 中的 Arguments 对象都有哪些用途吗?
    前端 JavaScript 实现一个简易计算器
    Docker 系列 _ 01_ 一念缘起
    机器学习资料大全
    pdf、txt文本复制到EXCEL后的格式快速调整法
    习惯的养成
    磁盘剩余空间监控
    please wait while windows configures microsoft visual studio professional 2013
  • 原文地址:https://www.cnblogs.com/killkill/p/1730783.html
Copyright © 2020-2023  润新知