因為上一次研究了Oracle的事務一致性,中間查閱資料的時候,看到這個地方與回滾段有關。所以就羅列了以下簡單的知識。更為深層次的就不再深挖了,個人感覺對於事務的一致性和隔離級別是開發經理應該了解的,但是回滾段的具體機制應該是DBA的學習范疇了。
回滾段(ROLLBACK SEGMENT)的作用:
回滾段是在事務中間過程中,將修改前的狀態記錄下來,記錄的過程中加上類似時間戳的scn。它的主要作用有兩個:
- 當事務出現錯誤回滾的時候,原始數據可以從回滾段中找回。
- 實現讀一致性。當讀操作讀取到某一行,發現這行數據已經被修改,就會根據讀取時刻的scn去回滾段中找之前的數據。
關於回滾段導致的
ORA-01555錯誤。
網上的說法:
- 1、在1點鍾,有個用戶A發出了select * from table1;此時不管將來table1怎么變化,正確的結果應該是用戶A會看到在1點鍾這個時刻的內容。這個是沒有疑問的。
- 2、在1點30分,有個用戶B執行了update命令,更新了table1表中的第4000萬行的這條記錄,這時,用戶A的全表掃描還沒有到達第4000萬條。毫無疑問,這個時候,第4000萬行的這條記錄是被寫到了回滾段里去了的,我假設是回滾段RBS1,如果用戶A的全表掃描到達了第4000萬行,是應該會正確的從回滾段RBS1中讀取出1點鍾時刻的內容的。
- 3、這時,用戶B將他剛才做的操作commit了,但是這時,系統仍然可以給用戶A提供正確的數據,因為那第4000萬行記錄的內容仍然還在回滾段RBS1里,系統可以根據SCN來到回滾段里找到正確的數據,但是大家注意到,這時記錄在RBS1里的第4000萬行記錄已經發生了一點重大的改變:就是這個第4000萬行的在回滾段RBS1里的數據有可能隨時被覆蓋掉,因為這條記錄已經被提交了!!!
- 4、由於用戶A的查詢時間漫長,而業務在一直不斷的進行,RBS1回滾段在被多個不同的tracnsaction使用着,這個回滾段里的extent循環到了第4000萬行數據所在的extent,由於這條記錄已經被標記提交了,所以這個extent是可以被其他transaction覆蓋掉的!
- 5、到了1點40分,用戶A的查詢終於到了第4000萬行,而這時已經出現了第4條說的情況,需要到回滾段RBS1去找數據,但是已經被覆蓋掉了,於是01555就出現了。
我的理解:上面的說法大致正確,不過有一個誤區,給人造成一種印象:一旦一個事務提交了,它所占據的回滾段里的數據,有可能還是需要的(為了保證讀一致性),但是如果此時來了一個新的事務來處理同樣的這塊數據,這個回滾段就會被重寫。其實不是這樣的,新的事務會在回滾段里有不同的scn,不會直接重寫還有用的回滾段,之所以會出現01555,是因為回滾段的空間是有限制的,一旦時間太長,或者執行了其他復雜事務導致了回滾段不夠用,老的回滾段才會被清除。所以要避免01555,主要是擴大回滾段大小,優化耗時的查詢,減少占用回滾段太多的不必要事務(如Clob或者Blob字段上的事務)。