Oracle前滾和Oracle後滾的學習案例

來源:互聯網
上載者:User

案例(1)

就假設我修改了一條資料:update people set name='Fusnow' where name='old fusnow';

那我需要做的事情包括:

在redo log buffer產生redo資訊(包括對錶的redo,undo的redo,索引什麼的就不考慮了)

在buffer cache裡修改name='Fusnow',修改undo segment

------------------

情況1

如果一切正常,我現在commit,commit會觸發lgwr把redo log buffer裡的資訊寫入到磁碟的redo log file,如果這個操作成功完成,那我的資料安全了,現在如果系統崩潰,儘管可能會丟失buffer cache裡的髒資料,但可以從redo log裡找到重做資訊,所以,可以恢複,當然這個情況不用rollback。

------------------

情況2

如果lgwr把redo log buffer裡的資訊寫入到磁碟的redo log file的過程中系統就崩了,那實際上對使用者而言commit沒有成功就報錯了,這時候datafile和redo log上都沒有我們要的資訊,所以正好,系統啟動的時候我這個改動的roll forward/back 都省了。

------------------

情況3

如果commit之前,有什麼原因導致我們要flush buffer cache,比如buffer cache滿了,oracle要吧buffer cache裡的dirty data寫入到磁碟,這要觸發dbwr,但dbwr寫之前一定要觸發lgwr,先把redo log buffer裡的資料寫入到redo log file。原因很簡單,如果不觸發lgwr,由於對於我的這個改變的髒資料包括表的改動和undo改動,而dbwr很可能不是在一次io裡面把這些髒資料寫入磁碟,如果就是這麼巧,我們先寫入了表的改動,還沒來得及寫undo的髒資料,資料庫崩了,那現在我們的狀態是datafile裡面有改過的表資料,沒有undo資料,redo裡面沒有redo資訊,由於我是沒有commit,所以要復原,但這種情況下是不可能的,因為undo丟了,可以重建undo的redo也丟了。因此,dbwr一定要觸發lgwr。

如果在dbwr觸發lgwr的前提下,我們先寫入了表的改動,還沒來得及寫undo的髒資料的時候資料庫崩了,我們實際上是先roll forward,通過redo產生undo,再rollback,通過undo復原事務。

當然,有兄弟也提過了了,先後順序是1.roll forward, 2.open database, 3.rollback,我想這主要是oracle為了節省時間,因為設計上按照1.roll forward, 2.rollback, 3.open database的順序應該也是可以的,但這樣比較慢,我們完全可以在roll forward結束後馬上open database,然後讓使用者訪問資料庫的其他部分,讓smon慢慢rollback,這時候如果使用者想訪問正被復原的資料是會被堵塞的。當然,在fast模式下,oracle會優先rollback使用者想訪問的block,讓使用者儘快可以訪問這些正被rollback的資料。

案例(2)

假定有一下動作陳述式:

update gaojf set  name='exitgogo' where name='old_exitgogo';

這個語句是這樣執行的:

1:首先檢查name='old_exitgogo'是否記錄在buffer cache中,如果不在,讀取到buffer中。

本文URL地址:http://www.bianceng.cn/database/Oracle/201410/45542.htm

2:在復原段資料表空間的相應復原段事務表中分配事務段,這個操作產生redo資訊。

3:從復原段中讀入或者在buffer中或者說是在buffer cache中建立name='old_exitgogo'的前鏡像,這個操作同樣產生redo資訊並記錄寫入redo buffer。

4:在資料緩衝區修改name='exitgogo',這個操作的日誌資訊也寫入redo buffer。

5:當使用者提交時刻,會在redo buffer中記錄提交資訊,同時會在復原段中標記該事務為非啟用狀態(inactive),這點很重要。

可以看到,在一個事務進行過程中,redo和undo是交替出現的,redo buffer會首先記錄此事務變化前的資料和變化後的資料,然後把變化前的資料寫入復原段,最後才在資料緩衝區中修改資料。

以下把instance crash後,先forward,再open,再把未提交的rollback的詳細過程介紹如下:

當以上這個語句執行到第四步的時候,正巧有某種原因導致oracle要flush buffer cache,比如buffer cache滿了等等時間發生,此時,oracle要把髒資料寫入磁碟,也就是此時觸發了dbwr寫進程,又由於dbwr寫之前一定要觸發lgwr,所以以上語句執行的前4步都會寫入redo檔案中。

此時,如果發生資料庫崩潰,由於沒有提交動作發生,也就是沒有第五步的操作了 那麼,在資料庫復原段中標記這個事務將仍為啟用狀態(active)。

在資料庫重新啟動過程中,後台進程SMON會掃描undo segment header,將發現上面的執行語句還是處於啟用狀態,於是, 將這些未提交的活動事務標誌為dead。

roll forward可能發生在以下兩種情況下:

(1):如果以上語句在執行第三步時,資料庫crash,那麼undo復原段中記錄的此事務的前鏡像資料將丟失,資料庫在啟動過程中,會首先發生rollforward,根據redo檔案記錄的資訊,在復原段中產生name='old_exitgogo'的前鏡像。這也是redo為什麼記錄undo資訊的原因。

(2):如果以上語句提交後,dbwr進程還沒有來的及將修改資訊寫到資料檔案,此時資料庫崩了,那麼資料庫在重新啟動後也要進行roll forward,此時根據redo log檔案的記錄更新資料檔案。也就是讓以上語句的更改生效,所以只要提交的資料就不會丟失。

接下來資料庫就可以open。

此後有兩種情況下將發生復原:

(1):後台進程SMON發現dead事務,根據情況去逐步復原。

(2):由於資料庫已經open,可能就有很多使用者進程訪問這些dead事務塊。此時這些前台的進程將會去undo segment取得前鏡像的資料,例如以上的name='old_exitgogo'這個值,然後修改資料緩衝區,完成復原。這個過程本身也要產生redo,因此回退這個操作代價很大。

至此,資料庫啟動過程的前滾以及後援動作完成.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.