1. 程式人生 > >oracle FLASHBACK介紹——閃退、回滾

oracle FLASHBACK介紹——閃退、回滾

在介紹flashback之前先介紹下undo_retention相關引數

undo_retention:表示undo資料的過期時間。系統預設這個時間設定為900即15分鐘。但要注意,保證undo資料在這個時間內有效的前提是undo表空間有

                        足夠的空間儲存。如果undo空間已滿且又有新事務執行則會覆蓋原來的undo資料而不管undo資料是否過期。不過,如果undo空間足夠,

                        儘管undo資料已經   過了指定的時間,只要不被覆蓋,該undo資料還是存在,因此也還是能夠被執行flashback閃回(但是必須在增刪改

                        表記錄之前先執行alter table table_name enable row movement即允許該表進行行移動,否則過了指定的時間該undo資料儘管沒被

                        覆蓋也會無法閃回了,會提示ora-01466錯誤)。

    如果想確保undo資料有效期為undo_retention指定的時間,可以通過 為undo表空間指定Retention Guarantee,如下:

Alter tablespace undotbs1 retention guarantee;(禁止的話執行:Alter tablespace undotbs1 retention noguarantee;
這樣就可以保證undo表空間儘管已經滿了,有新事務出現也不會去覆蓋未過期的undo資料。當然此時的新事務執行就要卡住了。  具體參考http://blog.itpub.net/post/602/469270 建立表並插入資料     
CREATE TABLE flashback_test (a VARCHAR2(255),b VARCHAR2(255),c VARCHAR2(255));
INSERT INTO flashback_test VALUES('d1','s','s');
INSERT INTO flashback_test VALUES('d2','sw','sf');
INSERT INTO flashback_test VALUES('d3','swd','ss');

刪除資料
DELETE FROM flashback_test WHERE a='d1';
--基於TIMESTAMP時間的返回查詢

SELECT *FROM flashback_test AS OF TIMESTAMP SYSDATE - 15/1440;
提示ORA-01466:無法讀取資料-表定義已更改
但是沒有做過表修改啊,奇怪了
DELETE FROM flashback_test WHERE a='d2';
SELECT *FROM flashback_test AS OF TIMESTAMP SYSDATE - 10/1440;
1    d2    sw    sf
2    d3    swd    ss
但是第一條記錄找不回來了,看來返回查詢只能在一定時間內,超過了該時間就無法查詢了。

--基於SCN的返回查詢 查詢某個時刻的scn
SQL> select timestamp_to_scn(to_date('20100105160606','yyyy-mm-dd hh24:mi:ss')) from dual; 檢視scn
select dbms_flashback.get_system_change_number from dual;
select current_scn from v$database;  

GRANT EXECUTE ON dbms_flashback TO fyzh_ora;--授權一般使用者可執行dbms_flashback包
SELECT dbms_flashback.get_system_change_number FROM dual;--檢視當前的SCN
SELECT *FROM flashback_test AS OF SCN 12486407805791
1    d3    swd    ss

FLASHBACK TABLE只是針對表的增刪改操作進行閃回

通過如下語句可以準確的獲取當前的時間點
SQL>  variable scn number;
SQL>  exec :scn:=dbms_flashback.get_system_change_number (scn為3373273)
select count(1) from t;--20000條記錄
delete from t;
select count(1) from t;--現在只有0條記錄

select count(1) from t as of scn :scn;查詢在刪之前的某個時間點,資料仍是20000條

現在將表閃回到3373273這個點
flashback table t to scn:scn;
提示“ORA-08189: 因為未啟用行移動功能, 不能閃回表”錯誤,執行如下語句
alter table t enable row movement;--允許對行rowid進行移動

再進行閃回
flashback table t to scn:scn;

此時再查詢該表
select count(1) from t;恢復了20000條記錄。

我們也可以通過flashback_transaction_query這個檢視中獲取想要閃回的時間點。

--TRUNCATE TABLE 操作的閃回實驗
TRUNCATE TABLE flashback_test;
SELECT * FROM flashback_transaction_query WHERE table_name='FLASHBACK_TEST';
FLASHBACK TABLE flashback_test TO SCN 12486407806290;
提示ORA-01466:無法讀取資料-表定義已更改
說明:ddl操作不會記錄到flashback_transaction_query檢視中,且也不能執行閃回 建立表並插入資料     
CREATE TABLE flashback_test (a VARCHAR2(255),b VARCHAR2(255),c VARCHAR2(255));
INSERT INTO flashback_test VALUES('d1','s','s');
INSERT INTO flashback_test VALUES('d2','sw','sf');
INSERT INTO flashback_test VALUES('d3','swd','ss'); 
1.刪除表
--刪除表
DROP TABLE flashback_test;
--查看回收站,該表存在回收站中
SELECT * FROM user_recyclebin WHERE original_name='FLASHBACK_TEST';
--執行閃回
FLASHBACK TABLE flashback_test TO BEFORE DROP;
--執行閃回後,該表已不在回收站,在檢視該表已經恢復
SELECT * FROM flashback_test;

2.刪除表且執行purge操作
--刪除表
DROP TABLE flashback_test PURGE;
--查看回收站,發現沒有在回收站中
SELECT * FROM user_recyclebin WHERE original_name='FLASHBACK_TEST';

3.清除回收站
PURGE TABLE original_name;--清除回收站中的某個表
PURGE INDEX original_name;--清除回收站中的某個索引
PURGE RECYCLEBIN;--清除自己使用者下的回收站資訊
PURGE TABLESPACE tablespace_name;--清除指定表空間下所有在回收站的物件
PURGE TABLESPACE tablespace_name USER user_name;--清除指定表空間指定使用者下在回收站中的物件(drop user 若加上CASCADE關鍵字則不進入回收站)
PURGE DBA_RECYCLEBIN; --從所有使用者的回收站清除所有物件

注:如果被刪除的表不在回收站,則執行flashback drop table時會提示ORA-38305:物件不在回收站中。 

不同版本查詢介紹
VERSIONS  BETWEEN 能夠檢視指定時間段內undo表空間中記錄的不同版本
1.建立表
CREATE TABLE ff (a VARCHAR2(255),b VARCHAR2(255),c VARCHAR2(255));
2.分別作插入,更新,刪除操作
INSERT INTO ff VALUES('d1','s','s');
UPDATE ff SET a='u_d2' WHERE a='d1';
DELETE FROM ff WHERE a='d1';
3.檢視 該時間內ff表非操作情況
1)VERSIONS BETWEEN TIMESTAMP minvalue AND MAXVALUE 方式
SELECT versions_starttime,
       versions_endtime,
       versions_xid,
       versions_operation,
       a,
       b,
       c
  FROM ff VERSIONS BETWEEN TIMESTAMP minvalue AND maxvalue
 ORDER BY versions_starttime;
VERSIONS_STARTTIME         VERSIONS_ENDTIME             VERSIONS_XID     VERSIONS_OPERATION       A     B    C
------------------------  ---------------------------- ----------------   ------------------    ----- ----- ----
30-12月-11 01.27.57 下午   30-12月-11 01.28.36 下午    0900000035070000         I                d1     s    s
30-12月-11 01.28.36 下午                               0100140069060000         U                u_d1   s    s

2)VERSIONS BETWEEN TIMESTAMP to_date('2011-12-30 13:22:00', 'yyyy-mm-dd hh24:mi:ss') AND to_date('2011-12-30 13:23:00', 'yyyy-mm-dd hh24:mi:ss')
SELECT versions_starttime,
       versions_endtime,
       versions_xid,
       versions_operation,
       a,
       b,
       c
  FROM ff VERSIONS BETWEEN TIMESTAMP to_date('2011-12-30 13:22:00', 'yyyy-mm-dd hh24:mi:ss') AND to_date('2011-12-30 13:23:00', 'yyyy-mm-dd hh24:mi:ss');

3)VERSIONS BETWEEN SCN 12486407818849 AND 12486407818864
SELECT *FROM flashback_transaction_query WHERE table_name='FF';
SELECT versions_starttime,
       versions_endtime,
       versions_xid,
       versions_operation,
       a,
       b,
       c
  FROM ff VERSIONS BETWEEN SCN 12486407818849 AND 12486407818864; GRANT SELECT ON flashback_transaction_query TO fyzh_ora;--直接賦予該表的select許可權還是無法查詢,提示許可權不夠
GRANT SELECT ANY TRANSACTION TO fyzh_ora;--必須授予ANY TRANSACTION才行

--建立表flashback_test
CREATE TABLE flashback_test (a VARCHAR2(255),b VARCHAR2(255),c VARCHAR2(255));
--插入三條記錄
INSERT INTO flashback_test VALUES('d1','s','s');
INSERT INTO flashback_test VALUES('d2','sw','sf');
INSERT INTO flashback_test VALUES('d3','swd','ss');
--執行刪除操作
DELETE FROM flashback_test WHERE a='d1'; --通過版本查詢xid,在flashback_transaction_query檢視中找出flashback_test表對應刪除操作的undo_sql,執行該sql即可閃回  SELECT xid, operation, table_name, undo_sql
  FROM flashback_transaction_query
 WHERE xid IN
       (SELECT versions_xid

          FROM flashback_test versions BETWEEN TIMESTAMP minvalue AND maxvalue); 

 查詢結果如下圖所示:

 

SQL> show parameter retention guarantee;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_flashback_retention_target        integer     1440
undo_retention                       integer     900

1.建立表並插入資料     
CREATE TABLE flashback_test (a VARCHAR2(255),b VARCHAR2(255),c VARCHAR2(255));
INSERT INTO flashback_test VALUES('d1','s','s');
INSERT INTO flashback_test VALUES('d2','sw','sf');
INSERT INTO flashback_test VALUES('d3','swd','ss');
DELETE FROM flashback_test WHERE a= 'd1';
2.FLASHBACK DATABASE 
1)一般使用者下執行:
SQL> FLASHBACK DATABASE TO TIMESTAMP (SYSDATE - 1/24);
FLASHBACK DATABASE TO TIMESTAMP (SYSDATE - 1/24)
ORA-01031: 許可權不足
2)採用sys使用者執行:
SQL> FLASHBACK DATABASE TO TIMESTAMP (SYSDATE - 1/24); 
FLASHBACK DATABASE TO TIMESTAMP (SYSDATE - 1/24)
ORA-38757: 要閃回資料庫, 資料庫必須已裝載但不能開啟。
3)關閉資料庫並裝載資料庫
C:\Users\thinkpad>sqlplus/nolog
SQL*Plus: Release 11.1.0.7.0 - Production on 星期四 12月 29 16:05:16 2011
Copyright (c) 1982, 2008, Oracle.  All rights reserved.
SQL> conn sys/[email protected] as SYSDBA --sys使用者登入
已連線。
SQL> SHUTDOWN IMMEDIATE;--關閉資料庫
資料庫已經關閉。
已經解除安裝資料庫。
ORACLE 例程已經關閉。
SQL> startup MOUNT;--裝載資料庫,無法識別監聽,退出重新以sys登入可解決
ORA-12514: TNS: 監聽程式當前無法識別連線描述符中請求的服務
SQL> exit
從 Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options 斷開

C:\Users\thinkpad>sqlplus/nolog
SQL*Plus: Release 11.1.0.7.0 - Production on 星期四 12月 29 16:06:19 2011
Copyright (c) 1982, 2008, Oracle.  All rights reserved.
SQL> conn sys/fyzh as SYSDBA --再次登入
已連線到空閒例程。
SQL> startup mount; --裝載資料庫
ORACLE 例程已經啟動。

Total System Global Area  535662592 bytes
Fixed Size                  1348508 bytes
Variable Size             251661412 bytes
Database Buffers          276824064 bytes
Redo Buffers                5828608 bytes
資料庫裝載完畢。

4)再次執行還是報錯
SQL> FLASHBACK DATABASE TO TIMESTAMP (SYSDATE - 1/24);
FLASHBACK DATABASE TO TIMESTAMP (SYSDATE - 1/24)
ORA-38726: 未啟用閃回資料庫事件記錄。
SQL> flashback database to restore point BEFORE_DROP;
flashback database to restore point BEFORE_DROP 
ORA-38780: 還原點 'BEFORE_DROP' 不存在。

5)開啟閃回功能
SQL> alter database flashback on;
alter database flashback on
ORA-38706: 無法啟用 FLASHBACK DATABASE 事件記錄。
ORA-38707: 尚未啟用介質恢復。

6)開啟歸檔和閃回
SQL> alter database archivelog;
Database altered
SQL> alter database flashback on;
Database altered

7)再次執行
SQL> FLASHBACK DATABASE TO TIMESTAMP (SYSDATE - 0.1/24);
FLASHBACK DATABASE TO TIMESTAMP (SYSDATE - 0.1/24)
ORA-38729: 執行 FLASHBACK 的閃回資料庫日誌資料不足。

SQL> FLASHBACK DATABASE TO TIMESTAMP (SYSDATE - 0.01/24);
Done

8)開啟資料庫
SQL> alter database open;
alter database open
*
第 1 行出現錯誤:
ORA-01589: 要開啟資料庫則必須使用 RESETLOGS 或 NORESETLOGS 選項

SQL> alter database open noresetlogs;
alter database open noresetlogs
*
第 1 行出現錯誤:
ORA-01610: 使用 BACKUP CONTROLFILE 選項的恢復必須已完成

SQL> alter database open resetlogs;
資料庫已更改。

9)檢視 表還存在,資料2條

注:1.必須具有DBA許可權
    2.資料庫必須處在裝載狀態
    3.必須啟用介質恢復
    4.必須開啟閃回和歸檔(必須在歸檔模式下才能開啟閃回)
    5.閃回好後,開啟資料庫要使用 RESETLOGS 或 NORESETLOGS 選項
    6.使用該功能,需要之前就已經開啟歸檔模式和閃回,否則等資料損壞再開啟已經來不及了
復原點是手動建立的一個時間點,資料庫可以閃回到建立的該復原點。
普通復原點:只是在閃回或恢復操作中為指定以前的SCN或時間點提供方便。但不保證資料庫在所有情形下都保留成功執行
            閃回資料庫操作所需的閃回資料庫日誌。
建立普通復原點:CREATE RESTORE POINT test_point;
有保證的復原點:保證可以把資料庫倒退到由復原點指定的SCN或時間點.
建立有保證的復原點:CREATE RESTORE POINT test_storepoint GUARANTEE FLASHBACK DATABASE;
刪除復原點:DROP RESTORE POINT point_name;
檢視復原點:v$restore_point檢視

建立復原點注意事項:
1.建立復原點必須開啟歸檔模式
2.建立復原點可以不開啟閃回
3.建立復原點若閃回沒開啟資料庫需為裝載狀態
SQL> CREATE RESTORE POINT test_storepoint GUARANTEE FLASHBACK DATABASE;
CREATE RESTORE POINT test_storepoint GUARANTEE FLASHBACK DATABASE
第 1 行出現錯誤:
ORA-38784: 無法建立還原點 'TEST_STOREPOINT'。
ORA-38787: 在閃回資料庫處於關閉狀態時, 建立第一個可靠還原點需要裝載模式。
4.建立了復原點後,資料庫的閃回由原來的no狀態變成了RESTORE POINT ONLY
SQL> CREATE RESTORE POINT test_storepoint GUARANTEE FLASHBACK DATABASE;
還原點已建立。
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
RESTORE POINT ONLY

利用復原點閃回資料庫:
FLASHBACK DATABASE TO RESTORE POINT test_storepoint;