【故障處理】ORA-01555

TaihangMeng發表於2017-05-03

一、為什麼會出現ORA-01555

    ORA-01555便是著名的snapshot too old(快照太舊)問題。這個錯誤是由資料庫的讀一致性(Read consistency)引起的,當查詢需要訪問被修改的資料時,它會到undo裡訪問該資料的前映象,如果該前映象已被覆蓋,查詢語句就會返回ORA-01555的錯誤。


二、引起ORA-01555錯誤的具體原因

    1、SQL語句執行時間太長,或者UNDO表空間過小,或者事務量過大,或者過於頻繁的提交,導致執行SQL過程中進行一致性讀時,SQL執行後修改的前映象(即UNDO資料)在UNDO表空間中已經被覆蓋,不能構造一致性讀塊。

    2、SQL語句執行過程中,訪問到的塊,在進行延遲塊清除時,不能確定該塊的事務提交時間與SQL執行開始時間的先後次序。(當一個查詢觸發延遲塊清除時,Oracle需要去查詢回滾段獲得該事務的提交SCN,如果事務的前映象資訊已經被覆蓋,並且查詢SCN也小於回滾段中記錄的最小提交SCN,那麼Oracle將無從判斷查詢SCN和事務提交SCN的大小,此時出現延遲塊清除導致的ORA-01555錯誤)。


三、解決辦法

    1、對於第一種原因,解決的辦法無非就是增加UNDO表空間大小,優化查詢SQL以縮短查詢時間,避免頻繁地提交,使用undo_rententiion和undo表空間GUARANTEE功能避免。

    2、對於第二種原因,大批量的UPDATE 或INSERT 會導致塊清除(block cleanout),所以在大批量UPDATE 或大量載入之後使用DBMS_STATS收集相關物件的統計資訊,載入之後完成對這些物件的清理


四、例項

    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錯誤。


五、參考文章

http://www.laoxiong.net/ora-1555-case.html

http://blog.itpub.net/30776559/viewspace-2138298/

http://f.dataguru.cn/thread-172668-1-1.html

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

相關文章