【Flashback】使用閃回功能快速恢復使用者的誤操作

secooler發表於2009-12-05
Oracle提供的閃回特性對於快速恢復誤操作的資料起到了非常大的幫助。在沒有這個特性的Oracle早期版本,如果需要恢復因使用者錯誤導致的資料丟失,需要大量的時間和精力去做不完全恢復。
不過,這種用空間換時間的策略也存在限制,不可能無限地恢復任何時間點的誤操作。針對那些“及時”發現的誤操作,使用該方法進行恢復是非常有效的。

簡單演示一下這個方法,供參考。

1.建立實驗表T
sec@ora10g> create table t (x int);

Table created.

2.初始化資料
sec@ora10g> insert into t values (1);

1 row created.

sec@ora10g> commit;

Commit complete.

sec@ora10g> insert into t values (2);

1 row created.

sec@ora10g> commit;

Commit complete.

3.檢視錶中的資料,之所以使用rowid欄位是為了後面實驗參考方便。
sec@ora10g> select rowid, x from t;

ROWID                       X
------------------ ----------
AAASVaAAFAAAAAYAAA          1
AAASVaAAFAAAAAYAAB          2

4.模擬誤刪除
sec@ora10g> delete from t;

2 rows deleted.

sec@ora10g> commit;

Commit complete.

5.看一看此時T表有哪些動作被記錄在案?
sec@ora10g> select versions_starttime,versions_endtime, versions_xid, versions_operation,t.x from t versions between timestamp minvalue and maxvalue;

VERSIONS_STARTTIME    VERSIONS_ENDTIME      VERSIONS_XID     V          X
--------------------- --------------------- ---------------- - ----------
05-DEC-09 09.52.51 PM                       09002C004B250000 D          2
05-DEC-09 09.52.51 PM                       09002C004B250000 D          1
05-DEC-09 09.50.57 PM 05-DEC-09 09.52.51 PM 090018004B250000 I          2
05-DEC-09 09.49.54 PM 05-DEC-09 09.52.51 PM 090008004B250000 I          1

因為前後的操作時間並不是很長,所以對於T表的所有操作都清晰的展示出來了。

6.恢復方法一:使用UNDO SQL。
重點關注一下“VERSIONS_XID”的內容,每一個不同的值都對應了一個完整的操作動作。我們逐條看一下上面每個動作對應的恢復語句。
1)如果要恢復誤刪除的操作,可以使用下面的UNDO SQL。
sec@ora10g> select undo_sql from flashback_transaction_query WHERE XID='09002C004B250000';

UNDO_SQL
----------------------------------------------------------------------
insert into "SEC"."T"("X") values ('2');
insert into "SEC"."T"("X") values ('1');

2)向前一步回滾:回滾插入的“2”,即刪除記錄“2”對應的行。
sec@ora10g> select undo_sql from flashback_transaction_query WHERE XID='090018004B250000';

UNDO_SQL
----------------------------------------------------------------------
delete from "SEC"."T" where ROWID = 'AAASVaAAFAAAAAYAAB';

3)再向前回滾:回滾插入的“1”,即刪除記錄“1”對應的行。
sec@ora10g> select undo_sql from flashback_transaction_query WHERE XID='090008004B250000';

UNDO_SQL
----------------------------------------------------------------------
delete from "SEC"."T" where ROWID = 'AAASVaAAFAAAAAYAAA';

7.恢復方法二:使用SCN號進行便捷恢復
上面雖然已經列出了具體回滾的SQL語句,只要簡單的執行即可,不過如果涉及的到的記錄數非常多,那麼使用具體的UNDO SQL就不是很方便了。
這裡有一個比較簡單的方法,我們可以透過XID的值在flashback_transaction_query檢視中得到操作前的SCN號,然後根據SCN號進行閃回恢復。簡單演示一下
1)得到誤刪除之前的SCN號
sec@ora10g> col UNDO_SQL for a42
sec@ora10g> col OPERATION for a8
sec@ora10g> select undo_sql, operation, start_scn from flashback_transaction_query WHERE XID='09002C004B250000';

UNDO_SQL                                   OPERATIO  START_SCN
------------------------------------------ -------- ----------
insert into "SEC"."T"("X") values ('2');   DELETE     31205010
insert into "SEC"."T"("X") values ('1');   DELETE     31205010
                                           BEGIN      31205010
2)使用上面的SCN號“31205010”進行閃回
sec@ora10g> flashback table t to scn 31205010;
flashback table t to scn 31205010
                *
ERROR at line 1:
ORA-08189: cannot flashback the table because row movement is not enabled

3)上面報錯提示資訊很明確,需要啟用“row movement”
sec@ora10g> alter table t enable row movement;

Table altered.

4)再次嘗試閃回,成功。
sec@ora10g> flashback table t to scn 31205010;

Flashback complete.

5)最後重新檢視一下T表的操作記錄
sec@ora10g> select versions_starttime,versions_endtime, versions_xid, versions_operation,t.x from t versions between timestamp minvalue and maxvalue;

VERSIONS_STARTTIME    VERSIONS_ENDTIME      VERSIONS_XID     V          X
--------------------- --------------------- ---------------- - ----------
05-DEC-09 10.02.16 PM                       09000F004C250000 I          1
05-DEC-09 10.02.16 PM                       09000F004C250000 I          2
05-DEC-09 09.52.51 PM                       09002C004B250000 D          2
05-DEC-09 09.52.51 PM                       09002C004B250000 D          1
05-DEC-09 09.50.57 PM 05-DEC-09 09.52.51 PM 090018004B250000 I          2
05-DEC-09 09.49.54 PM 05-DEC-09 09.52.51 PM 090008004B250000 I          1

6 rows selected.

可見閃回的動作也被記錄在案,因為使用的是真實的SQL來完成。

6)使用這種基於SCN的恢復方法可以將表恢復到任何“可恢復”的時間點,比較靈活。
例如,我們可以使用下面的SQL恢復T表到僅插入記錄“1”的狀態。
sec@ora10g> flashback table t to scn 31204988;

Flashback complete.

sec@ora10g> select * from t;

         X
----------
         1

8.小結
使用此閃回方法恢復誤操作有一個前提,就是需要儘早的發現問題,果斷的採取行動。若誤操作的記錄已經在UNDO中被清除,則此方法就不可行了,需要另尋他法。

Good luck.

secooler
09.12.05

-- The End --

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

相關文章