讨論主題:
1、你能重制buffer busy waits等待嗎?
2、重制buffer busy waits等待之後,你抓住産生buffer busy waits 的原兇了嗎?
3、加大log buffer會減少buffer busy waits等待嗎?
4、找到原兇之後如何優化buffer busy waits等待?
測試DB版本11g:
SQL> select * from v$version where rownum=1;
BANNER
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
(一)、用Dtrace +mdb跟蹤模拟buffer busy waits等待事件
SQL> select sid from v$mystat where rownum=1;
SID
125
SQL> select spid from v$session s,v$process b where s.paddr=b.addr and s.sid in(select sid from v$mystat where rownum=1);
SPID
1887
SQL> select rowid,name from t1 where id=1;
ROWID NAME
AAASTVAAGAAAACnAAA BBBBBB
SQL> select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from t1;
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
6 167
SQL> select hladdr from x$bh where file#=6 and dbablk=167;
HLADDR
00000003A41E4080
(二)、再開一個視窗用mdb設mdb斷點
-bash-3.2# mdb -p 1887
(三)、再回到125号會話:對 rowid='AAASTVAAGAAAACnAAA'這條記錄做修改
update t1 set name='BBBBBB' where rowid='AAASTVAAGAAAACnAAA';
這時已被阻塞
(四)、接第二步驟開始用mdb跟蹤
Loading modules: [ ld.so.1 libc.so.1 ]
sskgslcas :b
:c
mdb: stop at sskgslcas
mdb: target stopped at:
sskgslcas: movq %rsi,%rax
sskgsldecr :b
mdb: stop at sskgsldecr
sskgsldecr: lock subq %rsi,(%rdi)
::step
sskgslcas+3: lock cmpxchgq %rdx,(%rdi)
(五)、打開144号會話:查詢rowid='AAASTVAAGAAAACnAAA'的這行記錄
SQL> conn gyj/gyj
Connected.
SQL> select distinct sid from v$mystat;
SID
144
SQL> select * from t1 where rowid='AAASTVAAGAAAACnAAA';
這時查詢被阻塞
(六)、打開138号會話:觀察等待事件
SQL> select sid,event,total_waits,time_waited_micro from v$session_event where lower(event) like 'buffer%';
SID EVENT
TOTAL_WAITS TIME_WAITED_MICRO
144 buffer busy waits
1 7005803
重制了buffer busy waits等待事件
buffer busy waits 的原兇是:寫阻塞讀的原因!
一、當log_buffer=5210112時分别在兩會話上跑SQL,産生buffer busy waits等事
1.查目前的log_buffer大小,即為5M
sys@OCM> show parameter log_buffer;
NAME TYPE VALUE
log_buffer integer 5210112
2.分别在兩會話上跑sql
begin
for i in 1 .. 500000 loop
update t1 set id=id+0 where rowid='AAAS1wAADAAAAFUAAA';
commit;
end loop;
end;
/
declare
m_name varchar2(50);
for i in 1..500000 loop
select name into m_name from gyj.t1 where rowid='AAAS1wAADAAAAFUAAA';
end loop;
3.産生的buffer busy waits等事
sys@OCM> sys@OCM> select sid,event,total_waits,time_waited_micro from v$session_event where event in('log buffer
space','buffer busy waits') and sid in(141,24);
SID EVENT TOTAL_WAITS TIME_WAITED_MICRO
24 buffer busy waits 14915 13445559
24 log buffer space 41 12871945
141 buffer busy waits 1866 554125
141 log buffer space 31 14763344
二、當log_buffer=40960000時分别在兩會話上跑SQL,産生buffer busy waits等事
-
修改log_buffer=5210112為20480000
sys@OCM> alter system set log_buffer=20480000 scope=spfile;
sys@OCM> startup force;
sys@OCM> show parameter log_buffer
log_buffer integer 20480000
select name into m_name from gyj.t1 where rowid='AAAS1wAADAAAAFUAAA';
3.産生buffer busy waits等事
sys@OCM> select sid,event,total_waits,time_waited_micro from v$session_event where event in('log buffer
space','buffer busy waits') and sid in(142,20);
SID EVENT TOTAL_WAITS TIME_WAITED_MICRO
20 buffer busy waits 17259 7585360
142 buffer busy waits 4902 1343520
三、對步驟一與步驟二對比
sys@OCM> sys@OCM> select sid,event,total_waits,time_waited_micro from v$session_event where event in('log buffer
SID EVENT TOTAL_WAITS TIME_WAITED_MICRO
24 buffer busy waits 14915 13445559
24 log buffer space 41 12871945
141 buffer busy waits 1866 554125
141 log buffer space 31 14763344
SID EVENT TOTAL_WAITS TIME_WAITED_MICRO
20 buffer busy waits 17259 7585360
142 buffer busy waits 4902 1343520
比較TIME_WAITED_MICRO,明顯是步驟一的比步驟二的大。步驟一的log_buffer=5M ,步驟二的log_buffer=20M
說明步驟二的buffer busy waits的等待時間少。即增大log_buffer可以減少buffer busy wait等待的時間。
4、找到原兇之後如何優化buffer busy waits等
buffer busy waits優化的重點是寫,即寫操作的時間更快一點或着寫操作的次數更少一點!!!