通過查詢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 模式中的表不能使用表閃回技術

 

 

ref:
https://www.796t.com/content/1521735669.html

arrow
arrow
    文章標籤
    oracle
    全站熱搜

    噗噗噗的潛水珽 發表在 痞客邦 留言(0) 人氣()