热点块引发的Cache buffer Chains latch:
SQL语句即便适当进行了调优,有时也无法解决cache buffers cahins latch,若在编写SQL语句时的SQL工作方式,
只是持续扫描少数特定块,则在多个会话同时执行此SQL语句时,就会发生Hot Block引起的cache buffers chains latch争用。
测试方案如下:
1) 创建与测试相同的表和索引。
2) 即便有效扫描索引,多个会话也会反复扫描相同的块,因此发生Hot Block引起的cache buffers chains latch争用。
SQL> create or replace Procedure cbc_do_select(p_from in NUMBER,
2 p_to IN NUMBER) is
3 begin
4 -- 反复,集中扫描特定块
5 for idx in 1 .. 3000 loop
6 for x in (select id from cbc_test where id between p_from and p_to) loop
7 null;
8 end loop;
9 end loop;
10 end;
11 /
Procedure created
---同时执行20个读取工作
var job_no number;
begin
for idx in 1 .. 20 loop
dbms_job.submit(:job_no,'cbc_do_select(1000,1010);');
commit;
end loop;
end;
select sid,event,p1,p2,p3,p1raw from v$session where event='latch: cache buffers chains'
p1 p2 p3 p1raw
1 56 latch: cache buffers chains 758400976 150 0 000000002D3447D0
引发问题的SQL语句时select * from cbc_test where id between p_from and p_to,此SQL语句本身已经是优化的状态,因为通过cbc_test_idx索引,
只扫描必要范围并获取相应值。通过v$latch_children视图确认特定子latch使用是否偏多,从此可以间接判断是否是Hot Block引起的锁存器争用。
或者也可以捕捉v$session_wait 视图的PARAW列值,将反复被观察的值为锁存器地址利用。
SQL> SQL> SQL> SQL> select *
from (select addr, child#, gets, sleeps
from v$latch_children
where name = 'cache buffers chains'
order by sleeps desc)
where rownum <= 20 2 3 4 5 6 ;
ADDR CHILD# GETS SLEEPS
-------- ---------- ---------- ----------
2D3447D0 632 22491 74
2D351280 908 1843173 15
2D341E34 575 21975 6
2D33F498 518 15291 3
2D34FA08 874 4050 1
2D331E28 226 16410 1
2D33296C 241 12922 1
2D33A2D4 407 12470 1
2D346438 670 2590 1
2D3567B0 1024 2836 0
2D3560D8 1014 2830 0
ADDR CHILD# GETS SLEEPS
-------- ---------- ---------- ----------
2D35605C 1013 3634 0
2D355EE0 1012 1187 0
2D355E64 1011 1806 0
2D355DE8 1010 1455 0
2D355D6C 1009 2011 0
2D355BF0 1008 2615 0
2D355B74 1007 3166 0
2D355AF8 1006 8798 0
2D355A7C 1005 2829 0
已选择20行。
已选择20行。
SLEEPS :
SLEEPS NUMBER Number of times a willing-to-wait latch request resulted in a session sleeping while waiting for the latch
从结果来看child# 632发生了锁存器争用,利用x$bh视图可以确认哪些块是Hot Block
SQL> select hladdr,
obj,
(select object_name
from dba_objects
where (data_object_id is null and object_id = x.obj)
or data_object_id = x.obj
and rownum = 1) as object_name,
dbarfil,
dbablk,
tch
from x$bh x
where hladdr in ('2D3447D0','2D341E34','2D351280')
order by hladdr, obj
2 3 4 5 6 7 8 9 10 11 12 13 14 ;
HLADDR OBJ OBJECT_NAME DBARFIL DBABLK TCH
-------- ---------- -------------------- ---------- ---------- ----------
2D341E34 37 I_OBJ2 1 32383 9
2D341E34 288 I_JOB_JOB 1 2017 43
2D341E34 288 I_JOB_JOB 1 2017 1
2D341E34 288 I_JOB_JOB 1 2017 1
2D341E34 288 I_JOB_JOB 1 2017 1
2D341E34 288 I_JOB_JOB 1 2017 1
2D341E34 444 STATS_TARGET$ 2 852 0
2D3447D0 37 I_OBJ2 1 32375 9
2D3447D0 236 I_IDL_CHAR1 1 63207 0
2D3447D0 267 SMON_SCN_TO_TIME_AUX 2 61809 0
2D3447D0 287 JOB$ 1 2009 1
HLADDR OBJ OBJECT_NAME DBARFIL DBABLK TCH
-------- ---------- -------------------- ---------- ---------- ----------
2D3447D0 287 JOB$ 1 2009 2
2D3447D0 287 JOB$ 1 2009 2
2D3447D0 287 JOB$ 1 2009 22
2D3447D0 287 JOB$ 1 2009 1
2D351280 2 ICOL$ 1 83980 25
2D351280 37 I_OBJ2 1 44472 10
2D351280 40 I_OBJ5 1 14339 1
2D351280 68 SYN$ 1 40600 14
2D351280 159 TRIGGER$ 1 83747 1
2D351280 6213 WRH$_SQL_PLAN 2 4265 0
2D351280 75405 WRH$_SQLSTAT_INDEX 2 4498 0
HLADDR OBJ OBJECT_NAME DBARFIL DBABLK TCH
-------- ---------- -------------------- ---------- ---------- ----------
2D351280 75500 CBC_TEST_IDX 7 291882 80
已选择23行。