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