zoukankan      html  css  js  c++  java
  • ora flashback详解

    使用oracle数据库时,难免会碰到一些问题.

         例:1.如何回滚已经commit了的数据

             2.如何查询已经被覆盖掉的数据[update],或者被delete了的数据

             3.如何将数据恢复到某个时间点

                 我们就可以使用Flashback相关语句解决相关问题了   

    关于Flashback[回闪]:

          从9i到10g到最新的11.2g,oracle对Flashback功能进行了进一步的扩展,利用Flashback我们可做到

              1.flashback query      闪回查询,并不实际修改表的数据

              2.flashback table       闪回表格,可恢复表格的数据

              3.flash database       闪回数据库,可恢复db的数据

    ①:

    关于Flashback Query:
        1.Flash Query通过undo数据表空间数据,利用一致性的方法来查找用户需要的数据
        2.作用范围:查找指定时间点被(delete,update)的数据   只是做查找操作,如果设计恢复那么就要使用flashback table了
        3.相关参数:

                        1.查询出来的数据存活时间受 undo_retention(默认为900秒)影响     [目标值,该变量(秒)可以影响undo表空间产生的data存活时间,时间一到,即死亡(消失)]

                        2.闪回时间受undo表空间大小影响                             [关于undo表空间的操作,另一片文章会有讲解]
                        3.查询的仅仅是快照,并不能修改当前状态                     

                        4.基本语法[两种方式,使用时间片或scn号]  使用时间片的情况比较多
                                  1.select *  from 你要查询表的名字 as of timestamp         [查询某一时间该表的数据]
                                  2.select * from 你要查询表的名字 as of scn 具体scn号      [关于scn号,另一篇文章会讲解]

        4.原理:

                  简单的说就是将以前被修改,删除了的数据,通过开启Flashback 模式,回到我们需要回到的时间来查看数据,

                  在undo_retention该变量设置的时间过后,该镜像数据会自动被清除.相当于查看的是一个镜像数据.

                  一种方式是利用scn号来查看镜像数据,另一种是通过查找时间片来查询镜像数据

                      案例1:
    ①--创建测试flashQuery表格 主要由scn号和系统日期组成

        create table testQuery(

           id number,

           scn number,

           time varchar2(20),

           mydate varchar2(20)

         );

     


    ②--插入测试数据

    begin

       for i in 1..16

          loop

              insert into testQueryvalues(i,dbms_flashback.get_system_change_number(),to_char   (sysdate,'yyyy-mm-dd hh24:mi:ss'),'你好'||i); --插入scn号和sysdate为方便后续查询

            commit;   --如果不实时commit,那么会在循环完后,批量提交,时间点是一样的

            dbms_lock.sleep(2); --使用dbms_lock.sleep 方法和java的thread睡眠是一个意思  参数以秒为单位

       end loop;

    end;


    ③--查询未修改的数据

    result:
                1 3303552 2011-01-25 11:51:33 你好1
                2 3303556 2011-01-25 11:51:35 你好2
                3 3303558 2011-01-25 11:51:37 你好3
                4 3303560 2011-01-25 11:51:39 你好4
                5 3303562 2011-01-25 11:51:41 你好5
                6 3303564 2011-01-25 11:51:43 你好6
                7 3303566 2011-01-25 11:51:45 你好7
                8 3303568 2011-01-25 11:51:47 你好8
                9 3303570 2011-01-25 11:51:49 你好9
                10 3303572 2011-01-25 11:51:51 你好10
                11 3303574 2011-01-25 11:51:53 你好11
                12 3303576 2011-01-25 11:51:55 你好12
                13 3303578 2011-01-25 11:51:57 你好13
                14 3303580 2011-01-25 11:51:59 你好14
                15 3303582 2011-01-25 11:52:01 你好15
                16 3303584 2011-01-25 11:52:03 你好16

    ④--查询最新的scn号[类似于check point],该scn号在每次commit时,都会自动变化[使用scn号来开启Flashback Query模式]

          select dbms_flashback.get_system_change_number from dual;

          result:3307628  --该scn号可以理解成为一个check point点.我们可以借助这个标记来回退到该scn号查询当前的数据
    ④--修改第十条,和第十一条的数据:

     

          update testQuery tq set tq.mydate='新年快乐' where scn='3303572';

          commit;

          update testQuery tq set tq.mydate='万事如意' where scn='3303574';

          commit;

    select * from testQuery

    result: 

                1 3303552 2011-01-25 11:51:33 你好1
                2 3303556 2011-01-25 11:51:35 你好2
                3 3303558 2011-01-25 11:51:37 你好3
                4 3303560 2011-01-25 11:51:39 你好4
                5 3303562 2011-01-25 11:51:41 你好5
                6 3303564 2011-01-25 11:51:43 你好6
                7 3303566 2011-01-25 11:51:45 你好7
                8 3303568 2011-01-25 11:51:47 你好8
                9 3303570 2011-01-25 11:51:49 你好9
                10 3303572 2011-01-25 11:51:51 新年快乐

                11 3303574 2011-01-25 11:51:53 万事如意
                12 3303576 2011-01-25 11:51:55 你好12
                13 3303578 2011-01-25 11:51:57 你好13
                14 3303580 2011-01-25 11:51:59 你好14
                15 3303582 2011-01-25 11:52:01 你好15
                16 3303584 2011-01-25 11:52:03 你好16

     ⑤--使用scn号来进行闪回查询

                1.不开启Flashback模式,仅使用Flashback query语句做查询

    select * from testQuery as of scn 3307628

    result:
                1 3303552 2011-01-25 11:51:33 你好1
                2 3303556 2011-01-25 11:51:35 你好2
                3 3303558 2011-01-25 11:51:37 你好3
                4 3303560 2011-01-25 11:51:39 你好4
                5 3303562 2011-01-25 11:51:41 你好5
                6 3303564 2011-01-25 11:51:43 你好6
                7 3303566 2011-01-25 11:51:45 你好7
                8 3303568 2011-01-25 11:51:47 你好8
                9 3303570 2011-01-25 11:51:49 你好9
                10 3303572 2011-01-25 11:51:51 你好10
                11 3303574 2011-01-25 11:51:53 你好11
                12 3303576 2011-01-25 11:51:55 你好12
                13 3303578 2011-01-25 11:51:57 你好13
                14 3303580 2011-01-25 11:51:59 你好14
                15 3303582 2011-01-25 11:52:01 你好15
                16 3303584 2011-01-25 11:52:03 你好16

           2.开启Flashback模式做查询,整个db将会产生某个scn号所在时间点的镜像数据. 

             使用dbms包开启Flashback模式:

        exec DBMS_FLASHBACK.ENABLE_AT_SYSTEM_CHANGE_NUMBER(3307628);

            现在查看表的数据:

    select * from testQuery as of scn 3307628;

    result:
                1 3303552 2011-01-25 11:51:33 你好1
                2 3303556 2011-01-25 11:51:35 你好2
                3 3303558 2011-01-25 11:51:37 你好3
                4 3303560 2011-01-25 11:51:39 你好4
                5 3303562 2011-01-25 11:51:41 你好5
                6 3303564 2011-01-25 11:51:43 你好6
                7 3303566 2011-01-25 11:51:45 你好7
                8 3303568 2011-01-25 11:51:47 你好8
                9 3303570 2011-01-25 11:51:49 你好9
                10 3303572 2011-01-25 11:51:51 你好10
                11 3303574 2011-01-25 11:51:53 你好11
                12 3303576 2011-01-25 11:51:55 你好12
                13 3303578 2011-01-25 11:51:57 你好13
                14 3303580 2011-01-25 11:51:59 你好14
                15 3303582 2011-01-25 11:52:01 你好15
                16 3303584 2011-01-25 11:52:03 你好16

    注:此时整个DB为镜像数据.

       [如果单独再开启个链接,那么看到的还是真实数据而不是镜像数据];

       [如果中途要退出Flashback模式请使用:exec DBMS_FLASHBACK.DISABLE;]

    退出Flashback 模式:

    exec DBMS_FLASHBACK.DISABLE;

    select * from testQuery

    result: 

                1 3303552 2011-01-25 11:51:33 你好1
                2 3303556 2011-01-25 11:51:35 你好2
                3 3303558 2011-01-25 11:51:37 你好3
                4 3303560 2011-01-25 11:51:39 你好4
                5 3303562 2011-01-25 11:51:41 你好5
                6 3303564 2011-01-25 11:51:43 你好6
                7 3303566 2011-01-25 11:51:45 你好7
                8 3303568 2011-01-25 11:51:47 你好8
                9 3303570 2011-01-25 11:51:49 你好9
                10 3303572 2011-01-25 11:51:51 新年快乐

                11 3303574 2011-01-25 11:51:53 万事如意
                12 3303576 2011-01-25 11:51:55 你好12
                13 3303578 2011-01-25 11:51:57 你好13
                14 3303580 2011-01-25 11:51:59 你好14
                15 3303582 2011-01-25 11:52:01 你好15
                16 3303584 2011-01-25 11:52:03 你好16


                                                                                                                                             以上就是使用scn号来做闪回查询了;

    ⑥--使用时间点来进行闪回查询

         select * from testQuery as of timestamp  to_timestamp('2011-01-25 13:25:55','yyyy-mm-dd hh24:mi:ss');

              做此查询要确保没有对原有表结构进行修改,如果有的话可能引发异常;

    select * from testQuery;

    result:
                1 3303552 2011-01-25 11:51:33 你好1
                2 3303556 2011-01-25 11:51:35 你好2
                3 3303558 2011-01-25 11:51:37 你好3
                4 3303560 2011-01-25 11:51:39 你好4
                5 3303562 2011-01-25 11:51:41 你好5
                6 3303564 2011-01-25 11:51:43 你好6
                7 3303566 2011-01-25 11:51:45 你好7
                8 3303568 2011-01-25 11:51:47 你好8
                9 3303570 2011-01-25 11:51:49 你好9
                10 3303572 2011-01-25 11:51:51 你好10
                11 3303574 2011-01-25 11:51:53 你好11
                12 3303576 2011-01-25 11:51:55 你好12
                13 3303578 2011-01-25 11:51:57 你好13
                14 3303580 2011-01-25 11:51:59 你好14
                15 3303582 2011-01-25 11:52:01 你好15
                16 3303584 2011-01-25 11:52:03 你好16


     关于scn号和这个timeStamp的转换[这个可能会出问题(undo表空间过小,无法查询到过早的数据)]

             scn→→timeStamp:            

             select SCN_TO_TIMESTAMP(SCN号) as ts from dual; 

             timeStamp→→scn

                      select TIMESTAMP_TO_SCN('25-1月-11 01.05.29.046000 下午') from dual; 

    ②:

    关于Flashback Table:

          1.闪回表格,可将表格的数据闪回到某个时间点   

          2.需要开启行移动模式      [enable row movement]            

          3.原理:Flashback Table也是利用Undo数据来恢复对象到指定时间点
          4.使用范围:恢复当前表及其相关对象到某个时间点 
          5.注意点:

                      1).闪回时间受参数undo_retention影响

                      2).闪回时间受undo表空间大小影响

                      3).和flashback query有差别,恢复表到以前的时间点 [真实闪回,而不是镜像]
          6.语法:

               1).flashback table table_name to timestamp ....                [根据时间点闪回]

               2).flash table table_name to scn ...                                   [根据scn号回退,实际操作基本上不会用到]

               3).flashback table table_name to timestamp ... enable triggers.                   [创建表,开启行移动模式,用的不多]

               4).flashback table testFlashTable to TIMESTAMP systimestamp - interval '5' minute;    [回退到几分钟之前,用的多]

    例:将第一条数据更新,然后进行闪回表格,得到我们以前的数据;

    创建新的表格测试:

     

     

    create table testFlashTable(

       id number,

       mydata varchar2(60)

    );

     

    插入测试数据: 

    insert into testFlashTable values(1,'一帆风顺');

    commit;

     

    select * from testQuery;

    result:

            1 一帆风顺

    ------等待5分钟--------让scn号飞一会,不然可能会出错

    删除数据:

    delete from testFlashTable;

    commit;

     

    select * from testQuery;

    result:

            无;

     

     

    开启行移动模式:

    alter table testFlashTable enable row movement;

    使用flashBack:[这种方法用的比较多,不小心删除了,马上就可以闪回][闪回到5分钟以前]

    flashback table testFlashTable to TIMESTAMP systimestamp - interval '5' minute;

    或者: [闪回到时间点]

    flashback table t to  timestamp  to_timestamp('2011-01-26 11:35:40','yyyy-mm-dd hh24:mi:ss'); 


    ③:

    关于Flashback Database:

          1.闪回DB,可将数据库闪回到某个时间点   [需要事先配置,让oracle处于Flashback 状态]

       在真实环境中使用Flashback Database的场景是较少的,更多的是使用rman技术来做恢复还原 

       需要单独开启后台进程[Recover Writer][RVWR],会额外增大oracle的开销

       这里就不对其做描述了.

  • 相关阅读:
    [CSS] prefers-reduced-motion
    [VSCode] Adding Custom Syntax Highlighting to a Theme in VSCode
    Subversion/Git/ReviewBoard工作流程
    oracle hints
    Node.js学习(10)----文件系统fs
    网络子系统41_inet_peer平衡二叉树的删除
    由链表初始化看C语言的二级指针
    挣值管理不是搞数字游戏(4)——让挣值管理实用!
    关于数据库一致改关闭下redo日志文件丢失的处理办法的总结
    Android 操作系统的内存回收机制
  • 原文地址:https://www.cnblogs.com/hllnj2008/p/5332672.html
Copyright © 2011-2022 走看看