[zt] Oracle Undo的學習

tolywang發表於2009-03-29
           回滾段可以說是用來保持資料變化前映象而提供一致讀和保障事務完整性的一段磁碟儲存區域。當一個事務開始的時候,會首先把變化前的資料和變化後的資料先寫入日誌緩衝區,然後把變化前的資料寫入回滾段,最後才在資料緩衝區中修改(日誌緩衝區內容在滿足一定的條件後可能被寫入磁碟,但在事務提交的時候日誌必須寫入磁碟,而資料緩衝區中的資料依賴於檢查點的發生和DBWR程式的活動)

    Rollback是一個代價昂貴的操作,如果一個系統的事務回退率過高,應該檢查系統是否正常或者程式設計思路是否存在問題。查詢資料庫啟動依賴的

事務回退率,如果發現太高,一定要引起重視。

--查詢回退率的sql

SELECT NAME, VALUE
   FROM v$sysstat
WHERE NAME IN ('user commits', 'transaction rollbacks');

     關於回滾段的資料,如果是delete操作,則回滾段將回記錄整個行的資料;如果是update,則只記錄被修改了的欄位的變化前的資料(前映像);如果是insert,則只記錄插入記錄的rowid。所以,假如commit,那麼回滾段中簡單標記該事務已經提交;假如rollback,則操作是 delete的話,把回滾段中的資料重新寫回資料塊,操作是update的話則把變化前的資料修改回去,操作是insert的話則根據rowid把該記錄刪除。這個過程是保障事務的完整性,保障資料不會丟失。

    一致性讀(consisitent reads) Oralce的查詢集是根據時間點來判定的。Oracle內部透過系統改變號SC作為相對時間點的標準,任何對資料庫的改變都會產生SCN,對資料塊的資料改變的時候會把該改變所對應的SCN記錄在塊中。假設查詢開始的時候SCN為T,則在查詢所掃描的資料塊中,如果資料塊的COMMIT SCN小魚T,則查詢接受該資料,如果COMMIT SCN大於T或者說還沒有產生COMMIT SCN,則查詢會嘗試去回滾段中查詢資料。這保證了資料的讀取時間點的一致性。

在透過回滾段中獲取資料的時候,本質上是把資料緩衝區中的資料塊做一個複製,然後將回滾段中記錄的內容恢復到該塊中,然後查詢使用這個塊來進行讀取。

系統回滾段和延遲迴滾段

SYSTEM回滾段是建立在系統表空間中,主要用於系統級的事務和分配普通事務於其他回滾段上。當手工建立資料後需要建立普通回滾段之前必須首先建立系統回滾段。按oracle文件說,當普通事務異常多的事情可能會使用系統回滾段的情況。正常情況下,系統回滾段主要用於兩個方面:一是系統事務,不如針對資料字典的操作的truncate table 和 drop table。如果truncate or drop table的過程中沒有成果,則系統會根據系統回滾段中的資料字典操作資訊對該DDL操作進行回退。另一個方面,就是延遲迴滾段(Deferred Rollback Segment)。延遲迴滾段表示,當我們使一個表空間OFFLINE之後,由於表空間不可用,這個時候若有事務資料位於該空間並執行回滾命令,在client看起來該事務已經回滾,但對於資料塊來說回滾並沒有真正完成,這個時候資料庫將該回滾資訊寫入系統回滾段(這就是延遲迴滾段),等表空間重新ONLINE的時候,資料塊從系統回滾段中將回滾資訊寫入表空間。

回退段的設定和管理

Oracle9i之前需要手動設定回退段,我們需要考慮如下問題:

1.系統併發事務數有多少
2.系統是否存在大查詢或者大事務,是否頻繁
3.能提供給系統回滾段的表空間的磁碟空間是多少

9i的UNDO TABLESPACE

從9i開始,推薦使用UNDO TABLESPACE,系統自動管理回滾段

Sql> show parameter undo
undo_management                       string    AUTO
undo_retention                        integer   900
undo_tablespace                       string    UNDOTBS1

UNDO TABLESPACE變的很大,我們不能縮小,這個時候我們需要考慮建立新的UNDO TABLESPACE,然後換到新的表空間。這時即使UNDO表空間有事務也可以切換,只不過不能立即刪除該表空間,切換之後等到原來的表空間中所有的事務出力完畢,並且達到undo_retention的時間後,就可以drop原來的UNDO表空間。

SQL> alter system set undo_tablespace = undotbs02;

        System altered.

切換了UNDO表空間後應該修改pfile或者spfile,使得下次啟動應用新的UNDO表空間。

回滾段著名的ORA-01555問題

從應用角度來看ORA-01555

1.查詢執行時間太長。首先是最佳化查詢,然後考慮在資料塊不繁忙的時候執行,最後考慮加大回滾段。

2.過渡頻繁的提交。把能夠成批提交的單條事務改成成批提交

3.exp的時候使用而來consistent = y. 這個引數主要是為了保證在exp的時候使得所有的到處的表在時間點上具有一致性,避免存在主外來鍵關係的表由於不同的時間點的不一致而破壞了資料的完整性。建議該操作在系統空閒的時候進行。

4.由於回滾段回縮導致回滾段還沒有迴圈使用的情況下就出現了回滾段中找不著資料的情況。只能加大回滾段增大optimal設定。

UNDO scripts

查詢資料塊當前某個session的事務所使用的回滾段大小

SELECT b.SID, a.xidusn, a.xidusn
   FROM v$transaction a, v$session b
WHERE a.addr = b.taddr

回滾段表空間中的一個資料檔案丟失或者損害的恢復方法

…………….


由於對應的undo block/或者undo header slot資訊被覆蓋,導致consistent read不能完成, 系統會報出ora-01555的錯誤資訊..

出現這種情況的原因可能有以下幾種.

1. 對於早期的manual undo, 可能是由於系統設定了optimal size, rollback segment wrap 導致部分undo資訊被丟棄..

2. 由於undo retention 設定的時間小於sql執行的長度,這樣從這條sql開始時候其他session產生的部分undo由於retention的原因被覆蓋,導致無法完成consistent read.

3. 由於commit over fetch loop. 導致transaction slot 被覆蓋,無法完成consistent read ..


ORA-01555錯誤淺析-- (1).htm

總結出以下方法來解決1555錯誤問題:

1、擴大回滾段

因為回滾段是迴圈使用的,如果回滾段足夠大,那麼那些被提交的資料資訊就能儲存足夠長的時間是那些大事務完成一致性讀取。

2、增加undo_retention時間

undo_retention規定的時間內,任何其他事務都不能覆蓋這些資料。

3、最佳化相關查詢語句,減少一致性讀。

減少查詢語句的一致性讀,就降低讀取不到回滾段資料的風險。這一點非常重要!

4、減少不必要的事務提交

提交的事務越少,產生的回滾段資訊就越少。

5、對大事務指定回滾段

透過以下語句可以指定事務的回滾段

SET TRANSACTION USE ROLLBACK SEGMENT rollback_segment

給大事務指定回滾段,即降低大事務回滾資訊覆蓋其他事務的回滾資訊的機率,又降低了他自身的回滾資訊被覆蓋的機率。大事務的存在,往往是1555錯誤產生的誘因。

6、使用遊標時儘量使用顯式遊標,並且只在需要的時候開啟遊標,同時將所有可以在遊標外做的操作從遊標迴圈中拿出。

當遊標開啟時,查詢就開始了,直到遊標關閉。減少遊標的開啟時間,就減少了1555錯誤發生的機率。

 

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

相關文章