1. 背景

cbc latch的竞争,读取模式下各个版本可能是不同的。

比如在版本11.2.0.4.0是模拟不出读取模式下latch: cache buffers chains,这里原因不做探讨。

2. 过程

关于cbc latch,我们知道逻辑读下,通过全表扫描或者rowid去读取块,用的是独占的cbc latch模式。

2.1 热块竞争

热块竞争下的cbc。

2.1.1 版本11.2.0.1.0

SYS@zkm> create table zkm.test as select rownum id from dual connect by rownum<=10;

Table created.

SYS@zkm> select dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block#,rowid from zkm.test where rownum=1;

     FILE#     BLOCK# ROWID
---------- ---------- ------------------
4 131 AAAEQGAAEAAAACDAAA

2.1.1.1 session 1(sid:34)

SYS@zkm> select sid from v$mystat where rownum=1;

       SID
----------
34 SYS@zkm> declare
2 r int;
3 begin
4 for i in 1..1000000000 loop
5 select count(*) into r from zkm.test where rowid='AAAEQGAAEAAAACDAAA';
6 end loop;
7 end;
8 /
---等待

2.1.1.2 session 2(sid:35)

SYS@zkm> select sid from v$mystat where rownum=1;

       SID
----------
35 SYS@zkm> declare
2 r int;
3 begin
4 for i in 1..1000000000 loop
5 select count(*) into r from zkm.test where rowid='AAAEQGAAEAAAACDAAA';
6 end loop;
7 end;
8 /
---等待

2.1.1.3 session 3

查看等待事件。

下边结果是最终执行完后查询信息。

SYS@zkm> select sid,event,TOTAL_WAITS from v$session_event where sid in (34,35);

       SID EVENT                                                            TOTAL_WAITS
---------- ---------------------------------------------------------------- -----------
34 Disk file operations I/O 1
34 latch: cache buffers chains 176
34 cursor: pin S 1497
34 SQL*Net message to client 7
34 SQL*Net message from client 6
35 Disk file operations I/O 1
35 latch: cache buffers chains 236
35 cursor: pin S 1453
35 SQL*Net message to client 7
35 SQL*Net message from client 6 10 rows selected.

其中,“latch: cache buffers chains”中sid34和sid35各发生了176次和236次。

2.1.2 版本11.2.0.4.0

步骤类似2.1,省略其中2.1.1.1-2.1.1.2。

2.1.2.1 session 3

SYS@zkm> select sid,event,TOTAL_WAITS from v$session_event where sid in (35,28);

       SID EVENT                                                            TOTAL_WAITS
---------- ---------------------------------------------------------------- -----------
28 Disk file operations I/O 1
28 cursor: pin S 5225
28 latch: shared pool 6
28 SQL*Net message to client 7
28 SQL*Net message from client 6
35 Disk file operations I/O 2
35 db file sequential read 7
35 cursor: pin S 5235
35 latch: shared pool 4
35 SQL*Net message to client 7
35 SQL*Net message from client 6 11 rows selected.

其中,“latch: cache buffers chains”一次都没有出现。

2.1.3 版本10.2.0.1.0

步骤类似2.1,省略其中2.1.1.1-2.1.1.2。

2.1.3.1 session 3

SQL> select sid,event,TOTAL_WAITS from v$session_event where sid in (147,148);

       SID EVENT                                                            TOTAL_WAITS
---------- ---------------------------------------------------------------- -----------
147 latch: cache buffers chains 762
147 latch: library cache 551
147 latch: library cache pin 423
147 SQL*Net message to client 9
147 SQL*Net message from client 8
148 latch: cache buffers chains 706
148 latch: library cache 624
148 latch: library cache pin 393
148 SQL*Net message to client 9
148 SQL*Net message from client 8 10 rows selected.

出现“latch: cache buffers chains”远远多于在11.2.0.1.0上的次数。并且时间上运行了3个小时(我还是ssd的盘),前面的两个版本都没那么久。

2.2热链竞争

热链竞争下的cbc。

2.2.1 版本11.2.0.1.0


SYS@zkm> set linesize 500
SYS@zkm> select dbms_rowid.rowid_relative_fno(rowid) file#,dbms_rowid.rowid_block_number(rowid) block#,rowid from zkm.test where id=1; FILE# BLOCK# ROWID
---------- ---------- ------------------
4 131 AAAEQGAAEAAAACDAAA SYS@zkm> select distinct hladdr from x$bh where file#=4 and dbablk=131; HLADDR
----------------
00000003E4734398 SYS@zkm> select a.file#,a.dbablk,b.owner,b.object_name from x$bh a,dba_objects b where a.hladdr='00000003E4734398' and a.obj=b.data_object_id; FILE# DBABLK OWNER OBJECT_NAME
---------- ---------- ------------------------------ --------------------------------------------------------------------------------------------------------------------------------
1 3160 SYS I_MON_MODS$_OBJ
2 15242 SYS I_WRI$_OPTSTAT_HH_OBJ_ICOL_ST
4 131 ZKM TEST
4 4469 ZKM PIS SYS@zkm> select object_id,data_object_id from dba_objects where owner='ZKM' and object_name='PIS'; OBJECT_ID DATA_OBJECT_ID
---------- --------------
17419 17419 SYS@zkm> select dbms_rowid.rowid_create(1,17419,4,4469,0) from dual; DBMS_ROWID.ROWID_C
------------------
AAAEQLAAEAAABF1AAA

其中,00000003E4734398是cbc latch的地址。找出这个地址后,在找出这个地址下保护的其他对象。

这里我们挑zkm.pis这张表(文件4,块号4469),因为SYS.I_MON_MODS$_OBJ和SYS.I_WRI$_OPTSTAT_HH_OBJ_ICOL_ST没办法查询,我新构造了zkm.pis这张表直到出现这个00000003E4734398也有zkm.pis的结果。

2.2.1.1 session 1(sid:19)

SYS@zkm> select sid from v$mystat where rownum=1;

       SID
----------
19 SYS@zkm> declare
2 r int;
3 begin
4 for i in 1..1000000000 loop
5 select id into r from zkm.test where rowid='AAAEQGAAEAAAACDAAA';
6 end loop;
7 end;
8 /
---等待

2.2.1.2 session 2(sid:31)

SYS@zkm> select sid from v$mystat where rownum=1;

       SID
----------
31 SYS@zkm> declare
2 r int;
3 begin
4 for i in 1..1000000000 loop
5 select count(*) into r from zkm.pis where rowid='AAAEQLAAEAAABF1AAA';
6 end loop;
7 end;
8 /
---等待

2.2.1.3 session 3

SYS@zkm> select sid,event,state,p1raw,p2raw from v$session where sid in (19,31) order by 2;

       SID EVENT                                                            STATE               P1RAW            P2RAW
---------- ---------------------------------------------------------------- ------------------- ---------------- ----------------
31 latch: cache buffers chains WAITED SHORT TIME 00000003E4734398 0000000000000096
19 latch: cache buffers chains WAITED SHORT TIME 00000003E4734398 0000000000000096

session 1和session 2跑期间可以刷出以上结果,其中,p1raw正好是latch的地址。

最后session 1和session 2,通过视图v$session_event查看等待事件的统计如下:

SYS@zkm> select sid,event,TOTAL_WAITS from v$session_event where sid in (19,31);

       SID EVENT                                                            TOTAL_WAITS
---------- ---------------------------------------------------------------- -----------
19 Disk file operations I/O 1
19 latch: cache buffers chains 213
19 SQL*Net message to client 7
19 SQL*Net message from client 6
31 Disk file operations I/O 1
31 latch: cache buffers chains 279
31 SQL*Net message to client 7
31 SQL*Net message from client 6 8 rows selected.

2.2.2 版本11.2.0.4.0

步骤类似2.2.1.1-2.2.1.2,省略。

2.2.2.1 session 3

最后session 1和session 2,通过视图v$session_event查看等待事件的统计如下:

SYS@zkm> select sid,event,TOTAL_WAITS from v$session_event where sid in (29,24);

       SID EVENT                                                            TOTAL_WAITS
---------- ---------------------------------------------------------------- -----------
24 Disk file operations I/O 1
24 latch: shared pool 7
24 SQL*Net message to client 8
24 SQL*Net message from client 7
24 SQL*Net break/reset to client 2
29 Disk file operations I/O 1
29 latch: shared pool 9
29 SQL*Net message to client 7
29 SQL*Net message from client 6 9 rows selected.

2.2.3 版本10.2.0.1.0

步骤类似2.2.1.1-2.2.1.2,省略。

2.2.3.1 session 3

SQL> select sid,event,state,p1raw,p2raw from v$session where sid in (148,158) order by 2;

       SID EVENT                                                            STATE               P1RAW            P2RAW
---------- ---------------------------------------------------------------- ------------------- ---------------- ----------------
158 latch: cache buffers chains WAITED KNOWN TIME 0000000082FA5158 000000000000007A
148 latch: cache buffers chains WAITED KNOWN TIME 0000000082FA5158 000000000000007A

session 1和session 2跑期间可以刷出以上结果,其中,p1raw正好是latch的地址。

最后session 1和session 2,通过视图v$session_event查看等待事件的统计如下:

SQL> select sid,event,TOTAL_WAITS from v$session_event where sid in (148,158);

       SID EVENT                                                            TOTAL_WAITS
---------- ---------------------------------------------------------------- -----------
148 latch: cache buffers chains 773
148 latch: library cache 794
148 latch: library cache pin 426
148 SQL*Net message to client 9
148 SQL*Net message from client 8
158 latch: cache buffers chains 673
158 latch: library cache 950
158 latch: library cache pin 413
158 SQL*Net message to client 9
158 SQL*Net message from client 8 10 rows selected.

现象和热块竞争时候是一样的。11.2.0.4.0一样模拟不出来“latch: cache buffers chains”。

而且在10.2.0.1.0和11.2.0.1.0中,10g的这个事件次数远多于11g的。

3 热块/链竞争的解决

热链竞争:可以通过修改隐藏参数_db_block_hash_buckets或者_db_block_hash_latches值,它们分别控制HASH Bucket的数量和CBC Latch的数量。修改后,BH和HASH Bucket的对应关系就会被重新计算。原本在同一链表中的BH,重新计算后很可能就不在同一链表中了。不过,不是实在无计可施的情况,不推荐修改这两个参数。

热块竞争:大多是执行计划不合理或者sql有问题导致的。比如等值查询条件表,表又比较大,可以考虑创建唯一索引,因为索引的根块枝块页块表块都是使用共享模式的CBC Latch,不用担心引起争用。

05-11 18:20