暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle 闪回查询、闪回版本查询、闪回事务查询

oracleEDU 2017-09-25
765

闪回查询 -- 查询过去某一个时刻的状态 ( 查询的是已经提交的数据 )

闪回版本查询 -- 查询一个时间段内做那些操作

闪回事务查询 -- 核心是事务的相反语句(undo SQL),可以还原整个事务也可以撤销事务部分数据

① 闪回查询

示例:

当前scott.emp表中scott的工资

SQL> select ename ,sal from scott.emp;

ENAME             SAL

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

SMITH             800

WARD             1250

MARTIN           1250

TURNER           1500

ADAMS            1100

JAMES             950

MILLER           1300

ALLEN            1600

JONES            2975

BLAKE            2850

CLARK            2450

SCOTT            3000       #这是scott的工资 

KING             5000

FORD             3000

修改Scott的工资

update scott.emp set sal=0 where ename ='SCOTT';

commit;

select ename ,sal from scott.emp where ename ='SCOTT';

ENAME             SAL

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

SCOTT               0

要查出scott原来的工资多少,然后恢复原来的工资

查询过去某个时刻的语法:

select   字段名,.....

from 表名

AS OF TIMESTAMP <T1>  或者 scn

where 条件

查1分钟前scott的工资

SQL> select ename ,sal from scott.emp  as of timestamp(sysdate-5/1440) where ename ='SCOTT'; 

ENAME             SAL

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

SCOTT               0

查10分钟前scott的工资

SQL> select ename ,sal from scott.emp  as of timestamp(sysdate-10/1440)

where ename ='SCOTT';

ENAME             SAL

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

SCOTT            3000

如何表示过去的某个时间

1分钟前:    sysdate -1/1440

5分钟前:    sysdate -5/1440

1小时前:   sysdate -1/24

1天前    sysdate -1

查具体的过去的某个时间

select ename ,sal from scott.emp  as of timestamp to_timestamp('2017-9-25 17:00:00','yyyy-mm-dd hh24:mi:ss') ;

恢复

update scott.emp set sal=(select sal from scott.emp as of timestamp(sysdate-10/1440) where ename ='SCOTT') where ename ='SCOTT';

commit;

SQL> select ename ,sal from scott.emp where ename ='SCOTT';

ENAME             SAL

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

SCOTT            3000

恢复删除的数据

delete from scott.emp where rownum <=4;

commit;

原来14条,现在10条,查出到底哪4条数据被删除了

select * from scott.emp as of timestamp(sysdate -5/1440) minus select * from scott.emp;

还原

insert into scott.emp (select * from scott.emp as of timestamp(sysdate -5/1440) minus select * from scott.emp);

建立一张视图v_15, 可以查看scott.emp表15分钟的数据

create or replace view v_15 as select * from scott.emp as of timestamp(system - 15/1440);

② 闪回版本查询

伪列:

versions_xid     事务编号

versions_startscn    起始的SCN

versions_endscn    结束SCN号 如果有值,证明这记录已非当前记录

versions_starttime    起始时间

versions_endtime    结束时间

versions_operation    操作类型

VERSIONS_OPERATION说明:

I    插入

D    删除

U    更新

语法:

SELECT versions_xid, to_char(versions_starttime ,'yyyy-mm-dd hh24:mi:ss'),VERSIONS_OPERATION ,字段名

from 表名

VERSIONS BETWEEN TIMESTAMP <t1> and <t2>

WHERE 条件 

示例:

  1. 建立scott.e表, 和scott.emp一样

    create table scott.e as select * from scott.emp;

  2. 查看当前时间

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

    TO_CHAR(SYSDATE,'YY

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

    2017-09-25 00:35:19

  3. 执行3个事务

    update scott.e set sal=0 where empno =7788;

    commit;

    update scott.e set sal=1 where empno =7788;

    commit;

    delete from scott.e  where empno =7788;

    commit;

    select empno,ename ,sal from scott.e where empno =7788;

    no rows selected

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

    TO_CHAR(SYSDATE,'YY

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

    2017-09-25 00:36:51

     

  4. 查出scott.e表在该时间段内发生了哪些操作

    select versions_xid, to_char(versions_starttime,'yyyy-mm-dd hh24:mi:ss') ,versions_operation ,ename ,sal from scott.e VERSIONS BETWEEN TIMESTAMP  to_timestamp('2017-09-25 00:35:19','yyyy-mm-dd hh24:mi:ss') and to_timestamp('2017-09-25 00:36:51','yyyy-mm-dd hh24:mi:ss') where empno=7788;

    VERSIONS_XID     TO_CHAR(VERSIONS_ST V ENAME             SAL

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

    03000D0045030000 2017-09-25 00:35:53 D SCOTT               1

    090012003D030000 2017-09-25 00:35:53 U SCOTT               1

    0A00110073020000 2017-09-25 00:35:48 U SCOTT               0

                                                                           SCOTT            3000

     

  5. select ename ,sal from scott.emp as of timestamp to_timestamp('2017-09-25 00:35:48','yyyy-mm-dd hh24:mi:ss') where ename ='SCOTT';

        ENAME             SAL

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

        SCOTT            3000

    闪回版本查询提供了两个参数minvalue、 maxvalue 

    select versions_xid, to_char(versions_starttime,'yyyy-mm-dd hh24:mi:ss') ,versions_operation ,ename ,sal from scott.e VERSIONS BETWEEN TIMESTAMP   minvalue and maxvalue where empno=7788;

    VERSIONS_XID     TO_CHAR(VERSIONS_ST V ENAME             SAL

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

    03000D0045030000 2017-09-25 00:35:53 D SCOTT               1

    090012003D030000 2017-09-25 00:35:53 U SCOTT               1

    0A00110073020000 2017-09-25 00:35:48 U SCOTT               0

                                                                           SCOTT            3000

    如果要找回记录:

    insert into scott.emp (select *  from scott.emp as of timestamp to_timestamp('2017-09-25 00:35:48','yyyy-mm-dd hh24:mi:ss') where empno =7788);

    commit;    

③ 闪回事务查询

必须先开启补全日志

alter database add supplemental log data;

alter database add supplemental log data (primary key) columns;  (必须是有主键的表)

示例:

用户执行一个事务

update scott.emp set sal=sal+1000;

commit;

操作完发现不应该修改scott的sal,需要将scott还原,其余的不变

(先找出是哪个事务 -- 版本查询 --

再找出事务ID -- 找出UNDO SQL -- 执行恢复)

通过版本查询,查出时间和事务编号

select versions_xid, to_char(versions_starttime,'yyyy-mm-dd hh24:mi:ss') ,versions_operation ,ename ,sal from scott.emp VERSIONS BETWEEN TIMESTAMP minvalue   and  maxvalue where empno=7788;

VERSIONS_XID     TO_CHAR(VERSIONS_ST V ENAME             SAL

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

07001A0068020000 2017-09-25 00:58:34 U SCOTT            4000

                                       SCOTT            3000

事务编号 07001A0068020000 

通过事务编号去找 FLASHBACK_TRANSACTION_QUERY

select  OPERATION,TABLE_NAME,ROW_ID ,UNDO_SQL from FLASHBACK_TRANSACTION_QUERY where XID='07001A0068020000';

select UNDO_SQL from FLASHBACK_TRANSACTION_QUERY where XID='07001A0068020000';

UNDO_SQL

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

update "SCOTT"."EMP" set "SAL" = '2975' where ROWID = 'AAASR/AAEAAAAI9AAD';

update "SCOTT"."EMP" set "SAL" = '1250' where ROWID = 'AAASR/AAEAAAAI9AAC';

update "SCOTT"."EMP" set "SAL" = '1600' where ROWID = 'AAASR/AAEAAAAI9AAB';

update "SCOTT"."EMP" set "SAL" = '800' where ROWID = 'AAASR/AAEAAAAI9AAA';

update "SCOTT"."EMP" set "SAL" = '1300' where ROWID = 'AAASR/AAEAAAAI8AAN';

update "SCOTT"."EMP" set "SAL" = '3000' where ROWID = 'AAASR/AAEAAAAI8AAM';

update "SCOTT"."EMP" set "SAL" = '950' where ROWID = 'AAASR/AAEAAAAI8AAL';

update "SCOTT"."EMP" set "SAL" = '1100' where ROWID = 'AAASR/AAEAAAAI8AAK';

update "SCOTT"."EMP" set "SAL" = '1500' where ROWID = 'AAASR/AAEAAAAI8AAJ';

update "SCOTT"."EMP" set "SAL" = '5000' where ROWID = 'AAASR/AAEAAAAI8AAI';

update "SCOTT"."EMP" set "SAL" = '3000' where ROWID = 'AAASR/AAEAAAAI8AAH';

update "SCOTT"."EMP" set "SAL" = '2450' where ROWID = 'AAASR/AAEAAAAI8AAG';

update "SCOTT"."EMP" set "SAL" = '2850' where ROWID = 'AAASR/AAEAAAAI8AAF';

update "SCOTT"."EMP" set "SAL" = '1250' where ROWID = 'AAASR/AAEAAAAI8AAE';

SQL> select rowid ,ename  ,sal from scott.emp where ename = 'SCOTT';

ROWID              ENAME             SAL

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

AAASR/AAEAAAAI8AAH SCOTT            4000

begin 

update "SCOTT"."EMP" set "SAL" = '3000' where ROWID = 'AAASR/AAEAAAAI8AAH';

commit;

end;

/

闪回查询只能 找出undo-sql 还需要人工去执行语句.

参考手册:

Advanced Application Developer's Guide -- 12 Using Oracle Flashback Technology

Using Oracle Flashback Version Query

最后修改时间:2021-04-28 20:10:10
文章转载自oracleEDU,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论