【原創】Oracle Flashback 知行合一

leonarding發表於2013-05-18

更多精彩內容盡在


Oracle Flashback  知行合一


資料庫版本

SYS@LEO1>select* from v$version;

BANNER

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

Oracle Database 11g Enterprise EditionRelease 11.2.0.1.0 - 64bit Production

PL/SQLRelease 11.2.0.1.0 - Production

CORE    11.2.0.1.0      Production

TNS forLinux: Version 11.2.0.1.0 - Production

NLSRTLVersion 11.2.0.1.0 - Production

交流區

今天又和大家見面了,おはようございます(日本見面語),剛剛看完火影記住了這麼一句。來讓我們看看今天講點什麼呢,喔上次講的是RMAN這個神奇的備份工具,這次我們繼續這個備份與恢復話題,從另一個角度來講一講10g剛剛出的一個新特性叫“FlashBack閃回”,可能大家注意到題目的最後四個字“知行合一”,為什麼要寫這四個字呢,它來自明朝一位猛人之口(當然不是宦官),他叫“王守仁”一位傑出的哲學家,他告訴我們學習知識,不能光空想,但也不能毫無頭緒的實踐。

知行合一:知是指科學知識,行是指人的實踐,所謂認識事物的道理與在現實中運用此道理,是密不可分的一回事。

要在知與行反覆的驗證中領悟原理,循序漸進,方可大成。

什麼是閃回:通俗易懂的講就是把你所做的事回退回去。比如你走路回家,但發現走錯了,怎麼辦?你可以按原來的方向倒著走回去,回退到起點,重新走一遍。它不同於redo,因為redo當發現錯誤時,即重新做一遍->前滾。

Flashback 是按照原來的路線回退回來->倒帶子->回滾。

Flashback閃回場景:

使用UNDO閃回&閃迴歸檔

(1)閃回查詢

(2)閃回版本查詢

(3)閃回事務查詢

(4)閃回表

使用recyclebin閃回

(5)閃回drop

使用閃回日誌

(6)閃回資料庫

Flashback可以解決:多種誤刪除(表誤刪除,資料誤刪除,資料庫誤刪除)和查詢過去某一時間點的歷史資料(不對現有資料做修改)

實驗

1.演示閃回查詢的三種方式,閃回查詢,閃回版本查詢,閃回事務查詢。

在閃回查詢中最常用的就是這三種

閃回查詢:檢視過去某一時間點的歷史資料,不對現有資料做修改,請記住這是閃回到過去的一個“時間點”。

Oracle內部都會把時間轉換成SCN號,也就是說即檢視過去某一個SCN號的歷史資料,讀undo資訊不修改現有資料

LEO1@LEO1>create table leo1 (x int,yint,z int);          建立一個表

Table created.

LEO1@LEO1>insert into leo1 values(1,1,1);              插入三行資料

1 row created.

LEO1@LEO1>insert into leo1values(2,2,2);

1 row created.

LEO1@LEO1>insert into leo1values(3,3,3);

1 row created.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>select * from leo1;                        已經commit

        X          Y          Z

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

        1          1          1

        2          2          2

        3          3          3

LEO1@LEO1>alter session setnls_date_format='yyyy-mm-dd hh24:mi:ss';  定義日期時間格式

Session altered.

LEO1@LEO1>select sysdate from dual;                                當前日期和時間

SYSDATE

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

2013-05-16 12:22:51

LEO1@LEO1>selectdbms_flashback.get_system_change_number from dual; 呼叫函式獲得scn

GET_SYSTEM_CHANGE_NUMBER

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

                 1108807

LEO1@LEO1>select current_scn fromv$database;                       這種方法也可以獲得

CURRENT_SCN

-----------

1108819

LEO1@LEO1>delete from leo1 where x=1 rx=2;           刪除2

2 rows deleted.

LEO1@LEO1>commit;

Commit complete.

LEO1@LEO1>select * from leo1;                         現在表裡還剩1

        X          Y          Z

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

        3          3          3

【參】Books->Application Developer’s Guide - Fundamentals -> 10 Developing FlashbackApplication -> Using Flashback Query (SELECT … AS OF)

如果我們想看看2013-05-1612:22:51時候,表裡的資料分佈情況怎麼辦呢,這時就用上了閃回查詢

使用時間戳構造閃回查詢

LEO1@LEO1>select * from leo1 as oftimestamp to_timestamp('2013-05-16 12:22:51','yyyy-mm-dd hh24:mi:ss');

        X          Y          Z

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

        1          1          1

        2          2          2

        3          3          3

使用SCN構造閃回查詢,scn timestamp 更精確,一個timestamp包含好幾個scn

LEO1@LEO1>select * from leo1 as of scn1108819;

        X          Y          Z

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

        1          1          1

        2          2          2

        3          3          3

這種閃回的資料,都來自undo段,如果undo資訊不夠用,才報ora-01555錯誤

它只是查詢過去時間的資料,表中的資料還是沒有變化

LEO1@LEO1>select * from leo1;

        X          Y          Z

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

        3          3          3

閃回版本查詢:顧名思義,這是基於資料版本閃回,查詢一個時間段內的資料變化,Oracle會記錄這個時間段內的所有資料版本和操作,任君選擇。每一次commit就算一個版本,讀undo資訊不修改現有資料

LEO1@LEO1>create table leo2 as select *from leo1;     我們建立一個leo2

Table created.

LEO1@LEO1>insert into leo2values(5,5,5);

commit;

insert into leo2 values(6,6,6);

commit;

insert into leo2 values(7,7,7);

commit;

update leo2 set x=55 where x=5;

commit;

update leo2 set x=66 where x=6;

commit;

update leo2 set x=77 where x=7;

commit;

delete from leo2;

commit;

我們插入3條記錄->更新3條記錄->全刪除

LEO1@LEO1>select * from leo2;

no rows selected

LEO1@LEO1>col versions_starttime fora30;

LEO1@LEO1>col versions_endtime for a30;

LEO1@LEO1>col versions_operation for a5;

LEO1@LEO1>selectversions_xid,versions_starttime,versions_endtime,versions_operation,x,y,z fromleo2 versions between timestamp minvalue and maxvalue;

VERSIONS_XID     VERSIONS_STARTTIME   VERSIONS_ENDTIME   VERSI          X          Y          Z

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

06000C004B030000 16-MAY-13 04.15.14 PM                     D              3          3          3

                                     16-MAY-1304.15.14 PM               3         3          3

06000C004B030000 16-MAY-13 04.15.14 PM                     D            77          7          7

06000C004B030000 16-MAY-13 04.15.14 PM                     D            66          6          6

06000C004B030000 16-MAY-13 04.15.14 PM                     D            55          5          5

0800170045030000 16-MAY-13 04.15.14PM16-MAY-13 04.15.14 PM  U             77          7          7

01001B008E020000 16-MAY-13 04.15.14PM16-MAY-13 04.15.14 PM  U             66          6          6

0A00130087020000 16-MAY-13 04.15.14PM16-MAY-13 04.15.14 PM  U             55          5          5

020018004C030000 16-MAY-13 04.15.14 PM16-MAY-13 04.15.14 PM  I              7          7          7

070016002B030000 16-MAY-13 04.15.14 PM 16-MAY-1304.15.14 PM  I              6          6          6

040010007A020000 16-MAY-13 04.15.14 PM 16-MAY-1304.15.14 PM  I              5          5          5

11 rows selected.

偽列說明

versions_startscn          版本起始scn

versions_endscn          版本結束scn

versions_starttime        版本開始時間

versions_endtime         版本結束時間

versions_operation        執行的操作

versions_xid              操作事務ID

timestamp minvalue and maxvalue    時間戳最小值與最大值

這是倒序,每一次commit稱為一個獨立版本040010007A020000 070016002B030000 020018004C030000 這是三次插入的版本x y z是修改後的值,0A00130087020000 01001B008E0200000800170045030000 是三次更新的版本,06000C004B030000是刪除的版本,刪除操作我們有三條記錄(告訴我們刪除了哪些內容)但版本號都是一樣的因此算一個版本,我們一共有7個版本。

現在我說明一下“閃回版本查詢”在實際中的應用,在生產中“閃回版本查詢”與“閃回事務查詢”結合使用的,

版本查詢可以讓DBA能夠獲得過去時間段中的所有改變而不是特定值,檢索出DBA想要查的那個事務ID,有了事務ID我們就可以結合“事務查詢”進行“事務閃回”,撤銷錯誤的事務操作。這個版本查詢也不是想查多久就查多久的,最大的可用版本依賴於undo_retention引數。如果不夠會報:ora-01555,下面我們看看,如何正確使用查詢到的版本。

閃回事務查詢:基於事務閃回,查詢過去某一個事務的歷史資料

事務:上一個commit,下一個commit就算一次事務,透過flashback_transaction_query檢視可以找到事務,然後撤銷事務檢視過去的歷史資料,讀undo資訊不修改現有資料

LEO1@LEO1>selectxid,logon_user,table_name,operation,undo_sql,row_id fromflashback_transaction_query where table_name='LEO2';
XID               LOGON_USER    TABLE_NAME    OPERATION   UNDO_SQL   ROW_ID

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

01001B008E020000  LEO1          LEO2           UNKNOWN                                                                                                                                                         

我們在查詢這個檢視的時候會發現,只有事務id,操作使用者,操作表這三列,其他都是unknown,這是因為oracle預設沒有提供這些詳細附加資訊,需要開啟附加選項才可,這和log miner的原理一樣。

切記需要重新開啟一個session執行如下操作

LEO1@LEO1>alter database addsupplemental log data;       啟動收集詳細資訊選項

Database altered.

重新執行一遍上面的DML操作,此處省略。。。。。。

LEO1@LEO1>select xid,logon_user,table_name,operation,undo_sql,row_idfrom flashback_transaction_query where table_name='LEO2';

XID  LOGON_USER TABLE_NAME  OPERATION  UNDO_SQL    ROW_ID                                                                  

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

0100010090020000 LEO1  LEO2 INSERT     delete from"LEO1"."LEO2" where ROWID = 'AAAR9rAAFAAAACMAAA';                    AAAR9rAAFAAAACMAAA

0900140043030000 LEO1  LEO2  INSERT     delete from"LEO1"."LEO2" where ROWID = 'AAAR9rAAFAAAACMAAB';                    AAAR9rAAFAAAACMAAB

040019007B020000 LEO1  LEO2  INSERT     delete from"LEO1"."LEO2" where ROWID = 'AAAR9rAAFAAAACMAAC';                    AAAR9rAAFAAAACMAAC

分段說明:這三條就是剛才我們做的插入操作,undo_sql欄位顯示插入操作的“逆操作”,如果我們做了誤操作的話,可以用給的逆操作SQL進行撤銷,大家會發現這裡還有一個rowid欄位,rowid表示這條記錄在物理磁碟上的地址,使用rowid來定位記錄是最快捷的。

020012004E030000 LEO1  LEO2 UPDATE  update"LEO1"."LEO2" set "X" = '5' where ROWID = 'AAAR9rAAFAAAACMAAA';           AAAR9rAAFAAAACMAAA

030019004C030000 LEO1  LEO2 UPDATE  update"LEO1"."LEO2" set "X" = '6' where ROWID ='AAAR9rAAFAAAACMAAB';          AAAR9rAAFAAAACMAAB

070001002E030000 LEO1  LEO2 UPDATE  update "LEO1"."LEO2" set "X" = '7' whereROWID = 'AAAR9rAAFAAAACMAAC';          AAAR9rAAFAAAACMAAC

這三條是我們剛做的update操作,如果發現更新誤操作了,可以用逆操作SQL撤銷

08000B0047030000 LEO1 LEO2 DELETE insert into"LEO1"."LEO2"("X","Y","Z")values ('77','7','7');                   AAAR9rAAFAAAACMAAC

08000B0047030000 LEO1 LEO2 DELETE insert into"LEO1"."LEO2"("X","Y","Z")values ('66','6','6');                   AAAR9rAAFAAAACMAAB

08000B0047030000 LEO1 LEO2 DELETE insert into"LEO1"."LEO2"("X","Y","Z")values ('55','5','5');                   AAAR9rAAFAAAACMAAA

這三個事務id全都一樣的記錄是我們delete操作,我們可以用insert語句進行撤銷

小結:到此我們三個閃回查詢全部完整的演示了一遍,總結一下,這三種方式的閃回共同點都是利用undo表空間的資料進行歷史資料查詢,不對現有資料作修改操作。我們在使用的時候要根據場景來綜合應用。


2.模擬一次ora-01555錯誤。

講之前闡述一下原理,我們要“知行合一”嘛,不要忘記

原因:就是當一個select查詢等待時間太長,這個過程中查詢的資料被修改完畢commit了,此時它的前映像就為inactive狀態,如果這時候有其他會話也想用undo段,就會把inactive狀態的回滾區覆蓋掉,這時正好select查詢完畢想讀取它的前映像,發現已經被覆蓋了,此時oracle會報ora-01555錯誤。理解原理很重要

我用一種叫做閃回查詢的功能來實現ora-01555

flashback query:原理也是使用undo segment中的前映像,來查詢出我們修改之前的資料映像,一般用於誤操作恢復。可以基於時間閃回還可以基於SCN號閃回,一秒鐘包括好幾個SCN號,不管基於什麼oracle內部都是按照SCN號順序操作的。只要我們查詢的原映像被覆蓋了,就會報ora-01555錯誤。

實驗

Oracle 11g時候已經有了解決方案了,隆重推出“閃迴歸檔”的方法,後面我會演示如何利用“閃迴歸檔”避免“ora-01555

我們就來演示下,當前映像被覆蓋後發生的ora-01555

SYS@LEO1>create undo tablespaceundotbs02 datafile '/u02/app/oracle/oradata/LEO1/undotbs02.dbf' size 5mautoextend off;

Tablespace created.

LEO1@LEO1>selecttablespace_name,file_name,autoextensible from dba_data_files wheretablespace_name='UNDOTBS02';

TABLESPACE_NAME     FILE_NAME                                     AUT

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

UNDOTBS02           /u02/app/oracle/oradata/LEO1/undotbs02.dbf         NO

建立一個新的undo表空間undotbs02,大小2m,設的小一點,方便我們迴圈覆蓋

SYS@LEO1>alter system setundo_tablespace='UNDOTBS02';     切換資料庫預設undo表空間

System altered.

SYS@LEO1>show parameter undo                                    

NAME                              TYPE      VALUE

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

undo_management                   string      AUTO

undo_retention                      integer     900

undo_tablespace                     string      UNDOTBS02

SYS@LEO1>create table leo3 as select *from dba_objects;          建立表leo3

Table created.

SYS@LEO1>select current_scn fromv$database;                  當前SCN

CURRENT_SCN

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

   1121723

SYS@LEO1>delete from leo3 whereobject_type in ('TABLE','INDEX');   刪除6752

6725 rows deleted.

SYS@LEO1>commit;                                          提交

Commit complete.

SYS@LEO1>select object_type from leo3 asof scn 1121723 where object_type in('TABLE','INDEX') and rownum<10;

OBJECT_TYPE

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

TABLE

INDEX

TABLE

TABLE

INDEX

TABLE

INDEX

INDEX

INDEX

大家看這些資料,就是從undo segment中讀取出來的,我們需要指定當時的SCN進行閃回查詢

作一個匿名塊,按順序迴圈覆蓋undo段,把SCN=1121723的前映像覆蓋後,我們再去查,就會報ora-01555

SYS@LEO1>show user

USER is "SYS"

SYS@LEO1>begin

for i in 1..10000 loop

delete from leo3 where object_type in('TABLE','INDEX');

rollback;

end loop;

end;

/

2    3    4   5    6    7  

PL/SQL procedure successfully completed.

SYS@LEO1>select object_type from leo3 asof scn 1121723 where object_type in('TABLE','INDEX') and rownum<10;

select object_type from leo3 as of scn1121723 where object_type in('TABLE','INDEX') and rownum<10

                        *

ERROR at line 1:

ORA-01555: snapshot too old: rollbacksegment number 10 with name "_SYSSMU10_3331052151$" too small

小結:經過不懈的努力,終於模擬出來ORA-01555錯誤,這也可以證明undo分配是按順序迴圈使用,不可跨區覆蓋,undo回收也是按順序迴圈回收,不可跨區回收。


3.演示誤刪除表後的恢復。

下面我們講解一下“閃回表”and“閃回drop”,這是2種不同的誤操作恢復,一種是恢復表中資料,一種是恢復被刪除的表。

閃回表:把現有表還原到過去某一時間點的狀態,對現有資料做修改,讀undo資訊

LEO1@LEO1>create table leo4 (x int,yint,z int);       建立一個leo4

Table created.

LEO1@LEO1>insert into leo4values(5,5,5);           插入3

1 row created.

LEO1@LEO1>insert into leo4values(6,6,6);

1 row created.

LEO1@LEO1>insert into leo4values(7,7,7);

1 row created.

;

Commit complete.

LEO1@LEO1>select * from leo4;                    檢視一下

        X          Y          Z

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

        5          5          5

        6          6          6

        7          7          7

LEO1@LEO1>select current_scn fromv$database;     作一個標記,標註我們要閃回的位置

CURRENT_SCN

-----------

   1124184

LEO1@LEO1>delete from leo4 where x=5 rx=6;       刪除2

2 rows deleted.

;

Commit complete.

LEO1@LEO1>select * from leo4;                     還剩1

        X          Y          Z

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

        7          7          7

LEO1@LEO1>alter table leo4 enable rowmovement;     啟動行移動

Table altered.

行移動:閃回後的行物理位置會發生變化,原來的位置可能被佔用,因為你在delete後就會給刪除的行打上delete標籤,凡是有這種標籤的行都可以被覆蓋的,如果新資料佔用了原來的位置覆蓋了老資料,那麼在閃回原來的行時就需要移動到新的物理位置存放。

LEO1@LEO1>flashback table leo4 to scn1124184;       閃回表到scn=1124184

Flashback complete.

LEO1@LEO1>select * from leo4;                     被刪除的表記錄恢復回來了

        X          Y          Z

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

        5          5          5

        6          6          6

        7          7          7

閃回drop:防止誤刪除表 drop table leo4;利用recyclebin回收站完成閃回,不在讀取undo資訊了

這次我們用的是回收站,回收站佔用的是表空間的儲存區,當空間緊張時回收站被擠佔,當空間被全部佔用時,回收站也就不存在了,每個表空間都有一個回收站,預設是開啟on

LEO1@LEO1>show parameter recyclebin

NAME                                 TYPE       VALUE

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

recyclebin                              string     on

LEO1@LEO1>create table leo5 (x int);

Table created.

LEO1@LEO1>insert into leo5 values(10);

1 row created.

LEO1@LEO1>drop table leo5;

Table dropped.

LEO1@LEO1>create table leo5 (x int);

Table created.

LEO1@LEO1>insert into leo5 values(100);

1 row created.

LEO1@LEO1>insert into leo5 values(200);

1 row created.

;

Commit complete.

LEO1@LEO1>drop table leo5;

Table dropped.

LEO1@LEO1>create table leo5 (x int);

Table created.

LEO1@LEO1>insert into leo5 values(1000);

1 row created.

LEO1@LEO1>insert into leo5 values(2000);

1 row created.

LEO1@LEO1>insert into leo5 values(3000);

1 row created.

;

Commit complete.

LEO1@LEO1>drop table leo5;

Table dropped.

同一張表被3drop,如果我們想恢復其中有三條記錄的leo5怎麼辦呢

ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME

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

LEO5             BIN$3ODW6UVvIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:26:22

LEO5             BIN$3ODW6UVuIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:25:13

LEO5             BIN$3ODW6UVtIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:24:08

LEO1@LEO1>selectoriginal_name,object_name,type from recyclebin;

ORIGINAL_NAME   OBJECT_NAME                    TYPE

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

LEO5             BIN$3ODW6UVvIjHgQKjAZAERuQ==$0TABLE

LEO5             BIN$3ODW6UVuIjHgQKjAZAERuQ==$0TABLE

LEO5             BIN$3ODW6UVtIjHgQKjAZAERuQ==$0TABLE

LEO1@LEO1>select * from tab;                  

TNAME                          TABTYPE  CLUSTERID

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

BIN$3ODW6UVtIjHgQKjAZAERuQ==$0 TABLE

BIN$3ODW6UVuIjHgQKjAZAERuQ==$0 TABLE

BIN$3ODW6UVvIjHgQKjAZAERuQ==$0 TABLE

我們用上述三種方式都可以看到回收站中的表,它會以一種特殊的方式來命名

LEO1@LEO1>select * from"BIN$3ODW6UVvIjHgQKjAZAERuQ==$0";

        X

----------

     1000

      2000

     3000

LEO1@LEO1>select * from"BIN$3ODW6UVuIjHgQKjAZAERuQ==$0";

        X

----------

      100

      200

LEO1@LEO1>select * from"BIN$3ODW6UVtIjHgQKjAZAERuQ==$0";

        X

----------

       10
看看回收站中被我們drop的三個版本,哪個是我們想要恢復的,其中有3條記錄是我們想要恢復的

對回收站中指定的內容進行閃回

LEO1@LEO1>flashback table"BIN$3ODW6UVvIjHgQKjAZAERuQ==$0" to before drop;

Flashback complete.

LEO1@LEO1>select * from leo5;

        X

----------

     1000

     2000

     3000

LEO1@LEO1>show recyclebin                         現在回收站還剩2個版本

ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME

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

LEO5             BIN$3ODW6UVuIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:25:13

LEO5             BIN$3ODW6UVtIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:24:08

清空回收站

LEO1@LEO1>purge table"BIN$3ODW6UVuIjHgQKjAZAERuQ==$0";        清空指定的表

Table purged.

LEO1@LEO1>show recyclebin;                                      已經清空

ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME

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

LEO5             BIN$3ODW6UVtIjHgQKjAZAERuQ==$0TABLE        2013-05-17:09:24:08

LEO1@LEO1>purge recyclebin;                                     清空所有表

Recyclebin purged.

LEO1@LEO1>show recyclebin;                                      

LEO1@LEO1>selectoriginal_name,object_name,type from recyclebin;     資料字典裡也沒有了

no rows selected

4.演示閃迴歸檔。

所謂閃迴歸檔:這是Oracle 11g新特性,儲存歷史undo到資料檔案,可以避免ora-01555,在11g之前是不儲存undo資料的,這種方式有利必有弊,如果我們想要的undo資料被覆蓋了就不能實現快速恢復和回滾操作。

閃迴歸檔原理:是從定義在表空間中的閃回基表來還原資料,預設undo資料保留期5分鐘,當然我們可以指定更長時間。Oracle會自動清除超出保留期的閃回基表。例如 保留期7天,過了7天自動刪除閃回基表

當然也允許手工刪除閃迴歸檔

1)刪除全部閃迴歸檔

Alter flashback archive fda1 purge all;

2)刪除1天之前的閃迴歸檔

Alter flashback archive fda1 purge beforetimestamp (systimestamp – interval ‘1’ day);

3)刪除scn123456之前的閃迴歸檔

Alter flashback archive fda1 purge beforescn 123456;

fbda程式:負責捕獲undo資料到閃回基表

實驗

建立存放閃回基表的表空間leo_flashback_1

LEO1@LEO1>create tablespaceleo_flashback_1 datafile '/u02/app/oracle/oradata/LEO1/leo_flashback_1.dbf'size 20m autoextend off;

Tablespace created.

LEO1@LEO1>conn / as sysdba              切換成sys管理員使用者

Connected.

指定表空間leo_flashback_1為預設閃迴歸檔fbda1存放目錄,保留期設定為7天,預設是5分鐘

SYS@LEO1>create flashback archivedefault fbda1 tablespace leo_flashback_1 retention 7 day;

Flashback archive created.

定義非預設閃迴歸檔fbda2,限額為10m(這個閃迴歸檔fbda2只能存放10m基表)保留期設定為30

SYS@LEO1>create flashback archive fbda2tablespace leo_flashback_1 quota 10m retention 30 day;

Flashback archive created.

SYS@LEO1>conn leo1/leo1;                  連結leo1

Connected.

建立表leo6使用預設閃迴歸檔fbda1保留期7

LEO1@LEO1>create table leo6 (namevarchar2(20),avg number,employment varchar2(30)) flashback archive;

Table created.

LEO1@LEO1>insert into leo6values('leonarding',18,'DBA');

1 row created.

LEO1@LEO1>insert into leo6values('tigerfish',28,'data analyze');

1 row created.

LEO1@LEO1>insert into leo6values('sun_vn',38,'develop engineer');

1 row created.

;

Commit complete.

LEO1@LEO1>select * from leo6;

NAME             AVG      EMPLOYMENT

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

leonarding          18       DBA

tigerfish            28       data analyze

sun_vn             38       develop engineer

LEO1@LEO1>select current_scn fromv$database;               標記當前scn=1128826

CURRENT_SCN

-----------

   1128826

LEO1@LEO1>delete from leo6 where avg=18or avg=38;          刪除2條記錄

2 rows deleted.

LEO1@LEO1>commit;

Commit complete.

[oracle@leonarding1 trace]$ tail -falert_LEO1.log

Fri May 17 15:26:31 2013

Starting backgroundprocess FBDA

Fri May 17 15:26:31 2013

FBDA started with pid=28,OS id=9328

告警日誌裡面顯示FBDA程式已經開始工作,開始捕捉undo資料寫入閃回表空間leo_flashback_1

定義一個新undo表空間

LEO1@LEO1>create undo tablespaceundotbs03 datafile '/u02/app/oracle/oradata/LEO1/undotbs03.dbf' size 20mautoextend off;

Tablespace created.

LEO1@LEO1>alter system setundo_tablespace='UNDOTBS03';         修改預設undo表空間為UNDOTBS03

System altered.

LEO1@LEO1>show parameter undo

NAME                                 TYPE      VALUE

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

undo_management                      string      AUTO

undo_retention                         integer    900

undo_tablespace                        string     UNDOTBS03  已經修改成功

LEO1@LEO1>drop tablespace undotbs02including contents and datafiles; 刪除原來的undo表空間

Tablespace dropped.

LEO1@LEO1>alter system flushbuffer_cache;                        清空undo緩衝區

System altered.

LEO1@LEO1>select * from leo6;                                  當下leo6表中只有1

NAME                       AVGEMPLOYMENT

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

tigerfish                    28 data analyze

LEO1@LEO1>select * from leo6 as of scn1128826;                   我們閃回到scn=1128826

NAME             AVG      EMPLOYMENT

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

leonarding          18       DBA

tigerfish            28       data analyze

sun_vn             38       develop engineer

這裡用到的undo映像就是閃迴歸檔中的,因為我們剛才的undo表空間已經刪除了,oracle在刪除之前利用fbda程式把undo映像寫入閃迴歸檔,我們才能看到現在的歷史資料,閃迴歸檔不修改現有資料哦:)

介紹一下閃迴歸檔資料字典

閃迴歸檔表空間資訊

LEO1@LEO1>select * fromdba_flashback_archive_ts;

FLASHBACK_ARCHIVE_NAME     FLASHBACK_ARCHIVE#  TABLESPACE_NAME      QUOTA_IN_MB

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

FBDA1                       1                    LEO_FLASHBACK_1

FBDA2                       2                    LEO_FLASHBACK_1       10

閃迴歸檔資訊

LEO1@LEO1>select FLASHBACK_ARCHIVE_NAME,RETENTION_IN_DAYS,STATUSfrom dba_flashback_archive;

FLASHBACK_ARCHIVE_NAME         RETENTION_IN_DAYS       STATUS

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

FBDA1                                          7         DEFAULT

FBDA2                                         30

閃迴歸檔基表

LEO1@LEO1>selecttable_name,flashback_archive_name,archive_table_name,status fromdba_flashback_archive_tables;

TABLE_NAME   FLASHBACK_ARCHIVE_NAME     ARCHIVE_TABLE_NAME         STATUS

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

LEO6           FBDA1                       SYS_FBA_HIST_73594           ENABLED

LEO6表是透過SYS_FBA_HIST_73594閃回基表恢復的,基本字尾id就是原表的物件號

LEO1@LEO1>select object_name fromdba_objects where object_id=73594;

OBJECT_NAME

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

LEO6

LEO1@LEO1>selecttable_name,tablespace_name from user_tables;

TABLE_NAME                     TABLESPACE_NAME

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

SYS_FBA_DDL_COLMAP_73594       LEO_FLASHBACK_1    leo6表結構改變記錄

SYS_FBA_TCRV_73594              LEO_FLASHBACK_1    每次事務改變記錄

SYS_TEMP_FBT                                        臨時閃回表

SYS_FBA_HIST_73594                                   每個欄位改變記錄

調整配額為12M

LEO1@LEO1>alter flashback archive fbda2modify tablespace leo_flashback_1 quota 12m;

Flashback archive altered.

調整保留期為1

LEO1@LEO1>alter flashback archive fbda2modify retention 1 day;

Flashback archive altered.

刪除fbda2閃迴歸檔

LEO1@LEO1>drop flashback archive fbda2;

Flashback archive dropped.

撤銷leo6表的閃迴歸檔屬性

LEO1@LEO1>alter table leo6 no flashbackarchive;

Table altered.

小結:在使用閃迴歸檔時,請注意配額限制和保留期限制,在建立表的時候要指定閃迴歸檔屬性才行。

5.演示閃回資料庫

閃回資料庫:把整個庫回退到過去的某一狀態,這是基於閃回日誌的回退。Oracle 10g才剛剛引入新特性,是透過後臺程式RVWR來寫入閃回日誌的。

閃回資料庫原理:啟動閃回前提條件是開啟歸檔,歸檔日誌可以輔助閃回日誌完成閃回工作,往回閃不用歸檔,往前閃會用到歸檔。日誌塊每三秒鐘定期採集一次前映像,比如想恢復到10點的狀態,而我們只能閃回到9:55分,還差五分鐘內容就需要歸檔日誌or重做日誌來進行前滾恢復。

閃回要求資料庫為歸檔狀態,如果沒有啟動alter  database archivelog;   執行這條命令啟動歸檔

LEO1@LEO1>conn / as sysdba

Connected.

SYS@LEO1>archive log list

Database log mode             Archive Mode

Automatic archival             Enabled

Archive destination             /u02/app/oracle/archdata

Oldest online log sequence      3

Next log sequence to archive     5

Current log sequence           5

確認資料庫是否開啟了flashback功能

SYS@LEO1>select flashback_on fromv$database;      還沒有啟動,這是抓取控制檔案資訊

FLASHBACK_ON

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

NO

修改db_recovery_file_dest快速恢復區目錄和db_recovery_file_dest_size快速恢復區大小兩個引數,這是存放閃回日誌的地方,必須被指定

[oracle@leonarding1 oracle]$ mkdirflashback_area                    建立一個快速恢復區目錄

SYS@LEO1>alter system setdb_recovery_file_dest_size=1g;                        先設定大小

System altered.

SYS@LEO1>alter system setdb_recovery_file_dest='/u02/app/oracle/flashback_area';   再設定路徑

System altered.

指定閃回日誌保留期2(2880分鐘)

SYS@LEO1>alter system setdb_flashback_retention_target=2880 scope=both;

System altered.

SYS@LEO1>shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

SYS@LEO1>startup mount                         啟動到mount狀態

ORACLE instance started.

Total System Global Area  471830528 bytes

Fixed Size                  2214456 bytes

Variable Size             222299592 bytes

Database Buffers          239075328 bytes

Redo Buffers                8241152 bytes

Database mounted.

SYS@LEO1> show parameter db_recovery                      快速恢復區已經設定好了

NAME                             TYPE       VALUE

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

db_recovery_file_dest                string       /u02/app/oracle/flashback_area

db_recovery_file_dest_size            big integer  1G

SYS@LEO1>alter database flashback on;              mount狀態下才能啟動flashback功能

Database altered.

SYS@LEO1>alter database open;                    開啟資料庫

Database altered.

SYS@LEO1>select flashback_on fromv$database;      確認flashback功能已經成功開啟

FLASHBACK_ON

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

YES

SYS@LEO1>create table leo10 as select *from dba_objects;          建立個表

Table created.

SYS@LEO1>select count(*) from leo10;                           72200條記錄

COUNT(*)

----------

    72200

SYS@LEO1>select current_scn fromv$database;                    標記scn

CURRENT_SCN

-----------

   1144328

SYS@LEO1>drop table leo10 purge;                              直接刪除

Table dropped.

SYS@LEO1>show recyclebin                                    不進回收站

SYS@LEO1>

如果我們想把leo10表恢復回來有幾種方法呢,第一RMAN恢復  第二 Flashback 閃回資料庫

如果要閃回資料庫,在檔案開啟的狀態下是不可應用閃回日誌的,因此我們切換到mount狀態

SYS@LEO1>shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

SYS@LEO1>startup mount                                 

ORACLE instance started.

Total System Global Area  471830528 bytes

Fixed Size                  2214456 bytes

Variable Size             222299592 bytes

Database Buffers          239075328 bytes

Redo Buffers                8241152 bytes

Database mounted.

SYS@LEO1>alter session set nls_date_format='yyyy-mon-ddhh24:mi:ss';

Session altered.

SYS@LEO1>select oldest_flashback_timefrom v$flashback_database_log;           允許閃回的最早時間

OLDEST_FLASHBACK_TIM

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

2013-may-18 10:00:12

SYS@LEO1>select oldest_flashback_scnfrom v$flashback_database_log;           允許閃回的最早scn

OLDEST_FLASHBACK_SCN

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

            1143915

SYS@LEO1>flashback database to scn1144328;                               閃回到刪除之前

Flashback complete.

SYS@LEO1>alter database open resetlogs;                               非一致性開啟資料庫

Database altered.

1.資料檔案頭scn同步控制檔案

2.清空redo日誌,重置狀態為unused

3.歸檔日誌編碼從1開始

4.資料庫進入一個新的生命週期

SYS@LEO1>select count(*) from leo10;                                 完美恢復

COUNT(*)

----------

    72200

補充:不同粒度級別的閃回

基於時間點閃回

flashback database totime="to_date('2013-05-16 12:00:00','yyyy-mm-dd hh24:mi:ss')";

基於時間戳閃回,閃回到1小時之前

flashback database totimestamp(sysdate-1/24);

基於SCN號閃回

flashback database to scn 1144328;

基於日誌序號閃回

flashback database to sequence=1000thread=1;

基於還原點閃回

flashback database to restore pointleo_point1;

小結:我們可以根據實際情況來綜合分析使用哪種閃回,注意閃回資料庫是對整個庫進行閃回,所有的session操作都會還原,這是一種極端情況下的還原謹慎使用。

閃回查詢 閃回版本 閃回事務閃迴歸檔 閃回資料庫 01555




2013.5.18
天津&spring
分享技術~成就夢想
Blog



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26686207/viewspace-761416/,如需轉載,請註明出處,否則將追究法律責任。

相關文章