Oracle 日志的核心意义(快速提交,写缓存,回滚)
生活随笔
收集整理的這篇文章主要介紹了
Oracle 日志的核心意义(快速提交,写缓存,回滚)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這篇文章是參考甲骨論老相老師的教學視頻
http://v.youku.com/v_show/id_XMzk1MDA3NjA4.html
所做的學習筆記
1.Oracle有1個重要的原則.
??????? 這個原則就是已提交的事務,Oracle保證不會丟失. 除非服務器存儲設備出問題了.
??????? 也就是說,如果用戶在數據庫執行一些DML sql語句, 但是并沒有提交的話, 這時服務器突然崩潰, 或者斷電了. 重啟后, 用戶的這些修改有可能找不回來了.? 但是用戶,一但執行commit動作, 即使服務器崩潰, 重啟后用戶的修改還能找回來.
2. 后臺進程DBWR 不斷將LRUW鏈(臟buffer) 的冷端寫入到dbf文件中.
???????? 前面章節已經提過很多次,? 當server process修改完數據后(可能若干個buffer), 就直接返回給用戶, 告訴用戶修改完成了, 但是并不負責將這些buffer寫入到dbf文件, 而是將這些buffer掛到LRUW chain,寫入dbf文件的動作交由后進程DBWR執行.
???????? 如下圖:
????
?????? 這樣的好處時,提高了用戶的速度感受, 因為寫入buffer到dbf文件是1個很耗時間的物理IO動作, 如果讓server process執行這個動作才返回信息給用戶的話, 用戶就會覺得數據庫性能很差了.
3. 用戶提交commit時, 臟buffer并沒有寫入dbf文件.
?????? 這個很明顯了, 用戶commmit后,一般馬上就可以執行下1個動作了, 但是這時臟buffer并沒有寫放入到dbf文件. 只不過被掛在LRUW chain讓后臺DBWR來寫入.???
?????? 但如果這時服務器崩潰, 是否這些臟buffer就會丟失? 是否違反了Oracle上述的那個原則?? 其實不是, Oracle有另1個機制保證commit即使臟buffer還未寫入dbf文件, 也能把臟buffer重現出來.
?
?????? 如果沒有這個機制, 用戶commit后, 為了保證oracle的那個原則, server process就必須等待臟buffer寫入dbf文件后才能返回完成信息給用戶.? 這樣的話commit的速度就十分緩慢了.
??????? 這個機制就是日志系統了.
??????
4.所以說日志系統的第1個核心意義就是提高commit速度.
??????? 下面講解下這個機制的實現原理.
????????
??? 如上圖:
??? 4.1 內存中的redo log buffer 相對于buffer cache來一般很小, 只有幾MB空間.
??? 4.2 server process 一旦修改了buffer, 無論commit與否,都會產生redo 寫入到redo log buffer.
??? 4.3 server process 不commit的話, DBWR是不會將該buffer是不會寫入到dbf文件中的, 而LGWR 是不斷地將redo log buffer里的日志數據寫如到logfile里面.
?? 因為redo log buffer的大小很小,例如9g以前大概只有3g, 所以有幾個條件會觸發LGWR將redo log buffer里的數據寫入到日志文件.
??? 例如: a.? 每隔3秒寫一次.
????????????? b.? redo log buffer的占用到1MB(留下2BM作緩沖應急)
?????????????
??? 所以, 很多時候, server process修改了若干數據, 在commit之前, 對應的日志就已經寫入到日志文件里了. 所以commit時就能馬上提示用戶完成, 然后這時DBWR才按需將對應臟buffer寫入到dbf文件.
???? 即使這時服務器崩潰,? 但是由于日志文件里已經有其修改的記錄, 所以能根據這些日志數據, 把臟buffer重現出來, 就能保證commit后的數據不丟失了.
??
??? 4.4 如果commit的時候, 對應日志還在redo Log buffer 中, 那么commit動作也會觸發LGWR將日志數據寫入到日志文件. 才會提示用戶commit完成.
??? 有時後,用戶的sql語句修改完馬上就commit,? 對應的日志還在redo log buffer, 還沒寫入日志文件, 這時 commit動作就會觸發LGWR把日志數據寫入logfiles啦.
????? 當很多個session修改數據庫時,就會產生大量的日志數據, LGWR就比較繁忙了.
????? 可能有人會問, 寫入日志文件同樣是1個物理IO動作, 為什么commits 寫入臟buffer 就慢,? 寫入日志就快呢.
?????? 是因為1個事務中, 可能有多條DML語句, 修改的數據block可能遍布dbf文件中各個位置.? 而日志數據是嚴格按照修改時間產生的, 寫入日志文件時,在磁盤中也是一段物理上連續的數據.
??????
???? 所以寫入臟buffer 會耗費大量是時間在磁盤尋道上(磁頭知道到對應block的物理地址), 而物理IO 90%的時間都是尋道時間, 所以同為物理IO,? 寫入日志數據到日志文件時幾乎不用尋道, 只要按照順序一直寫就是了. 比寫入臟buffer快很多.
???? 所以說, 日志系統能大大加快commit速度!
5.所以說日志系統的第2個核心意義是令到Buffer cache發揮寫緩存的作用.
??? 當若干server process想從數據文件中讀出數據時, Buffer cache能作為1個讀緩存發揮作用, 因為第1次讀取數據文件中的1個block時, 就會把這個block放入buffer cache中, 下一次讀取這個block時就避免多余的物理IO了.
?????? 但是當DBWR把臟buffer從buffer cache寫入到dbf文件這個1個過程中, 是沒有寫緩存的, 因為DBWR寫入1個臟buffer就發生1次物理IO,? 下次寫入同樣1個臟buffer時也要發揮物理IO.
?????? 但是因為有日志系統的存在, 令到server process 在commit 時不必DBWR不必馬上將對應臟buffer 寫入到數據文件中, 而是將其放到LURW chain中,? 如果server process在接下來一段時間多次修改這個buffer, 那么這個臟buffer就會移到LRUW chain的熱端. 寫入到數據文件的優先級就更低了.? 所以實際上server process發生了對1個block的多次改動, 發生了多次commit動作, 但是DBWR把最后一次的改動結果寫入到dbf文件中的就行了,? 因為日志系統的存在, 不怕服務器崩潰后丟失了數據改動.
??????? 所以說日志令buffer cache發揮寫緩存的作用, 如果沒有日志, oracle為了保證commit后數據不丟失的原則, 務必commit 1次 寫入臟buffer1次...
?????? 而實際上, DBWR 會繞過操作系統的緩存, 直接將數據寫入到磁盤上的緩存中.? 至于磁盤本身有沒有將磁盤緩存的數據寫入到磁盤扇區對應地址上, DBWR是不知道的.?? 因為有電池的存在, 正常來將磁盤就算斷電也會保證將磁盤緩存中的數據寫入扇區. 但是若過磁盤的緩存出現故障, Oracle實際上還是有可能丟失數據的.
6.所以說日志系統的第3個意義是回滾數據.
????? 這個很簡單, 沒什么可說的,? 就是1個事務中發生了回滾動作, server process 就會提取日志數據, 根據日志把改動還原回去.
?????? 同樣, 因為數據改動可以rollback這個特性, 日志系統就可以協助用于構造CR塊了,
?????? 至于什么是CR塊, 之前已經提過很兩次了, 這里就不重復了哈哈.
?
?????
??
??
總結
以上是生活随笔為你收集整理的Oracle 日志的核心意义(快速提交,写缓存,回滚)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Oracle 日志原理剖析
- 下一篇: Oracle - Log buffer