首先了解Oracle在什麼情況下會產生ORA-01555錯誤: 假設有一張6000萬行數據的testdb表,預計testdb全表掃描1次需要2個小時,參考過程如下: 1、在1點鐘,用戶A發出了select * from testdb;此時不管將來testdb怎麼變化,正確的結果應該是用戶A會看到在1點鐘這個時刻的內容。 2、在1點30分,用戶B執行了update命令,更新了testdb表中的第4100萬行的這條記錄,這時,用戶A的全表掃描還沒有到達第4100萬條。毫無疑問,這個時候,第4100萬行的這條記錄是被寫入了回滾段,假設是回滾段UNDOTS1,如果用戶A的全表掃描到達了第4100萬行,是應該會正確的從回滾段UNDOTS1中讀取出1點鐘時刻的內容的。 3、這時,用戶B將他剛才做的操作提交了,但是這時,系統仍然可以給用戶A提供正確的數據,因為那第4100萬行記錄的內容仍然還在回滾段UNDOTS1裡,系統可以根據SCN到回滾段裡找到正確的數據,但要注意到,這時記錄在UNDOTS1裡的第4100萬行記錄已經發生了重大的改變:就是第4100萬行在回滾段UNDOTS1裡的數據有可能隨時被覆蓋掉,因為這條記錄已經被提交了! 4、由於用戶A的查詢時間漫長,而業務在一直不斷的進行,UNDOTS1回滾段在被多個不同的transaction使用著,這個回滾段裡的extent循環到了第4100萬行數據所在的extent,由於這條記錄已經被標記提交了,所以這個extent是可以被其他transaction覆蓋掉的! 5、到了1點45分,用戶A的查詢終於到了第4100萬行,而這時已經出現了第4條說的情況,需要到回滾段UNDOTS1去找數據,但是已經被覆蓋掉了,這時就出現了ORA-01555錯誤。
--以上來自網上
模擬錯誤
第一步:新建一個大表,大概100多W行
第二步:設置undo_retention的值,我這裡設置成二秒,
alter system set undo_retention=2 scope=spfile;
之後需要重新啟動數據庫
第三步:設置一個較小的undo空間, 我這裡設置是50M
第四步:A窗口執行select ,之後B窗口執行delete
A窗口:select * from ora01555;
B窗口:
結果:出現ora-01555錯誤。實驗成功OK,以後需要這個錯誤就不怕了,哈哈。