您好,登錄后才能下訂單哦!
如何理解redo的內(nèi)部過程與lgwr,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
Oracle采用混合日志記錄模式,以數(shù)據(jù)塊為單位,即dba + sql,即避免記錄整個(gè)塊,又可快速恢復(fù)
the granularity is at the block level (like physical logging), so one operation is stored for each individual block change
一個(gè)大事務(wù)可由多個(gè)mini-transaction即redo record組成,而每個(gè)record又可由多個(gè)change vector組成;commit/rollback單獨(dú)對(duì)應(yīng)1個(gè)redo record;
每個(gè)redo record包含1個(gè)原子操作,1個(gè)change vector僅對(duì)應(yīng)1個(gè)數(shù)據(jù)塊,change vector在實(shí)際修改塊之前生成;
事務(wù)提交時(shí),將生成的redo+undo和commit record寫入重做日志文件,同時(shí)更新rollback segment header的事務(wù)表;
注:臨時(shí)表只記錄undo
Redo有3種latch
1 Copy,可通過_LOG_SIMULTANEOUS_COPIES設(shè)置多個(gè)
2 Allocation 只有1個(gè)
3 Write 只有1個(gè)
REDO的生成
Redo先在PGA中生成,依次獲取copy latch--allocation latch,將redo寫入log buffer后再修改塊,Lgwr在刷新redo buffer時(shí)獲取write latch,避免同時(shí)多次刷新;
具體步驟如下
1 以排他模式pin住buffer block
2 在PGA中構(gòu)建change vector并組合成redo record,由kconew()/kcoadd()完成
3 調(diào)用kcrfwr()將record寫入log buffer:
計(jì)算record占用的空間大?。?br/> 分配SCN;
獲取copy latch,驗(yàn)證SCN;
獲取allocation latch,檢驗(yàn)log buffer/file是否有足夠空間,有則釋放allocation latch將redo寫入log buffer,否則同時(shí)釋放allocation/copy latch并通知LGWR進(jìn)行l(wèi)og flush/switch;
注:為防止多個(gè)進(jìn)程同時(shí)通知LGWR刷新redo或切換日志文件,引入write latch(只有1個(gè)),只有獲取此latch后才能進(jìn)行下一步操作;
4 將redo record寫至log buffer而后釋放copy latch,檢查是否達(dá)到觸發(fā)LGWR閾值;
5 更改buffer block
nologging
此模式下仍記錄redo record,其下的change vector類型均為INVALID;每個(gè)record可對(duì)應(yīng)多個(gè)數(shù)據(jù)塊,應(yīng)用該redo時(shí)相應(yīng)數(shù)據(jù)塊將被標(biāo)識(shí)為soft-corrupt;
LGWR觸發(fā)閾值
1 由前臺(tái)進(jìn)程觸發(fā):log buffer空間不足;事務(wù)提交
2 log buffer滿1/3
3 redo超過1M
4 3秒超時(shí)
5 日志切換
6 redo線程關(guān)閉
LGWR觸發(fā)過程
1 獲取write/allocation latch,前者防止LGWR被多次請(qǐng)求,后者防止為前臺(tái)進(jìn)程繼續(xù)分配redo空間
2 確定待寫的log buffer范圍(從起始處至待刷新的buffer),分配新SCN(避免兩次flush使用同一個(gè)SCN)
3 釋放allocation latch
4 計(jì)算所需redo write次數(shù),因?yàn)閘og buffer為環(huán)形,故至多寫兩次(分布于頭尾)
5計(jì)算target RBA,依據(jù)log_checkpoint_interval增進(jìn)增量檢查點(diǎn)
6 釋放write latch
7 確保待寫的log buffer都復(fù)制完畢,即等待所有copy latch釋放
8 LGWR更新redo block header的SCN和checksum(可選)
9 執(zhí)行磁盤寫,可修改_lgwr_async_io啟用異步IO
組提交
Lgwr在c1處接到請(qǐng)求,開始刷新log buffer時(shí)新增了c2/g1/c3,此時(shí)需等待c3寫完(釋放redo copy latch)后,連同c3一起刷新,
常見的redo等待事件
log file parallel write-由lgwr觸發(fā),將redo record寫入當(dāng)前l(fā)og文件,其并行度由物理磁盤數(shù)決定
log file sync-由前臺(tái)進(jìn)程等待,從commit/rollback直到lgwr將日志寫入磁盤并通知請(qǐng)求進(jìn)程為止
log buffer space- log buffer中沒有足夠空間存放新生成的redo,說明lgwr寫出速度較redo生成慢
log file switch-分為checkpoint incomplete和archiving needed
Log file sync流程
lgwr會(huì)post哪些前臺(tái)進(jìn)程?
當(dāng)lgwr刷新完日志后,會(huì)post相應(yīng)的前臺(tái)進(jìn)程(wakeup)繼續(xù)工作,那么lgwr怎么判斷應(yīng)該wakeup哪些前臺(tái)進(jìn)程呢?
log file sync等待的p1參數(shù)的含義為:P1 = buffer# in log buffer that needs to be flushed
當(dāng)lgwr刷新完buffer后,會(huì)掃描活躍會(huì)話列表,查看哪些會(huì)話在等待log file sync,而且會(huì)話的buffer#小于等于它所刷新的log buffer的最大值,這些會(huì)話會(huì)被wakeup。
Lgwr file sync與buffer busy wait
事務(wù)commit的stack call如下
為ktcCommitTxn=> ktucmt => kcbchg => kcbchg1_main => kcrfw_redo_gen => kcrf_commit_force
kcbchg==> block change ,為什么要發(fā)生block change呢? 因?yàn)閏ommit需要對(duì)在Buffer Cache里的block做immediate block cleanout,期間需要排他模式pin;
若此時(shí)其他會(huì)話訪問該塊則會(huì)等待buffer busy wait
http://www.askmaclean.com/archives/why-slow-redo-write-cause-buffer-busy-wait.html
歸檔日志流程
1 ARCH讀取控制文件以決定待歸檔的日志文件
2 分配歸檔內(nèi)存_LOG_ARCHIVE_BUFFERS * _LOG_ARCHIVE_BUFFER_SIZE;
3 以只讀方式打開待歸檔日志組的所有成員(以輪循方式依次讀取log buffer),并驗(yàn)證log file header;如果db_block_checksum=true每個(gè)log block還將驗(yàn)證checksum
4 創(chuàng)建并打開歸檔日志文件
5 以循環(huán)方式將日志從online log復(fù)制到archive log,對(duì)每個(gè)buffer都執(zhí)行sanity check
執(zhí)行完畢后關(guān)閉online log和archive log
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。