Oracle事務原理探究1--oracle核心技術讀書筆記五,oracle1--oracle

來源:互聯網
上載者:User

Oracle事務原理探究1--oracle核心技術讀書筆記五,oracle1--oracle

1. 衝突解決

       假如有一個系統只有你和我兩個使用者,並且我們都在持續對系統中一小部分資料做修改和查詢操作。

        如果你正在資料庫中做一批修改操作,而我正在做查詢,我一定不能看到你所做的修改,直到你告訴我可以看到你所做的所有更改才行(你提交了事務)。因此在oracle內部,必須有一個高效的辦法來識別哪些資料我可以看到,哪些資料我不可以看到。

       從相反的角度來看,在你提交事務的時候,你需要一種高效的機制讓其他所有人能夠看到事務已經提交(也就是要告訴別人你所有修改過的資料都是可見的了)。更極端一點的情況是,你可能需要決定復原事務,這樣的話,你也需要一種高效的機制能夠關聯上所有的undo記錄,按產生的順序排序,從而可以按相反的順序復原這些更改。


2. 事務與undo

        建立資料庫的時候,必須建立一個undo資料表空間。同時,oracle會在undo資料表空間中自動建立多個undo段,隨著資料庫負載的變化自動新增,擴大和收縮。

        交易管理起始於undo段,並以此為中心。undo段的第一個塊(段頭塊)包含如下結構:擴充映射,擴充控制頭(跟其他類型的段頭塊一樣),事務表,事務控制區(特殊的結構)。事務表的大概結構如下:

TRN    TBL:

 index   state   cflags     wrap#       uel                  scn                           dba                  nub                 cmt

0X00       9       0X00    0X2013    0X001b  0X0000.016f1fc1   0X0180083e     0X00000001     1302762364

0X01       9       0X00    0X2014    0X001a  0X0000.016f1f54   0X0180083e     0X00000001     1302762364

0X02     10       0X80    0X2013    0X001d  0X0000.016f20fc   0X0180083e     0X00000001      0

0X03       9       0X00    0X200c    0X001c   0X0000.016f20d8  0X0180083e     0X00000001      1302762364

0X04       9       0X00    0X200f     0X001f    0X0000.016f1c75  0X0180083f       0X00000001     1302762364

.........


 index 表示事務表中槽號,只是一個序列而已,從0x00開始到0x21結束,11g的版本有34個槽。

state 表示事務狀態:9代表事務不活動,10代表事務正在活動,從這裡我們看出16進位第0x02號槽上的事務正在活動。

cflags 表示正在使用事務槽的事務的狀態:0x00表示非活動事務、0x80表示活動事務、0x10表示死事務、0x90表示被復原的死事務

wrap# 表示事務表上的事務槽被重用的次數,它是XID的一部分。0x2013表示此時事務槽被重用了8211次。

uel   表示當前活動事務所在事務槽的下一個事務槽的指標(即如果又發生一個新的事務,此時就會用到UEL指向的事務槽上的index)。

scn   表示務事啟動、提交、復原的SCN.

dba   表示uba:第一部分的undo塊地址,這個DBA是(rollback)復原的起始點,也就是說是記錄事務修改的最後一條記錄所在UNDO塊的地址。這使oracle在崩潰恢複時,能夠找到事務產生的最後一條undo記錄,以便知道從何處開始處理復原。

nub   表示當前事務所用到的UNDO塊的個數。交易回復時,可以看到該值會逐步減少。

cmt   表示最接近當前的提交時間戳記,是從1970年1月1號零晨開始的(以秒為單位記錄)。0表示事務正在活動。


2.1 事務的開始和結束

       當會話開始一個事務的時候,會先取到一個undo段,從undo段的事務表中取得一條記錄,然後增加該記錄的wrap#的值,將state改為active(10),同時修改事務表其他一些列(比如cmt置0)。由於這也是對於資料庫塊的修改,所以會產生一條最終寫入重做記錄檔的重做改變向量(作業碼為5.2),並寫入資料庫。這樣會話就有了一個活動的事務了。

      同樣,當事務完成時(通常是使用者commit),會將state設回為free(9),並更新其他一些列,比如將當期的SCN寫入scn列。同樣,對資料庫塊的這一修改也要產生一個重做改變向量(作業碼5.4),最終記錄到重做日誌中。這一刻相當特別的重要,因為這個時刻你的會話正在向日誌寫進程(lgwr)發布命令將日誌緩衝區的當前內容寫入磁碟,並等待日誌寫進程確認寫入完成,以保護所提交的更改。(這個發送命令要求lgwr進程輸出重做日誌到磁碟其實很簡單,一旦發現進入日誌緩衝區的重做日誌作業碼是5.4,也就是是提交事務記錄,立刻將所有緩衝區的日誌重新整理輸出磁碟,完成後並告知把這條提交記錄放入日誌緩衝區的會話。)

      每一個事務會分配一個事務id,事務id由undo段編號,事務表中的條目索引號以及事務條目中最新的wrap#值構成。因此,當你看到像0X0009.002.00002013這樣的事務id時,就會知道:這個事務在undo段9裡,用的是第2條事務表記錄,wrap#值為0X2013。如果你想看這是哪個undo段,以及相應的段頭位置,可以使用segment_id列作為查詢條件查詢dba_rollback_segs視圖。


2.2 事務表

        在上面我們已經介紹了事務表的結構了,現在回顧一下,事務表主要的目的無非下面幾個:

        1. 顯示事務是已提交還是仍舊活動

        2. 已提交事務的SCN

        3. 事務產生的最近一條undo記錄的位置資訊,便於復原

        4. 事務產生的undo量

        如果一個事務必須復原,或者一個會話被強制殺掉,使得smon(系統監視進程)必須要復原它的事務,或者如果執行個體崩潰,在執行個體恢複期間,smon必須復原所有崩潰時的活動事務。那麼此時可以輕鬆找到所有活動事務(狀態等於10),並且找到每一個事務正在使用的最後的undo塊(dba列)。然後可以根據每一個事務對應的undo塊鏈表往回尋找,應用每一條undo記錄,因為每一條undo記錄指向了本事務中前一條undo記錄。


2.3 undo塊簡要介紹

      undo塊和普通資料區塊有許多相似之處:塊頭部分記錄了若干控制資訊和中繼資料,行目錄列出了堆積存放在塊中的每一項的位置,若干undo記錄在塊中自底向上堆放在一起,塊空閑空間位於塊中間。但表行和undo記錄最大的區別在於,undo記錄不會被修改,因此一旦undo記錄被寫入塊中,會永遠保留在相同的位置。(表行被修改之後,如果原來位置放不下,會拷貝到另一個新位置,這樣塊中會留下雜亂的指標和臨時的空洞)。

      一個不太為人知的事實是,單個undo塊也可以包含多個事務的undo記錄。一個事務會以獨佔的方式請求undo塊的所有權,pin住,然後使用該塊直到塊滿(此時事務請求新undo塊並更新它的事務表槽以指向新塊)或事務提交。如果事務提交後,undo塊中仍有空閑空間,該塊會被加入到undo段頭中空閑塊池的候選鏈表中。如果發生這種情況,該undo塊會被其他事務使用其剩餘的空間。


     

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.