ORA-01555: 快照過舊: 回退段號 18 (名稱爲 "_SYSSMU18_720684835$") 太小

首先了解Oracle在什麼狀況下會產生ORA-01555錯誤:數據庫

假設有一張6000萬行數據的testdb表,預計testdb全表掃描1次須要2個小時,參考過程以下: 優化

一、在1點鐘,用戶A發出了select * from testdb;此時無論未來testdb怎麼變化,正確的結果應該是用戶A會看到在1點鐘這個時刻的內容。日誌

二、在1點30分,用戶B執行了update命令,更新了testdb表中的第4100萬行的這條記錄,這時,用戶A的全表掃描尚未到達第4100萬條。毫無疑問,這個時候,第4100萬行的這條記錄是被寫入了回滾段,假設是回滾段UNDOTS1,若是用戶A的全表掃描到達了第4100萬行,是應該會正確的從回滾段UNDOTS1中讀取出1點鐘時刻的內容的。blog

三、這時,用戶B將他剛纔作的操做提交了,可是這時,系統仍然能夠給用戶A提供正確的數據,由於那第4100萬行記錄的內容仍然還在回滾段UNDOTS1裏,系統能夠根據SCN到回滾段裏找到正確的數據,但要注意到,這時記錄在UNDOTS1裏的第4100萬行記錄已經發生了重大的改變:就是第4100萬行在回滾段UNDOTS1裏的數據有可能隨時被覆蓋掉,由於這條記錄已經被提交了!事務

四、因爲用戶A的查詢時間漫長,而業務在一直不斷的進行,UNDOTS1回滾段在被多個不一樣的transaction使用着,這個回滾段裏的extent循環到了第4100萬行數據所在的extent,因爲這條記錄已經被標記提交了,因此這個extent是能夠被其餘transaction覆蓋掉的!開發

五、到了1點45分,用戶A的查詢終於到了第4100萬行,而這時已經出現了第4條說的狀況,須要到回滾段UNDOTS1去找數據,可是已經被覆蓋掉了,這時就出現了ORA-01555錯誤。io

緣由分析:"報表"程序執行時間漫長,在程序查詢的過程當中其餘用戶對"報表"進行了更新,被更新的數據寫入了回滾段,當程序到回滾段找數據時,發現數據已經被覆蓋掉,因而就出現了ORA-01555錯誤。另外"報表"程序執行效率不高也會形成ORA-01555錯誤。test

解決辦法:效率

一、擴大回滾段,由於回滾段是循環使用的,若是回滾段足夠大,那麼那些被提交的數據就能保存足夠長的時間,使那些大事務完成一致性讀取。以前EBS系統UNDO表空間爲9GB,目前爲10GB。見下圖:date

二、增長undo_retention時間,由於UNDO回滾段是循環使用,裏面的數據可能隨時被循環覆蓋掉,若是設置undo_retention時間更長,那麼在retention規定的時間內,任何其餘事務都不能覆蓋這些數據。目前EBS系統undo_retention爲10800秒(3個小時)。見下圖:

 

3最重要的一點就是優化程序相關查詢語句,減小查詢語句的一致性讀,下降讀取不到回滾段數據的風險。全部的出錯信息都會紀錄到數據庫日誌alert_PROD.log文件中,下圖紅線部分是一條SQL查詢詞句,ORA-01555頗有多是這條語句形成,把這條語句提供給開發人員來分析和優化程序代碼。

相關文章
相關標籤/搜索