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