最近正在学习高级OWI,按书作者的方法做的试验(纯模仿
),欢迎大家拍砖,谢谢!
背景:为了使用高速缓冲区,要查询或修改Hash chain的进程必须获取管理相应Chain的cache buffers chains锁存器,
在获取cache buffers chains锁存器过程中如果发生争用,则等待latch:cache buffers chains事件。
测试方案:
SQL> create table cbc_test(id number,name char(100));
Table created
SQL> insert into cbc_test(id ,name) select rownum, object_name from dba_objects;
48315 rows inserted
SQL> commit;
Commit complete
创建索引
SQL> create index cbc_test_idx on cbc_test(id);
Index created
-扫描表cbc_test的Procedure
SQL> create or replace procedure cbc_do_select (p_from in number, p_to in number) is
2 begin
3 --反复、集中扫描特定块
4 for idx in 1 .. 50000 loop
5 for x in (select id from cbc_test
6 where id between p_from and p_to) loop
7 null;
8 end loop;
9 end loop;
10 end;
11 /
Procedure created
30个会话同时执行读取工作
SQL> var job_no number;
SQL> begin
2 for idx in 1..30 loop
3 dbms_job.submit(job=>:job_no,what=>'cbc_do_select(1000,1010);',interval=> 'SYSDATE+1/14400');
4 commit;
5 end loop;
6 end;
7 /
PL/SQL procedure successfully completed
job_no
---------
855
查看等待事件
SQL> Select count(*), event
2 from v$session_wait
3 where event not in ('smon timer', 'pmon timer', 'rdbms ipc message',
4 'SQL*Net message from client')
5 group by event
6 order by 1 desc;
COUNT(*) EVENT
---------- ----------------------------------------------------------------
9 latch: cache buffers chains
1 Queue Monitor Wait
1 latch: library cache
1 wakeup time manager
1 job scheduler coordinator slave wait
查看锁存器使用情况
SQL> select *
2 from (select addr, child#, gets, sleeps
3 from v$latch_children
4 where name = 'cache buffers chains'
5 order by sleeps desc)
6 where rownum <= 20
7 /
ADDR CHILD# GETS SLEEPS
-------- ---------- ---------- ----------
6C7AB504 612 15891126 4826
6C77F28C 1 641 0
6C77F3B4 2 473 0
6C77F4DC 3 700 0
6C77F604 4 1827 0
6C77F72C 5 521 0
6C77F854 6 1825 0
6C77F97C 7 250 0
6C77FAA4 8 408 0
6C77FBCC 9 382 0
6C77FCF4 10 1245 0
6C77FE1C 11 476 0
6C77FF44 12 466 0
6C78006C 13 685 0
6C780194 14 772 0
6C7802BC 15 1775 0
6C7803E4 16 506 0
6C78050C 17 271 0
6C780634 18 628 0
6C78075C 19 722 0
20 rows selected
从以上结果看 child# 612锁存器使用比较高,发生了锁存器争用。
利用X$BH视图可以确认哪些块是Hot Block
SQL> select hladdr,
2 obj,
3 (select object_name
4 from dba_objects
5 where (data_object_id is null and object_id = x.obj)
6 or data_object_id = x.obj
7 and rownum = 1) as object_name,
8 dbarfil,
9 dbablk,
10 tch
11 from x$bh x
12 where hladdr in ('6C7AB504')
13 order by hladdr, obj;
HLADDR OBJ OBJECT_NAME DBARFIL DBABLK TCH
-------- ---------- -------------- ---------- ---------- ----------
6C7AB504 2 ICOL$ 1 6120 4
6C7AB504 72 IDL_UB1$ 1 14312 1
6C7AB504 176 SNAP$ 1 1298 3
6C7AB504 65735 CBC_TEST_IDX 2 1101 142
在X$BH视图中,TCH(Touch Count)高的块为标准筛选Hot Block。在CBC_TEST_IDX
索引的 1101块上发生了争用。
解决方案:1 赋予较高的pctfree值或使用小块,减少块争用。
2 使用partitioning方法尽量将行物理地插入到另外的块。
3 只对有问题的块的行删除后再执行插入工作,只对表可行。
),欢迎大家拍砖,谢谢!背景:为了使用高速缓冲区,要查询或修改Hash chain的进程必须获取管理相应Chain的cache buffers chains锁存器,
在获取cache buffers chains锁存器过程中如果发生争用,则等待latch:cache buffers chains事件。
测试方案:
SQL> create table cbc_test(id number,name char(100));
Table created
SQL> insert into cbc_test(id ,name) select rownum, object_name from dba_objects;
48315 rows inserted
SQL> commit;
Commit complete
创建索引
SQL> create index cbc_test_idx on cbc_test(id);
Index created
-扫描表cbc_test的Procedure
SQL> create or replace procedure cbc_do_select (p_from in number, p_to in number) is
2 begin
3 --反复、集中扫描特定块
4 for idx in 1 .. 50000 loop
5 for x in (select id from cbc_test
6 where id between p_from and p_to) loop
7 null;
8 end loop;
9 end loop;
10 end;
11 /
Procedure created
30个会话同时执行读取工作
SQL> var job_no number;
SQL> begin
2 for idx in 1..30 loop
3 dbms_job.submit(job=>:job_no,what=>'cbc_do_select(1000,1010);',interval=> 'SYSDATE+1/14400');
4 commit;
5 end loop;
6 end;
7 /
PL/SQL procedure successfully completed
job_no
---------
855
查看等待事件
SQL> Select count(*), event
2 from v$session_wait
3 where event not in ('smon timer', 'pmon timer', 'rdbms ipc message',
4 'SQL*Net message from client')
5 group by event
6 order by 1 desc;
COUNT(*) EVENT
---------- ----------------------------------------------------------------
9 latch: cache buffers chains
1 Queue Monitor Wait
1 latch: library cache
1 wakeup time manager
1 job scheduler coordinator slave wait
查看锁存器使用情况
SQL> select *
2 from (select addr, child#, gets, sleeps
3 from v$latch_children
4 where name = 'cache buffers chains'
5 order by sleeps desc)
6 where rownum <= 20
7 /
ADDR CHILD# GETS SLEEPS
-------- ---------- ---------- ----------
6C7AB504 612 15891126 4826
6C77F28C 1 641 0
6C77F3B4 2 473 0
6C77F4DC 3 700 0
6C77F604 4 1827 0
6C77F72C 5 521 0
6C77F854 6 1825 0
6C77F97C 7 250 0
6C77FAA4 8 408 0
6C77FBCC 9 382 0
6C77FCF4 10 1245 0
6C77FE1C 11 476 0
6C77FF44 12 466 0
6C78006C 13 685 0
6C780194 14 772 0
6C7802BC 15 1775 0
6C7803E4 16 506 0
6C78050C 17 271 0
6C780634 18 628 0
6C78075C 19 722 0
20 rows selected
从以上结果看 child# 612锁存器使用比较高,发生了锁存器争用。
利用X$BH视图可以确认哪些块是Hot Block
SQL> select hladdr,
2 obj,
3 (select object_name
4 from dba_objects
5 where (data_object_id is null and object_id = x.obj)
6 or data_object_id = x.obj
7 and rownum = 1) as object_name,
8 dbarfil,
9 dbablk,
10 tch
11 from x$bh x
12 where hladdr in ('6C7AB504')
13 order by hladdr, obj;
HLADDR OBJ OBJECT_NAME DBARFIL DBABLK TCH
-------- ---------- -------------- ---------- ---------- ----------
6C7AB504 2 ICOL$ 1 6120 4
6C7AB504 72 IDL_UB1$ 1 14312 1
6C7AB504 176 SNAP$ 1 1298 3
6C7AB504 65735 CBC_TEST_IDX 2 1101 142
在X$BH视图中,TCH(Touch Count)高的块为标准筛选Hot Block。在CBC_TEST_IDX
索引的 1101块上发生了争用。
解决方案:1 赋予较高的pctfree值或使用小块,减少块争用。
2 使用partitioning方法尽量将行物理地插入到另外的块。
3 只对有问题的块的行删除后再执行插入工作,只对表可行。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23203681/viewspace-701253/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/23203681/viewspace-701253/
本文通过创建大量并发读取任务,模拟了数据库中缓存缓冲区链锁存器的争用情况,并分析了热点块及其解决方案。
1216

被折叠的 条评论
为什么被折叠?



