ORA-01555: snapshot too old: rollback segment number with name "" too small

jane_pop發表於2014-10-15
當前資料庫有undotbs1和undotbs2兩個撤銷表空間,和一個空表flash_t,進行如下操作:
1.將當前的undo表空間設定為undotbs2,向flash_t中插入資料並提交:
SYS@orcl 13-OCT-14>show parameter undo 

NAME TYPE VALUE 
------------------------------------ ----------- ------------------------------ 
undo_management string AUTO 
undo_retention integer 900 
undo_tablespace string UNDOTBS2

HH@orcl 13-OCT-14>insert into flash_t select * from dba_users; 

44 rows created. 

HH@orcl 13-OCT-14>select count(1) from flash_T; 

COUNT(1) 
---------- 
44 

HH@orcl 13-OCT-14>commit; 

Commit complete.

2.查詢當前的系統時間:
HH@orcl 13-OCT-14>select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual; 

TO_CHAR(SYSDATE,'YY 
------------------- 
2014-10-13 00:33:11 

3.刪除flash_t中的所有資料,並提交:
HH@orcl 13-OCT-14>delete from flash_t; 

44 rows deleted. 

HH@orcl 13-OCT-14>commit; 

Commit complete.

4.切換到undotbs1:
SYS@orcl 13-OCT-14>alter system set undo_tablespace=undotbs1; 

System altered.

5.刪除undotbs2:
SYS@orcl 13-OCT-14>drop tablespace undotbs2; 

Tablespace dropped.

6.嘗試將表flash_t閃回到以上記錄的時間點:
HH@orcl 13-OCT-14>flashback table flash_t to timestamp to_timestamp('2014-10-13 00:33:11','yyyy-mm-dd hh24:mi:ss'); 
flashback table flash_t to timestamp to_timestamp('2014-10-13 00:33:11','yyyy-mm-dd hh24:mi:ss') 

ERROR at line 1: 
ORA-08189: cannot flashback the table because row movement is not enabled 


HH@orcl 13-OCT-14>alter table flash_t enable row movement; 

Table altered. 

HH@orcl 13-OCT-14>flashback table flash_t to timestamp to_timestamp('2014-10-13 00:33:11','yyyy-mm-dd hh24:mi:ss'); 

Flashback complete.

我們知道,閃回查詢,閃回事務和閃回表這三種閃回技術都是透過undo segment實現的,前面,我們剛開始使用的是undotbs2,在這期間向表中插入了資料,那麼這些資料理應在undotbs2中有相應的快照。之後,切換到了undotbs1,並且把存在flash_t資料的undotbs2刪除了,那麼當我們使用閃回表的時候,就無法找到undotbs2上的資料來進行閃回了,但是我們仍然閃回成功了,這是為什麼呢?
答案就是這些資料還存在buffer裡面,oracle首先會到buffer去檢視,如果buffer裡面沒有,才會到undotbs2中檢視並返回結果。
這是我們業務不繁忙的測試環境,如果在一個繁忙的生產系統上的話,是很大可能或者說基本上是無法閃回成功的,因為在繁忙的系統上,buffer中存在的資料會被沖刷掉,而undotbs2又被刪除了。
下面我們重複上面的步驟,但是在閃回之前把buffer清空,看看會發生什麼:
當前undo表空間是undotbs2:
SYS@orcl 13-OCT-14>show parameter undo 

NAME TYPE VALUE 
------------------------------------ ----------- ------------------------------ 
undo_management string AUTO 
undo_retention integer 900 
undo_tablespace string UNDOTBS2

HH@orcl 13-OCT-14>create table flash_t as select * from dba_users where 1=2; 

Table created.

向表中插入資料,提交:
HH@orcl 13-OCT-14>insert into flash_t select * from dba_users; 

44 rows created. 

HH@orcl 13-OCT-14>commit; 

Commit complete.

HH@orcl 13-OCT-14>select count(*) from flash_T; 

COUNT(*) 
---------- 
44

查詢當前系統時間:
HH@orcl 13-OCT-14>select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual; 

TO_CHAR(SYSDATE,'YY 
------------------- 
2014-10-13 01:15:11

刪除flash_t的資料且提交:
HH@orcl 13-OCT-14>delete from flash_t; 

44 rows deleted. 

HH@orcl 13-OCT-14>commit; 

Commit complete. 

HH@orcl 13-OCT-14>select count(*) from flash_T; 

COUNT(*) 
---------- 
0

切換到undotbs1,且刪除undotbs2表空間:
SYS@orcl 13-OCT-14>alter system set undo_tablespace=undotbs1; 

System altered. 

SYS@orcl 13-OCT-14>drop tablespace undotbs2 including contents and datafiles; 

Tablespace dropped. 

把buffer cache清空:
SYS@orcl 13-OCT-14>alter system flush buffer_cache; 

System altered. 

嘗試將表閃回到以上記錄的時間點:
HH@orcl 13-OCT-14>alter table flash_t enable row movement; 

Table altered. 

HH@orcl 13-OCT-14>flashback table flash_t to timestamp to_timestamp('2014-10-13 01:15:11','yyyy-mm-dd hh24:mi:ss'); 
flashback table flash_t to timestamp to_timestamp('2014-10-13 01:15:11','yyyy-mm-dd hh24:mi:ss') 

ERROR at line 1: 
ORA-00604: error occurred at recursive SQL level 1 
ORA-12801: error signaled in parallel query server P000 
ORA-01555: snapshot too old: rollback segment number with name "" too small 

可以看到,這時會出現一個ORA-01555快照過舊的錯誤。因為oracle已經找不到指定時間點的快照了,所以報錯。












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

相關文章