闪回技术(1)

本文详细介绍了在数据库操作中遇到事务故障时如何使用Oracle的闪回技术进行恢复,包括设置undo参数、启动闪回和附加日志、权限配置等步骤,以及闪回查询、版本查询和事务回滚的具体操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       在工作当中时常会出现这么一种情况:修改错了数据,或者误删了数据,或者插入了一些不应该插入的数据。这种情况不是实例崩溃,也没有出现介质损坏,只是正常工作中出现了操作事务,并没有使得数据库处于不一致的状态。这此时是事务故障。为了处理这些故障,ORACLE提供了闪回技术。除了闪回删除是通过recyclebin来恢复之外,其他的都利用了undo撤销段来进行恢复。为了维护一致性,数据库在读出需要修改的数据块到高速缓冲区的时候,都会同时复制一份到撤销段中。一来,可以方便对数据块修改的时候,其他用户访问该数据块;二来,如果需要回滚的时候,可以利用撤销段的这些数据来回滚。而且这些数据会保存在撤销段中一段时间,直到被重写。为此,可以通过这些undo数据来进行事务故障的恢复。

一、准备

1、undo

      既然前面所说了,闪回技术除了闪回删除之外是利用撤销段的数据进行恢复的。为此,撤销段必须存在,并且应该具有足够的空间以满足闪回的需求。需要注意的是下面三个参数:

SQL> show parameter undo;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------
undo_management                      string      AUTO    ---撤销段的管理方式;
undo_retention                       integer     900     ---撤销段数据的保留时间,过了这个时间,就会过期;
undo_tablespace                      string      UNDOTBS1---撤销段表空间;

2、启动

     需要在加载的状态下,启动闪回和附加日志。并且需要让数据库处于归档模式。

alter database flashback on;---启动闪回;
alter database add supplemental log data;---添加附加日志;
alter database archivelog;---归档模式;
---可以通过下面的方式查看上面这些的状态;
SQL> select log_mode,flashback_on,supplemental_log_data_min,supplemental_log_data_pk,supplemental_log_data_ui from v$database;

LOG_MODE     FLASHBACK_ON       SUPPLEME SUP SUP
------------ ------------------ -------- --- ---
ARCHIVELOG   YES                YES      NO  NO

/*supplemental_log_data_min,supplemental_log_data_pk,supplemental_log_data_ui
 *上面三个有一个为YES,表示附加日志已经启动;
 */

3、权限

      Oracle Flashback Query and Oracle Flashback Version Query需要flashback any table权限;

      Oracle Flashback Transaction Query需要select any transaction权限;

      调用DBMS_FLASHBACK包,需要该包的execute权限;

      闪回归档需要flashback archive administer权限;

grant flashback any table to sh;---授予flashback any table 权限;
grant select any transaction to sh;---授予select any transaction 权限;
grant execute on dbms_flashback to sh;---授予dbms_flashabck的execute权限;
grant flashback archive administer to sh;---授予flashback archive administer权限;

二、闪回查询

       闪回查询的一个基本功能就是,确定什么时候进行了什么操作。可以通过下面四种方法来查询过去的信息

  • select ..as of scn|timestamp....;
  • select versions_startscn,versions_starttime,versions_endscn,versions_endtime,versions_xid,versions_operation....VERSIONS {BETWEEN {SCN | TIMESTAMP} start  AND  end };
  • ORA_ROWSCN;
  • flashback_transaction_query;

具体操作如下:

---准备数据
SQL>create table t(
  2 id int,
  3 num int);
SQL>begin
  2 insert into t
  3 select 1,100 from dual union all
  4 select 2,200 from dual;
  5 commit;
  6 update t set num = 1111 where id =2;
  7 commit;
  8 update t set num = 2222 where id =2;
  9 commit;
 10 delete from t where id =2;
 11 commit;
 12 insert into t
 13 select 2,3333 from dual;
 14 commit;
 15 end;
 16 / 
      闪回查询:select ...as of scn|timestamp..
SQL> select * from t as of scn 2406855 ;

        ID        NUM
---------- ----------
         1        100
         2       3333     
       闪回版本查询:从下面的结果中可以看到,有两行的versions_starttime一样,但是versions_endtime一个为空,一个不为空,其实这表示这两行数据是同时插入的,也就是在插入完第二行数据的时候才commit。另外,对于同一行数据,在插入之后先后经过了两次的UPDATE,一次DELETE。DELETE的versions_endtime为空表示该行数据已经被删除,不在存在。
SQL> col versions_xid format a20;
SQL> col versions_starttime format a30;
SQL>  col versions_endtime format a30;
SQL> set linesize 150 pagesize 100;
SQL> select versions_xid,versions_startscn,versions_starttime,versions_endscn,versions_endtime,versions_operation,id,num from t versions between scn 2
406798 and 2406855 order by versions_startscn;

VERSIONS_XID         VERSIONS_STARTSCN VERSIONS_STARTTIME             VERSIONS_ENDSCN VERSIONS_ENDTIME               V         ID        NUM
-------------------- ----------------- ------------------------------ --------------- ------------------------------ - ---------- ----------
08000E00C5050000               2406800 05-8月 -13 10.40.58 下午                                                      I          1        100
08000E00C5050000               2406800 05-8月 -13 10.40.58 下午               2406823 05-8月 -13 10.41.31 下午       I          2        200
03002100E6050000               2406823 05-8月 -13 10.41.31 下午               2406830 05-8月 -13 10.41.46 下午       U          2       1111
08001900C4050000               2406830 05-8月 -13 10.41.46 下午               2406846 05-8月 -13 10.42.04 下午       U          2       2222
05001200E1060000               2406846 05-8月 -13 10.42.04 下午                                                      D          2       2222
08000500C6050000               2406855 05-8月 -13 10.42.28 下午                                                      I          2       3333
        通过flashback_transaction_query查询:可以利用该视图,查看到对应变化的事务ID,以及undo_sql,可以进行事务回滚。
SQL> col xid format A20;
SQL> col row_id format A20;
SQL> col undo_sql format A40;
SQL> set linesize 150 pagesize 100;
SQL> col table_name format A10;
SQL> col table_owner format A10;
SQL> col logon_user format a10;
SQL> col operation format A6;
SQL> select xid,start_scn,commit_scn,undo_change#,operation,row_id,undo_sql from flashback_transaction_query where table_name ='T' order by start_scn;

XID                   START_SCN COMMIT_SCN UNDO_CHANGE# OPERAT ROW_ID               UNDO_SQL
-------------------- ---------- ---------- ------------ ------ -------------------- ----------------------------------------
08000E00C5050000        2406798    2406800            2 INSERT AAASX1AAEAAAAI8AAB   delete from "SH"."T" where ROWID = 'AAAS
                                                                                    X1AAEAAAAI8AAB';

08000E00C5050000        2406798    2406800            1 INSERT AAASX1AAEAAAAI8AAA   delete from "SH"."T" where ROWID = 'AAAS
                                                                                    X1AAEAAAAI8AAA';

03002100E6050000        2406821    2406823            1 UPDATE AAASX1AAEAAAAI8AAB   update "SH"."T" set "NUM" = '200' where
                                                                                    ROWID = 'AAASX1AAEAAAAI8AAB';

08001900C4050000        2406828    2406830            1 UPDATE AAASX1AAEAAAAI8AAB   update "SH"."T" set "NUM" = '1111' where
                                                                                     ROWID = 'AAASX1AAEAAAAI8AAB';

05001200E1060000        2406844    2406846            1 DELETE AAASX1AAEAAAAI8AAB   insert into "SH"."T"("ID","NUM") values
                                                                                    ('2','2222');

08000500C6050000        2406853    2406855            1 INSERT AAASX1AAEAAAAI8AAC   delete from "SH"."T" where ROWID = 'AAAS
                                                                                    X1AAEAAAAI8AAC';
        利用ora_rowscn查询:ora_rowscn表示的是对应行最近commit的时间。不过,需要注意的是,如果你想把数据恢复到ORA_ROWSCN指定的时间的话,有可能会不成功,因为考虑到并发性因素,可能在数据恢复的过程中,ORA_ROWSCN已经发生了变化,因为其他用户可能修改该行数据,并且提交了,改变了ORA_ROWSCN。
SQL> select ora_rowscn,id,num from t;

ORA_ROWSCN         ID        NUM
---------- ---------- ----------
   2406855          1        100
   2406855          2       3333

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值