二者的由來,有二:
1)redo records的產生十分頻繁
2)server process每次產生的量卻不大
倘若每次產生的redo就須由大量高並發sp寫入redo log file,則存在兩個問題:
1)I/O開支大
2)redo file爭用
由此,Oracle在redo log機制中引入了log buffer和LGWR。
redo log buffer緩衝了sp產生的redo records,提高了oracle高並發的效能。LGWR則將log buffer中的records批量flush到redo file。對於oracle而言,只要對資料庫的改變寫入到redo log file,那麼相關的事務絕不丟失。
在事務提交時,會產生一個commit的change vector,這個CV被寫入log buffer後,sp會發出一個訊號,要求LGWR將和這個事務相關的redo records寫入到redo file,只有這個事務相關的redo全部安全著陸,sp才會向client發出事務提交成功的資訊“Commit Complited”。
由於redo entries實是嬌貴且重要。為了保障redo records的安全,oracle還實現了:
1)LGWR繞過OS的緩衝直接寫到redo log file,避免宕機而丟失redo
2)redo log file的block size和資料庫的block size是完全不同的,事實上,和OS的I/O block size如出一轍,從而一個redo block在一次物理i/o時可以同時寫入而不出現塊斷裂。
redo buffer是一個迴圈使用的順序讀寫的buffer:
1)redo records寫入log buffer是按順序的
2)當log buffer寫滿後,會從頭開始寫(這種情況是不會出現的)
log buffer資料的寫入是由sp完成的,這個寫操作屬於高並發,而log buffer的空間分配是個串列操作。所以需要鎖的保護:
1)redo copy latch:寫redo 到redo log buffer
2)redo allocation latch:控制log buffer空間分配
為了騰出更多的log buffer,oracle設計了LGWR寫的觸發條件:
1)commit時
2)1M redo entries時
3)超過_log_io_size參數指定的大小時
預設值是LOG BUFFER大小的1/3,這個參數單位是REDO LOG BLOCK
- SQL> col name for a15
- SQL> col value for a10
- SQL>
- SQL> select a.ksppinm name,b.ksppstvl value,a.ksppdesc description
- 2 from x$ksppi a,x$ksppcv b
- 3 where a.indx = b.indx
- 4 and a.ksppinm like '%log_io_size%'
- 5 /
-
- NAME VALUE DESCRIPTION
- --------------- ---------- --------------------------------------------------------------------------------
- _log_io_size 0 automatically initiate log write if this many redo blocks in buffer
4) 每3秒
5)DWWn寫之前寫
LGWR寫的具體過程:
1)先嘗試擷取redo writing latch,確保其他process不會繼續觸發lgwr(這裡可能會產生log file sync等待事件)
2)擷取redo allocation latch(public redo allocation latch),防止有新的change vector繼續寫入log buffer,造成LGWR無法確定應該寫多少redo.
3)LGWR確定寫的範圍(從上次lgwr啟動所寫的最後一個日誌塊到這個時間點時的最後一個被使用的所有寫滿or未寫滿的日誌塊)此時前台process仍可以向這個範圍內的redo block(buffer)寫內容(從PGA寫)所以lgwr不阻礙其它進程獲得redo copy latch(即:不阻止其它進程向log buffer 中可用塊中寫change vector)
4)確定redo block(buffer)後產生新SCN號
5)LGWR釋放redo allocation latch與redo writing latch
6)LGWR需要等待 其它進程對要寫入記錄檔的block的更新操作完成(pga-log buffer的操作),通過判斷日誌block(buffer)上的redo copy latch是否都釋放。
7)將第4步scn號copy到要寫入logfile的log buffer的塊頭裡,然後觸發物理的寫操作,將這些待寫日誌塊寫入redo file
“LOG BUFFER大於3M浪費空間,對效能影響不大的觀點”是錯誤的,因為存在LOG FILE SYNC等待事件:指等待LGWR將log buffer的資料寫入到redo log file中。一般:
1)如果事務在做commit時,會有log file sync等待事件。
2)redo writing latch競爭過多,sp會有log file sync等待事件。
這種情況下,加大log buffer,適當調整_log_io_size大小,就可能可以減小log file sync等待事件。