【internal】redo生成機制
redo生成流程
oracle10g之後引入的IMU(in memory undo)機制,這個機制改變了部分redo的生成機制,所以,redo生成流程必須分兩部分介紹:
傳統流程
IMU機制下的流程。
先說下如何區分系統是否使用了IMU。
10g以後,預設是啟用了IMU的,但有些條件下IMU被關閉。
這些條件有
1、RAC環境中
2、資料庫級別啟用了supplement log(任何級別)。
3、系統隱含引數_in_memory_undo引數設定成False的情形下。
4、redo檔案過小,小於50M的情形下。
5、(部分不使用IMU)當系統併發很高,當前所有的IMU Latch都被使用,新的IMU Latch請求都失敗,則會話不會等待IMULatch的釋放,而是直接使用傳統流程,繞過IMU。因此IMU層面不會造成等待。
6、(部分不使用IMU)當一個事務很大,產生的redo或回滾資料超過了共享池中IMU區、privateRedo Strand Area中任何一個的大小,則這個事務將不再使用IMU方式,原本寫的IMU區資料和redo資料將全部刷出。這個時間叫做IMUFlashes。每發生一次這種事件,v$sysstat中的IMU Flushes值將加1。
以上的檢查條件略多,所以,基本上通過
select * from v$sysstat a where a.NAME like '%IMU%'
檢視IMUcommits行的值,若這個值為0,則基本是沒啟用IMU了。
再說下IMU下的redo生成流程
l
流程解析:
1、server程序從共享池的sql中把目標值拿到PGA中。
2、申請IMULatch和redo allocation Latch。這裡IMU Latch和redo allocation Latch會有多個,對應privateredo area也會被分成多個strands。申請成功後,則分配IMU和private redo區間,分配完釋放兩個Latch。此區間就成程序私有的了,後續進行DML操作可以直接往裡面寫資料。
3、從PGA中生成資料塊的更改資訊(資料塊的redochange vector)。
4、從bufferpool中的對應塊裡找到修改前的值,放入到shared pool中的私有IMU區。並將新值寫入到buffer pool中的資料塊。該塊變成髒塊。
(4.5)SMON會定期醒來,檢查IMU中的資料,生成undo對應的redo資訊寫入私有redo區,並把資料刷入bufferpool中的undo block,該undo塊成為髒塊。
5、當事務commit。申請logbuffer區的redo allocation Latch(public area)。申請成功後,為該事務在redo buffer中分配一段空間,釋放Latch。
6、申請redocopy Latch。申請成功後,把IMU中剩餘資料生成redo,刷到undo block.並在copy Latch保護下把私有redo區中的資料拷貝到bufferpool。拷貝完成後釋放redo copy Latch。
7、LGWR開始把bufferpool中的資料往磁碟寫。
8、寫完成後commit完成。
傳統方式下的redo生成流程
流程解析:
1、server程序從共享池的sql中把目標值拿到PGA中。
1.5 從bufferpool中把old值拿到PGA中。
1.6 生成undo塊的redochange vector,生成data塊的redo change vector.
2、申請redoallocation Latch。申請成功後,則在buffer pool裡分配一段空間,釋放redo allocation Latch。
3、申請redocopy Latch。
4、申請成功後將undo的CV和data的CV拷貝到logbuffer。
5、修改bufferpool中的undo block(轉為dirty block)。
6、修改bufferpool中data block(轉為dirty block)。
(此時一個update語句即算結束)
7、若發生commit,將觸發LGWR把logbuffer中內容寫入到log file。
(commit完成)
redo檔案格式
redo過程事件分析
log buffer space
事件原因:
申請logbuffer中的空間不得。
log file sync
事件原因:
使用者commit之後,等待把相關redo資訊從logbuffer刷入log file的過程。
造成這個事件的原因主要有:
1、commit過於頻繁
2、LGWR工作過慢,一般伴隨著logfile parallel write,則表示IO過慢。
log file parallel write
事件原因:
LGWR在執行從logbuffer刷入log file過程中,開始物理IO的過程。(開始物理IO之前需要進行一些Latch的申請,以及程序間message的傳遞,這些部分加上物理IO就是logfile sync的過程。)
log file switch(checkpoint incomplete)
事件原因:
日誌切換時發生完全檢查點,但這個完全檢查點優先順序並不高,不會立即觸發DBWn程序寫入dirtyblock,因此日誌切換主要等待在關閉當前日誌,開啟新日誌的過程(即log file switch completion),但若日誌組切換了一輪,又切換到當前日誌組,可當前日誌中對應的髒塊還沒有寫完,即日誌仍為active狀態,這時session需要等待DBw0把改日誌對應的髒塊全部寫出,把檢查點scn登記到controlfile和data file header這些內容,這個等待過程就是 log file switch(checkpointincomplete) 。
所以,造成這個事件的原因主要有
1、日誌產生的太快大,導致切換過於頻繁。
2、當前日誌組設定的過少,或過小,導致切換過於頻繁。
3、DBWn程序寫的太慢,導致一輪日誌切換的時間仍然寫不完。
log fileswitch completion
事件原因:
這個過程主要就是關閉當前日誌,開啟新日誌。
log fileswitch(private strand flush incomplete)
事件原因:
log fileswitch (archiving needed)
事件原因:
遺留問題:
1、dumpshared pool檢視IMU等相關記憶體。
2、pbsa和pvsa數目初始化值及如何設定
3、redobuffer大小的初始化值和設定
4、相關latch的初始化大小和設定,redoallocation latch、redo copy latch、