Oracle 闪回特性(Flashback Query、Flashback T

系统 1611 0

--==================================================

-- Oracle 闪回特性 (Flashback Query Flashback Table)

--==================================================

 

    Oracle 闪回查询是指针对特定的表来查询特定的时间段内的数据变化情况来确定是否将表闪回到某一个特定的时刻以保证数据无讹误存在。

这个特性大大的减少了采用时点恢复所需的工作量以及数据库脱机的时间。   闪回查询通常分为 Flashback Query ( 闪回查询 )

Flashback Table Query( 闪回表查询 ) Flashback Version Query( 闪回版本查询 ) Flashback Transaction Query( 闪回事务查询 ) 。本文主要讲

Flashback Query ( 闪回查询 ) Flashback Table Query( 闪回表查询 ) 。其余闪回请参考后续文章。

 

一、 Flashback Query ( 闪回查询 )

    通常用于检索一条记录的所有版本,倒退单独的事务或者倒退从指定时间以来对特定表的所有变化

    Flashback Query 的所有形式取决于 UNDO 表表空间,关于 UDNO 表空间请参考: Oracle 回滚(ROLLBACK) 和撤销(UNDO)

   

    1. 闪回查询 ( Flashback Query ) 语法

           

        SELECT < column_name_list >

        FROM < table_name >

        AS OF < SCN >                             -- 使用 as of scn

        [WHERE <filter_conditions>]

        [GROUP BY <unaggregated columns>]

        [HAVING <group_filter>]

        [ORDER BY <column_positions_or_name>]

   

        SELECT < column_name_list >

        FROM < table_name >

        AS OF < TIMESTAMP >                        -- 使用 as of timestamp

        [WHERE <filter_conditions>]

        [GROUP BY <unaggregated columns>]

        [HAVING <group_filter>]

        [ORDER BY <column_positions_or_name>]

   

    2. 演示闪回查询

        a . 演示使用 as of timestamp 来进行闪回查询

            flasher@ORCL11G > create table tb1 as

              2   select empno , ename , job , deptno from scott . emp where 1 = 0 ;

 

            flasher@ORCL11G > insert into tb1

              2   select empno , ename , job , deptno

              3   from scott . emp where empno in( 7369 , 7499 , 7521 , 7566 );

 

            flasher@ORCL11G > commit ;

     

            flasher@ORCL11G > select * from tb1 ;

 

                  EMPNO ENAME       JOB            DEPTNO

            ---------- ---------- --------- ----------

                  7369 SMITH       CLERK              20

                  7499 ALLEN       SALESMAN           30

                  7521 WARD        SALESMAN           30

                  7566 JONES       MANAGER            20  

 

            flasher@ORCL11G > select to_char ( sysdate , 'yyyy-mm-dd hh24:mi:ss' ) from dual ;

 

            TO_CHAR ( SYSDATE , 'YY'

            -------------------

            2010 - 10 - 25 17 : 26 : 08

 

            flasher@ORCL11G > delete from tb1 where job = 'SALESMAN' ;

 

            flasher@ORCL11G > commit ;

 

            flasher@ORCL11G > select * from tb1 ;

 

                  EMPNO ENAME       JOB            DEPTNO

            ---------- ---------- --------- ----------

                  7369 SMITH       CLERK              20

                  7566 JONES       MANAGER            20    

         

            flasher@ORCL11G > select * from tb1 as of timestamp

              2   to_timestamp ( '2010-10-25 17:26:08' , 'yyyy-mm-dd hh24:mi:ss' );

 

                  EMPNO ENAME       JOB            DEPTNO

            ---------- ---------- --------- ----------

                  7369 SMITH       CLERK              20

                  7499 ALLEN       SALESMAN           30

                  7521 WARD        SALESMAN           30

                  7566 JONES       MANAGER            20    

 

            flasher@ORCL11G > select * from tb1 as of timestamp

              2   to_timestamp ( '2010-10-25 17:26:08' , 'yyyy-mm-dd hh24:mi:ss' )

              3   minus select * from tb1 ;

 

                  EMPNO ENAME       JOB            DEPTNO

            ---------- ---------- --------- ----------

                  7499 ALLEN       SALESMAN           30

                  7521 WARD        SALESMAN           30

        b . 演示使用 as of scn 来进行闪回查询

            flasher@ORCL11G > select current_scn from v$database ;

 

            CURRENT_SCN

            -----------

                2032782

 

            flasher@ORCL11G > select * from tb1 ;

 

                  EMPNO ENAME       JOB            DEPTNO

            ---------- ---------- --------- ----------

                  7369 Henry       CLERK              20

                  7566 JONES       MANAGER             20

 

            flasher@ORCL11G > delete from tb1 where empno = 7369 ;

 

            flasher@ORCL11G > commit ;

 

            flasher@ORCL11G > select * from tb1 as of scn 2032782 ;

 

                  EMPNO ENAME       JOB            DEPTNO

            ---------- ---------- --------- ----------

                  7369 Henry       CLERK              20

                  7566 JONES       MANAGER            20      

           

        由以上可知,通过闪回查询获得所需的记录信息,然后来构造新的 DML 语句并实施其操作来保证数据的完整性。

   

二、 Flashback Table Query ( 闪回表查询 )

    通过查询 UNDO 段来抽取所有已变化的记录细节,在此基础之上再构造和执行能够倒退这些变化的语句

    表闪回通过执行倒退变化的语句并且该执行是一个事务,所有常用规则在该事务上起作用。

    表闪回时,表上的触发器缺省被禁用,即该表上的 DML 触发器将暂时失效,可以在闪回时指定触发器是否失效。

    表闪回需要启用表上的记录转移选项

   

    1. 下面给出表闪回的种方式

        FLASHBACK TABLE < schema_name . table_name >

        TO SCN < scn_number >             -- 基于 SCN 的表闪回

        [<ENABLE | DISABLE> TRIGGERS]

   

        FLASHBACK TABLE < schema_name . table_name >

        TO TIMESTAMP < timestamp >        -- 基于 TIMESTAMP 的表闪回

        [<ENABLE | DISABLE> TRIGGERS]

 

        FLASHBACK TABLE < schema_name . table_name >

        TO RESTORE POINT < restore_point >    -- 基于 RESTORE POINT 的表闪回

        [<ENABLE | DISABLE> TRIGGERS]

   

    2. 演示基于 SCN 的表闪回

        下面的演示首先创建表 tb_tables ,并对表分几次插入数据,在完成插入前记录其 SCN 号用于后续对其进行闪回

       

            create table tb_emp as           -- 创建演示表 tb_emp

            select empno , ename , job , deptno from scott . emp where 1 = 0 ;

 

            select table_name , row_movement from user_tables ; -- 查看表的 row movement 行为,缺省为 disable

 

            TABLE_NAME                       ROW_MOVE

            ------------------------------ --------

            TB_EMP                          DISABLED

       

            select current_scn , systimestamp from v$database ;   -- 获取系统当前的 SCN

            CURRENT_SCN SYSTIMESTAMP

            ----------- --------------------------------------

                  661490 01 - JAN - 11 10.56.28.733000 PM + 08 : 00

 

            insert into tb_emp          -- 插入 deptno 10 的员工

            select empno , ename , job , deptno from scott . emp where deptno = 10 ;

            commit ;

 

            select current_scn , systimestamp from v$database ;   -- 获取系统当前的 SCN

            CURRENT_SCN SYSTIMESTAMP

            ----------- --------------------------------------

                661510   01 - JAN - 11 10.56.56.546000 PM + 08 : 00

 

            insert into tb_emp         -- 插入 deptno 20 的员工

            select empno , ename , job , deptno from scott . emp where deptno = 20 ;

            commit ;

 

            select current_scn , systimestamp from v$database ;   -- 获取系统当前的 SCN

            CURRENT_SCN SYSTIMESTAMP

            ----------- --------------------------------------

                661521   01 - JAN - 11 10.57.17.358000 PM + 08 : 00

            

            insert into tb_emp        -- 插入 deptno 30 的员工

            select empno , ename , job , deptno from scott . emp where deptno = 30 ;

            commit ;

 

            select current_scn , systimestamp from v$database ; -- 获取系统当前的 SCN

            CURRENT_SCN SYSTIMESTAMP

            ----------- --------------------------------------

                  661539 01 - JAN - 11 10.57.37.843000 PM + 08 : 00

 

            select deptno , count (*) from tb_emp group by deptno order by 1 ;

           

                DEPTNO    COUNT (*)

            ---------- ----------

                    10           3

                    20           5

                    30           6

       

            flashback table tb_emp to scn   661521 ;     -- 将表闪回到 scn 为,即插入部门号为的记录之前

 

            flashback table tb_emp to scn 661521       -- 闪回失败,收到错误提示,没有开启 row movement

                            *

            ERROR at line 1 :

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

 

            alter table tb_emp enable row movement ;    -- 开启表 tb_emp 表的 row movement 功能

 

            flashback table tb_emp to scn   661521 ;     -- 再次实施闪回,闪回成功

 

            select deptno , count (*) from tb_emp group by deptno order by 1 ;   -- 记录中没有部门为 30 的记录

                DEPTNO    COUNT (*)

            ---------- ----------

                    10           3

                    20           5

       

            flashback table tb_emp to scn   661510 ;     -- 将表闪回到 scn 为,即插入部门号为 20 的记录之前    

 

            select deptno , count (*) from tb_emp group by deptno order by 1 ;   -- 记录中没有部门为 20 的记录

 

                DEPTNO    COUNT (*)

            ---------- ----------

                    10           3

           

    3. 演示基于 TIMESTAMP 的表闪回

        使用 to timestamp 进行表闪回 , 继续使用上面创建的表来进行闪回

           

            -- 使用 timestamp 将表闪回到插入部门号 10 为之前

            flashback table tb_emp to timestamp   to_timestamp ( '01-JAN-11 10.56.28.733000' );  

 

            flashback table tb_emp to timestamp   to_timestamp ( '01-JAN-11 10.56.28.733000' ) -- 收到错误提示

                            *

            ERROR at line 1 :

            ORA - 01466 : unable to read data - table definition has changed   -- 表结构发生改变

 

            flasher@ORCL11G > flashback table tb_emp to scn 661539 ;   -- 可以将表闪回到插入部门号为 30 的记录之后

 

            Flashback complete .

 

        此处演示中收到了错误提示,注意对于表闪回,可以多次使用同一类型的闪回方式,可以往前闪回,一旦往前闪回之后,也可以往后进行闪回。

        但交叉闪回则提示表定义发生了变化。闪回失败。我们可以再次创建一张类似的新表进行基于 timestamp 进行闪回,与闪回 SCN 说不同的

        是,此处使用了 timestamp, 此演示在此省略。

       

    4. 演示基于 RESTORE POINT 的表闪回

        基于 RESTORE POINT 的表闪回首先要创建适当的闪回点,创建闪回点的方式为

            CREATE RESTORE POINT point_name ;

        对于闪回成功之后,无用的闪回点可以及时删除掉,删除闪回点的方式为

            DROP RESTORE POINT point_name

        下面对基于 RESTORE POINT 闪回进行演示

       

            drop table tb_emp purge ;   -- 删除先前创建的表 tb_emp

 

            create table tb_emp     -- 创建演示表 tb_emp

            enable row movement

            as select empno , ename , job , deptno from scott . emp where 1 = 0 ;

 

            create restore point zero ;    -- 创建闪回点 zero

 

            insert into tb_emp            -- 插入 deptno 10 的员工

            select empno , ename , job , deptno from scott . emp where deptno = 10 ;

            commit ;

 

            create restore point one ;     -- 创建闪回点 one

 

            insert into tb_emp            -- 插入 deptno 20 的员工

            select empno , ename , job , deptno from scott . emp where deptno = 20 ;

            commit ;

 

            create restore point two ;     -- 创建闪回点 two

 

            insert into tb_emp            -- 插入 deptno 30 的员工

            select empno , ename , job , deptno from scott . emp where deptno = 30 ;

            commit ;

 

            select deptno , count (*) from tb_emp group by deptno order by 1 ;

           

                DEPTNO    COUNT (*)

            ---------- ----------

                    10           3

                    20           5

                    30           6

 

            flashback table tb_emp to restore point two ;    -- 闪回到闪回点 two 之前

 

            select deptno , count (*) from tb_emp group by deptno order by 1 ;

 

            flashback table tb_emp to restore point one ;    -- 闪回到闪回点 one 之前

                               

            select deptno , count (*) from tb_emp group by deptno order by 1 ;

           

                DEPTNO    COUNT (*)

            ---------- ----------

                    10           3

                   

            drop restore point two ;    -- 删除创建的闪回点

            drop restore point one ;

            drop restore point zero ;

 

    5. 存在参照关系的表闪回

        帐户 flasher 中表 tb1 与表 tb2 存在外键关系,表 tb1 deptno 参照了表 tb2 中的 deptno

        帐户 flasher 中表 tb1 scott . emp 具有相同的表结构,表 tb2 与表 scott . dept 具有相同的表结构

        下面为表 tb2 新增一个 deptno ,且为表 tb1 新增一条记录

       

            create table tb1        -- 基于表 scott.emp 来创建表 tb1

            enable row movement

            as select * from scott . emp ;

 

            create table tb2        -- 基于表 scott.dept 来创建表 tb2

            enable row movement

            as select * from scott . dept ;

 

            alter table tb1         -- 为表 tb1 添加主键约束

            add constraint tb1_empno_pk primary key ( empno );

 

            alter table tb2         -- 为表 tb2 添加主键约束

            add constraint tb2_deptno_pk primary key ( deptno );

 

            alter table tb1         -- 为表 tb1 添加外键约束

            add constraint tb1_tb2_deptno_fk foreign key ( deptno )

            references tb2 ( deptno );

 

            insert into tb2         -- 为表 tb2 插入一个新部门

            select 50 , 'Customer' , 'Landon' from dual ;

 

            insert into tb1 ( empno , ename , job , deptno )    -- 为表 tb1 插入一个新的雇员

            select 8000 , 'Robinson' , 'Clerk' , 50 from dual ;

 

            commit ;

 

            select current_scn from v$database ;    -- 获得当前的 scn

            --- 687444

 

            delete from tb1 where empno = 8000 ;      -- 删除先前新增的部门

 

            delete from tb2 where deptno = 50 ;       -- 删除先前新增的雇员

 

            commit ;

 

            flashback table tb1 to scn 687444 ;     -- 闪回先前删除的雇员

              /*

            ERROR at line 1:

            ORA-02091: transaction rolled back     -- 提示事务被回滚,外键没有找到

            ORA-02291: integrity constraint (FLASHER.TB1_TB2_DEPTNO_FK) violated - parent key not found */

 

            flashback table tb1 , tb2 to scn 687444 ;    -- 将两个表同时闪回

 

            select empno , ename , deptno , dname           -- 此时新增的雇员被闪回,部门也被闪回

            from tb1

            inner join tb2

            using ( deptno )

            where deptno = 50 ;

 

                  EMPNO ENAME           DEPTNO DNAME

            ---------- ---------- ---------- --------------

                  8000 Robinson            50 Customer

   

    6. 表闪回的几个常见问题

        a. 当闪回删除操作之前,如果某个键值如主键被重用,将导致违反主键约束,闪回失败。

        b. 若闪回所需要的 UNDO 信息不存在,将引发 ORA-08180 no snapshot found based on specified time( 未找到基于指定时间的快照 ) 错误

        c. 如果受闪回影响的记录被其它用户锁定,将引发 ORA-00054 resource busy and acquire with NOWAIT specified ( 资源忙碌 ) 错误

        d. 表定义在闪回期间不能发生变化,否则导致 ORA-01466 unable to read data - table definition has changed( 表定义已变化 ) 错误

        e. 闪回前未启用 row movement ,将收到 ORA-08189: cannot flashback the table because row movement is not enabled 错误

        f. 对于存在参照关系的情况,建议将主表等一起实施闪回,否则,将收到 ORA-02091: transaction rolled back ORA-02291 错误

        g . SYS 模式中的表不能使用表闪回技术

       

    7. 有关 ORA - 01466 的问题可以参考这里: Flashback 与ORA-01466

 

三、更多参考

有关闪回特性请参考

        Oracle 闪回特性(FLASHBACK DATABASE)

Oracle 闪回特性(FLASHBACK DROP & RECYCLEBIN)

 

有关基于用户管理的备份和备份恢复的概念请参考:

        Oracle 冷备份

        Oracle 热备份

        Oracle 备份恢复概念

        Oracle 实例恢复

        Oracle 基于用户管理恢复的处理 ( 详细描述了介质恢复及其处理 )

       

    有关 RMAN 的恢复与管理请参考:

        RMAN 概述及其体系结构

        RMAN 配置、监控与管理

        RMAN 备份详解

        RMAN 还原与恢复

       

    有关 Oracle 体系结构请参考:

        Oracle 实例和Oracle 数据库(Oracle 体系结构)

        Oracle 表空间与数据文

        Oracle 密码文件

        Oracle 参数文件

Oracle 数据库实例启动关闭过程

        Oracle 联机重做日志文件(ONLINE LOG FILE)

        Oracle 控制文件(CONTROLFILE)

        Oracle 归档日志

 

       

Oracle 闪回特性(Flashback Query、Flashback Table)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论