AWR報告裡的log file sync和user commit為什麼不相等?
Top 5 Timed Foreground Events
Event | Waits | Time(s) | Avg wait (ms) | % DB time | Wait Class |
---|---|---|---|---|---|
db file sequential read | 1,234,292 | 6,736 | 5 | 44.97 | User I/O |
DB CPU | 5,251 | 35.05 | |||
log file sync | 83,846 | 1,594 | 19 | 10.64 | Commit |
log file switch completion | 1,256 | 372 | 296 | 2.48 | Configuration |
enq: TX – index contention | 19,327 | 310 | 16 | 2.07 |
Concurrency |
Instance Activity Stats
Statistic | Total | per Second | per Trans |
---|---|---|---|
user commits | 701,112 | 193.72 |
0.8 |
1小時的AWR報告,log file sync共等待了83864次,user commits共發生了701112次。你可能會問,這兩個值不應該相等嗎?或者應該差不多嗎?
理由聽上去也是比較充分的:
log file sync是使用者在commit事務的時候,產生的等待事件,等待本次事務日誌重新整理到磁碟。因此log file sync每次增加1,user commits就可能增加1。
但是事情要比描述的複雜一些。
比如,遞迴的事務也會產生log file sync等待,但是user commits次數並不增加,user commits只記錄使用者操作直接導致的commit次數,而不記錄遞迴事務產生的。
以下用實驗證明:
create table test (id number);
create sequence seq_test nocache;
建立了一張表和一個不帶有cache的sequence。
execute snap_system_events.start_snap
execute snap_stats.start_snap
select seq_test.nextval from dual;
execute snap_stats.end_snap
execute snap_system_events.end_snap
檢視統計資訊輸出:
Name Value
---- -----
Requests to/from client 5
opened cursors cumulative 7
user calls 7
recursive calls 16
recursive cpu usage 7
session logical reads 8
CPU used when call started 8
CPU used by this session 7
DB time 8
non-idle wait count 8
in call idle wait time 267
session uga memory 130,976
session uga memory max 130,976
messages sent 1
messages received 1
session pga memory 131,072
session pga memory max 131,072
enqueue requests 4
enqueue releases 4
physical write total IO requests 1
physical write total bytes 1,024
cell physical IO interconnect bytes 1,024
db block gets 3
db block gets from cache 3
consistent gets 5
consistent gets from cache 5
consistent gets - examination 5
logical read bytes from cache 65,536
db block changes 4
commit cleanouts 1
commit cleanouts successfully completed 1
calls to kcmgas 1
calls to get snapshot scn: kcmgss 5
redo entries 2
redo size 656
redo wastage 156
redo writes 1
redo blocks written 2
redo synch time (usec) 288
redo synch writes 1
undo change vector size 220
deferred (CURRENT) block cleanout applications 1
table fetch by rowid 1
rows fetched via callback 1
index fetch by key 2
HSC Heap Segment Block Changes 1
session cursor cache hits 4
session cursor cache count 3
buffer is not pinned count 4
parse count (total) 3
parse count (hard) 2
execute count 7
bytes sent via SQL*Net to client 1,314
bytes received via SQL*Net from client 1,565
SQL*Net roundtrips to/from client 5
PL/SQL procedure successfully completed.
Event Waits Time_outs Csec Avg Csec Max Csec
----- ----- --------- ---- -------- --------
rdbms ipc message 1 0 219 219.000 0
class slave wait 0 0 173 173.000 0
log file parallel write 1 0 0 .000 0
log file sync 1 0 1 1.000 0
db file sequential read 1 0 0 .000 0
SQL*Net message to client 9 0 0 .000 0
SQL*Net message from client 9 0 1 .111 0
PL/SQL procedure successfully completed.
發現user commits指標未發生任何變化,但是log file sync增加了1。由於我們的sequence的cache屬性設定的為nocache,因此每次呼叫都要去修改資料字典資訊,產生了遞迴的事務,進而導致了log file sync等待事件,但是由於是遞迴呼叫產生的事務,user commits並未增加。
那麼哪些情況下,user commits增加,但是log file sync卻不增加?
這種情況出現在PL/SQL裡呼叫commit的時候。
繼續拿我們上面建立的那張test表作為實驗用的表。
execute snap_system_events.start_snap
execute snap_stats.start_snap
begin
for i in 1 .. 100 loop
insert into test values(i);
commit;
end loop;
end;
/
execute snap_stats.end_snap
execute snap_system_events.end_snap
上面的程式碼迴圈執行了100次的insert,每次insert後都會提交。按照常規的思考,應該user commits增加100次,log file sync增加100次。但是事實不是這樣的。看下snap相關資訊的輸出。
user commits增加了100次,log file sync僅僅增加了1次。
Name Value
---- -----
Requests to/from client 4
opened cursors cumulative 219
user commits 100
user calls 6
recursive calls 356
recursive cpu usage 10
session logical reads 480
CPU used when call started 10
CPU used by this session 10
DB time 9
non-idle wait time 1
non-idle wait count 99
in call idle wait time 268
session uga memory 130,976
session uga memory max 65,488
messages sent 92
messages received 92
session pga memory 458,752
session pga memory max 196,608
enqueue requests 222
enqueue releases 222
physical write total IO requests 92
physical write total bytes 79,872
cell physical IO interconnect bytes 79,872
db block gets 453
db block gets from cache 453
db block gets from cache (fastpath) 20
consistent gets 27
consistent gets from cache 27
consistent gets from cache (fastpath) 8
consistent gets - examination 16
logical read bytes from cache 3,932,160
db block changes 444
free buffer requested 13
commit cleanouts 107
commit cleanouts successfully completed 107
switch current to new buffer 2
shared hash latch upgrades - no wait 1
calls to kcmgcs 7
calls to kcmgas 106
calls to get snapshot scn: kcmgss 115
redo entries 132
redo size 57,436
redo wastage 19,784
redo writes 92
redo blocks written 156
redo write time 1
redo blocks checksummed by FG (exclusive) 1
redo subscn max counts 4
redo synch time (usec) 505
redo synch writes 1
undo change vector size 14,936
no work - consistent read gets 4
immediate (CURRENT) block cleanout applications 1
deferred (CURRENT) block cleanout applications 55
IMU commits 99
IMU Flushes 3
IMU undo allocation size 56,448
IMU Redo allocation size 356
table scans (short tables) 1
table scan rows gotten 4
table scan blocks gotten 1
table fetch by rowid 1
cluster key scans 2
cluster key scan block gets 2
rows fetched via callback 1
index fetch by key 8
index scans kdiixs1 2
HSC Heap Segment Block Changes 104
Heap Segment Array Updates 1
session cursor cache hits 201
session cursor cache count 11
cursor authentications 1
buffer is not pinned count 13
parse time elapsed 1
parse count (total) 14
parse count (hard) 3
execute count 116
bytes sent via SQL*Net to client 952
bytes received via SQL*Net from client 1,603
SQL*Net roundtrips to/from client 4
sorts (memory) 1
PL/SQL procedure successfully completed.
Event Waits Time_outs Csec Avg Csec Max Csec
----- ----- --------- ---- -------- --------
rdbms ipc message 78 2 797 10.218 0
Disk file operations I/O 1 0 0 .000 0
class slave wait 0 0 217 217.000 0
DIAG idle wait 1 1 100 100.000 0
log file parallel write 92 0 1 .011 0
log file sync 1 0 0 .000 0
SQL*Net message to client 8 0 0 .000 0
SQL*Net message from client 8 0 6 .750 0
PL/SQL procedure successfully completed.
這是為什麼呢?
從等待事件的幾個等待次數來看,Lgwr寫了92次(log file parallel write),使用者會話僅僅等待了log file sync一次。那意味著使用者程式發出commit命令後,並沒有停下來等待lgwr重新整理日誌完成,就繼續處理後面的事務了,並沒有遵守事務的持久化原則!!如果例項在PL/SQL處理的過程中crash,那麼某些提交的事務是不可恢復的。Oracle對此有一個貌似合理的解釋,在PL/SQL沒有處理完畢之前,你不知道已經提交了多次。Oracle不會使他們可恢復,只有在PL/SQL結束的時候,增加redo sync writes次數和進入log file sync等待。在進行PL/SQL處理期間,不停的檢視等待事件,後臺看不到任何的log file sync等待。值得注意的是,如果PL/SQL裡包含了DBLINK,那麼就會使用傳統的提交方式,不會產生出這樣的“異常”。還有就是統計資料裡顯示了會話總共向lgwr傳送了92次message sent請求(請求寫日誌),lgwr也接受到了92次message recived資訊,並且寫了92次(log file parallel write)。你可能會問,到底多久,會話傳送一次寫請求?需要知道的是,傳送寫請求前,會話會去持有redo write latch,然後檢查lgwr是不是已經在處理寫請求了,如果已經在寫了,那麼不重複向LGWR傳送請求了,如果沒在寫,才會發,因此如果你的磁碟寫的速率足夠快,那麼lgwr就會被post的次數越多,成正比的關係。還有如果你的cpu足夠強,那麼PL/SQL塊loop的時間就足夠小,時間小了,那麼lgwr被post的次數也就少了,成反比的關係(在磁碟寫速率一定的情況下)。
最後提醒一句:雖然PL/SQL只有在結束的時候才會等待lgwr寫完成,產生log file sync等待,但是不要認為,在PL/SQL執行過程中,例項crash掉,此次PL/SQL處理的所有事務就會丟失,不是這樣的,只是可能會丟失一部分,是pl/sql在執行過程中,會話是傳送寫請求給lgwr的(message sent),lgwr接收到寫請求後,就要寫日誌,只要是被寫進了日誌檔案的事務就是可恢復的。也就是說,雖然前臺沒有等待log file sync,但是後臺其實一直是在忙著處理你的事務日誌的。
最後,我們可以來一個總結了,在awr報告裡看到user commits次數不等於log file sync次數是一種正常現象,由於一些特定的情況下,會產生出一些“異常”,比如本文中提到的,遞迴的事務不會增加user commits,但是會產生log file sync等待,在PL/SQL裡呼叫commit,會每次增加user commits次數,但是隻是在最後一次迴圈時才會產生log file sync等待。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22034023/viewspace-1214592/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle之 等待事件log file sync + log file parallel write (awr優化)Oracle事件Parallel優化
- log file sync 和 log file parallel writeParallel
- redo的等待log file sync和log file parallel write和redo size設定Parallel
- log file sync等待事件事件
- 【等待事件】log file sync事件
- log file sync" 等待事件事件
- mysql sync_binlog和 innodb_flush_log_at_trx_commitMySqlMIT
- sync_binlog和innodb_flush_log_at_trx_commit解析MIT
- _use_adaptive_log_file_sync設定 降低log_file_sync等待APT
- "log file sync"等待事件-2事件
- "log file sync"等待事件-1事件
- 等待事件 log file sync 小解事件
- _use_adaptive_log_file_syncAPT
- log file sync等待事件總結事件
- innodb_flush_log_at_trx_commit和sync_binlog innodb_flush_methodMIT
- 關於log file sync等待事件的描述事件
- ORACLE AWR效能報告和ASH效能報告的解讀Oracle
- 快捷生出awr和awrsql報告SQL
- log file sync等待事件處理思路事件
- MySQL 5.7中sync_binlog引數和半同步中after_commit和after_sync的區別MySqlMIT
- log file sync(日誌檔案同步) 與 Log file parallel write 等待事件Parallel事件
- 【MySQL】sync_binlog innodb_flush_log_at_trx_commit 淺析MySqlMIT
- 【WAIT】 log file sync等待事件說明AI事件
- 【RAC】RAC 效能分析 - 'log file sync' 等待事件事件
- RAC 資料庫中的'log file sync' 等待事件資料庫事件
- log file sync等待事件的成因及優化方法事件優化
- 【MySQL】五、sync_binlog innodb_flush_log_at_trx_commit 淺析MySqlMIT
- Script to Collect Log File Sync Diagnostic Information (lfsdiag.sql)ORMSQL
- Script toCollect Log File Sync Diagnostic Information (lfsdiag.sql)ORMSQL
- Oracle生成awr報告Oracle
- AWR解析報告分析
- mysql-awr報告MySql
- Oracle 生成awr報告Oracle
- oracle效能awr報告Oracle
- 如何使用awr_set_report_thresholds控制AWR報告裡的sql語句數量SQL
- 生成awr報告的指令碼指令碼
- 詳細的AWR解析報告
- 【AWR】Oracle批量生成awr報告指令碼Oracle指令碼