天天看點

觸發redo寫的幾個條件

主要有以下幾個條件觸發LGWR執行寫操作:

1.逾時(timeout)

當LGWR處于空閑狀态時,它依賴于rdbms ipc message等待,處于休眠狀态,直到3秒逾時時間到。

如果LGWR發現有redo需要寫出,那麼LGWR将執行寫出操作,log file parallel write等待事件将會出現。

啟用10046事件,從LGWR跟蹤日志中可以清楚的觀察到這些事件:

WAIT #0: nam='rdbms ipc message' ela= 2999554 p1=300 p2=0 p3=0
WAIT #0: nam='rdbms ipc message' ela= 2999470 p1=300 p2=0 p3=0
WAIT #0: nam='rdbms ipc message' ela= 566819 p1=300 p2=0 p3=0
WAIT #0: nam='log file parallel write' ela= 115 p1=1 p2=2 p3=1
WAIT #0: nam='rdbms ipc message' ela= 45752 p1=213 p2=0 p3=0
WAIT #0: nam='log file parallel write' ela= 94 p1=1 p2=3 p3=1
WAIT #0: nam='rdbms ipc message' ela= 51762 p1=208 p2=0 p3=0
WAIT #0: nam='log file parallel write' ela= 91 p1=1 p2=1 p3=1
WAIT #0: nam='rdbms ipc message' ela= 29033 p1=200 p2=0 p3=0
WAIT #0: nam='log file parallel write' ela= 99 p1=1 p2=2 p3=1
WAIT #0: nam='rdbms ipc message' ela= 40293 p1=197 p2=0 p3=0
WAIT #0: nam='log file parallel write' ela= 87 p1=1 p2=1 p3=1
      

2.門檻值達到

隻要一個程序在log buffer中配置設定空間,已經使用的Log buffer的數量将被計算。如果使用的塊的

數量大于或等于_log_io_size參數設定,那麼将會觸發LGWR寫操作。

如果此時LGWR未處于活動狀态,那麼LGWR将被通知去執行背景寫操作。

預設的_log_io_size等于1/3 log buffer大小,上限值為1M,此參數在X$KSPPSV中顯示的0值,意為預設值。

也就是,LGWR将在Min(1M,1/3 log buffer size)時觸發。注意此處的log buffer size是以log block來衡量的。

此值通常為512 bytes.

20:33:15 SQL> @D:/GetHiddenParameter.sql
Enter value for par: log_io
old  14:   x.ksppinm like '%_&par%'
new  14:   x.ksppinm like '%_log_io%'

NAME                           VALUE                     ISDEFAULT ISMOD      ISADJ
------------------------------ ------------------------- --------- ---------- -----
_log_io_size                   0                         TRUE      FALSE      FALSE

Elapsed: 00:00:00.02
      

獲得Oracle的隐含參數,參考 如何擷取Oracle的隐含參數

3.送出

當一個事物送出時,在redo stream中将記錄一個送出标志。

在這些redo被寫到磁盤上之前,這個事物是不可恢複的。是以,在事務傳回成功标志給使用者前,必須等待LGWR寫完成。程序通知LGWR寫,并且以log file sync事件開始休眠,逾時時間為1秒。

Oracle的隐含參數_wait_for_sync參數可以設定為false避免redo file sync的等待,但是就将無法保證事務的恢複性。

20:46:02 SQL> @D:/GetHiddenParameter.sql
Enter value for par: wait_for

NAME                           VALUE                     ISDEFAULT ISMOD      ISADJ
------------------------------ ------------------------- --------- ---------- -----
_wait_for_sync                 TRUE                      TRUE      FALSE      FALSE
      

注意,在遞歸調用(recursive calls)中的送出(比如過程中的送出)不需要同步redo直到需要傳回響應給使用者。是以遞歸調用僅需要同步傳回給使用者調用之前的最後一次Commit操作的RBA。

存在一個SGA變量用以記錄redo線程需要同步的log block number。

如果多個送出在喚醒LGWR之前發生,此變量記錄最高的log block number,在此之前的所有redo都将被寫入磁盤。

這有時候被稱為組送出(group commit).

4.在DBWR寫之前

如果DBWR将要寫出的資料的高RBA超過LGWR的on-Disk RBA,DBWR将post LGWR去執行寫出。

在Oracle8i之前,此時DBWR将等待log file sync事件。

從Oracle8i開始,DBWR把這些Block放入一個defer隊列,同時通知LGWR執行redo寫出,DBWR可以繼續執行無需等待的資料寫出。

參考:

http://www.ixora.com.au/notes/redo_write_triggers.htm zz:http://www.eygle.com/archives/2005/01/oracleoeooedele.html