oracle redo and undo log

來源:互聯網
上載者:User

(摘自http://lishiran.itpub.net/post/28911/288984,李士然之家)

redo--> undo-->datafile
insert一條記錄時, 表跟undo的資訊都會放進 redo 中, 在commit 或之前, redo 的資訊會放進硬碟上. 故障時, redo 便可恢複那些已經commit 了的資料.

redo->每次操作都先記錄到redo日誌中,當出現執行個體故障(像斷電),導致資料未能更新到資料檔案,則資料庫重啟時須redo,重新把資料更新到資料檔案
undo->記錄更改前的一份copy,當你系統rollback時,把這份copy重新覆蓋到原來的資料

redo->記錄所有操作,用於恢複(redo records all the database transaction used for recovery)
undo->記錄所有的前印象,用於復原(undo is used to store uncommited data infor used for rollback)

redo->已遞交的事務,執行個體恢複時要寫到資料檔案去的
undo->未遞交的事務.

redo的原因是:每次commit時,將資料的修改立即寫到online redo中,但是並不一定同時將該資料的修改寫到資料檔案中。因為該資料已經提交,但是只存在聯機記錄檔中,所以在恢複時需要將資料從聯機記錄檔中找出來,重新應用一下,使已經更改資料在資料檔案中也改過來!

undo的原因是:在oracle正常運行時,為了提高效率,加入使用者還沒有commit,但是空閑記憶體不多時,會由DBWR進程將髒塊寫入到資料檔案中,以便騰出寶貴的記憶體供其它進程使用。這就是需要UNDO的原因。因為還沒有發出commit語句,但是oracle的dbwr進程已經將沒有提交的資料寫到資料檔案中去了。

undo 也是也是datafile, 可能dirty buffer 沒有寫回到磁碟裡面去。
只有先redo apply 成功了,才能保證undo datafile 裡面的東西都是正確的,然後才能rollback

做undo的目的是使系統復原到系統崩潰前(關機前)的狀態,再進行redo是保證系統的一致性.
不做undo,系統就不會知道之前的狀態,redo就無從談起

所以instance crash recovery 的時候總是先rollforward, 再rollback

undo
回退段中的資料是以“回退條目”方式儲存。
回退條目=塊資訊(在事務中發生改動的塊的編號)+在事務提交前儲存在塊中的資料

在每一個回退段中oracle都為其維護一張“事務表”
在事務表中記錄著與該回退段中所有回退條目相關的事務編號(事務SCN&回退條目)

redo
重做記錄由一組“變更向量”組成。
每個變更變數中記錄了事務對資料庫中某個塊所做的修改。
當使用者提交一條commit語句時,LGWR進程會立刻將一條提交記錄寫入到重做記錄檔中,然後再開始寫入與該事務相關的重做資訊。

#事務提交成功後,Oracle將為該事備產生一個系統變更碼(SCN)。事務的SCN將同時記錄在它的提交記錄和重做記錄中。

commit
提交事務前完成的工作:
·在SGA區的回退緩衝中產生該事務的回退條目。在回退條目中儲存有該事務所修改的資料的原始版本。
·在SGA區的重做日誌緩衝中產生該事務的重做記錄。重做記錄中記載了該事務對資料區塊所進行的修改,並且還記載了對回退段中的資料區塊所進行的修改。緩衝中的重做記錄有可能在事務提交之前就寫入硬碟中。
·在SGA區的資料庫緩衝中記錄了事務對資料庫所進行的修改。這些修改也有可能在事務提交之前就寫入硬碟中。

提交事務時完成的工作:
·在為該事務指定的回退段中的內部事務表內記錄下這個事務已經被提交,並且產生一個惟一的SCN記錄在內部事務表中,用於惟一標識這個事務。
·LGWR後進進程將SGA區重做日誌緩衝中的重做記錄寫入聯機重做記錄檔。在寫入重做日誌的同時還將寫入該事務的SCN。
·Oracle服務進程釋放事務所使用的所有記錄鎖與表鎖。
·Oracle通知使用者事務提交完成。
·Oracle將該事務標記為已完成。

rollback
回退事務完成的工作:
·Oracle通過使用回退段中的回退條目,撤銷事務中所有SQL語句對資料庫所做的修改。
·Oracle服務進程釋放事務所使用的所有鎖
·Oracle通知交易回復成功。
·Oracle將該事務標記為已完成

舉個例子:
insert into a(id) values(1);(redo)
這條記錄是需要復原的。
復原的語句是delete from a where id = 1;(undo)

試想想看。如果沒有做insert into a(id) values(1);(redo)
那麼delete from a where id = 1;(undo)這句話就沒有意義了。

現在看下正確的恢複:
先insert into a(id) values(1);(redo)
然後delete from a where id = 1;(undo)
系統就回到了原先的狀態,沒有這條記錄了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.