ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Latch free等待事件三

Latch free等待事件三

原创 Linux操作系统 作者:chinagjj2008 时间:2009-04-14 09:00:48 0 删除 编辑

Oracle 10g 操作系统solaris

Db_cache_size

32m

64m

128m

256m

512m

1024m

2048m

_ksmg_granule_size

4m

4m

4m

4m

4m

16m

16m

_db_block_buffers

3976

7952

15904

31808

63616

127232

254464

_db_block_hash_buckets

8192

16384

32768

65536

131072

262144

524288

_db_block_hash_latches

1024

1024

1024

1024

1024

1024

2048

Oracle9i 操作系统solaris

Db_cache_size

32m

64m

128m

256m

512m

1024m

2048m

_ksmg_granule_size

4m

4m

16m

16m

16m

16m

16m

_db_block_buffers

4000

8000

16016

32032

64064

128128

256256

_db_block_hash_buckets

8009

16001

32051

64067

128147

256279

512521

_db_block_hash_latches

1024

1024

1024

1024

1024

1024

2048

Oracle8i 操作系统solaris

Db_block_buffers

4000

8000

16016

32032

64064

128128

192192

_db_block_hash_buckets

8000

16000

32032

64064

128128

256256

384384

_db_block_hash_latches

1024

1024

1024

1024

1024

1024

2048

Cache buffers chains latch争用原因一 ―― 低效的sql语句

低效的sql语句是导致cache buffers chains latch争用的主要原因。在高并发系统中, atch free时间可能因此非常明显。典型的情况是,应用程序开启多个并发会话执行相同的低效sql,并且访问同样的数据集。

你应该时刻铭记下面三点:

n 每次逻辑读都需要请求一次latch

n 只有获得某个latch之后才会停止对该latch的不断请求。

n 在某个时刻,只有一个进程可以获得cache buffers chains latch,而该latch可能用于保护很多的数据块,其中的某些块可能正在被其他进程请求(当然,前面也已经提过,oracle9i允许只读性质的cache buffers chains latch共享)。

一般而言,较少的逻辑读意味着较少的latch请求,也就意味着较少的latch争用和更好的系统性能。所以,你应该找出导致cache buffers chains latch争用的低效sql语句,优化这些语句,尽量降低其逻辑读。那些buffers_get/executions比值较大的sql可能就是你需要调整的语句。

1:某些dba可能通过修改隐含参数_db_blocks_hash_latches来增加系统中cache buffers chains latch的个数,而不是首先去优化低效的sql语句,这是不正确的,增加latch能暂时降低对latch的争用,但这是治标不治本的方法。

2:在sun solareis平台上,我们将一个数据库从oracle8.1.7.4升级到oracle9.2.05之后,发现了大量的cache buffers chains latch争用,新的优化器为应用程序生成了低效的执行计划。一些隐藏的优化器相关的参数,在oracle8i中是无效的,但在oracle9i中有效。在重设这些参数后,问题得意解决。如果你遭遇到同样的情况,建议请求oracle的技术支持。

Cache buffers chains latch争用原因二 ―― 热点块

热点块是导致cache buffers chains latch争用的另外一个主要原因。当多个进程重复访问一个或多个由同一个cache buffers chains latch保护的块时会导致该问题。这通常是应用程序引起的。在这种情况下,增加cache buffers chains latch的个数对热点块导致的争用没有什么作用。因为数据块分布在哪个hash buckethash chain上是由块地址(dba:data block address)hash bucket的个数决定的,和hash latch的个数没有关系。只要块地址和hash bucket数没有改变,这些热点块还是会分布在原来的hash buckethash chain上,还是由原来的hash latch保护,那么就还会对这些hash latch产生争用。除非系统中latch数目显著的增加(这样每个latch管理的hash bucket就会很少,甚至一个latch管理一个hash bucket,这样原来的热点块可能就会有其他的几个latch来管理,而不再需要争用原来的那个latch)。

解决这样的cache buffers chains latch争用,最好的方法是找出热点块。通过latch free等待事件的p1raw参数可以知道是否是因为热点块导致了latch争用。(在oracle10g中,cache buffers chains latch的相关等待事件不再是latch free,而是cache buffers chains)。P1raw参数是latch的地址。如果多个会话都在等待同一个latch地址,那么恭喜你遇到热点块问题了。下面的例子中,可以发现由地址为00000400837d7800 00000400837de400latch保护的hash chain中存在热点块(多个会话都在等待这两个地址的latch)。

Select sid, p1raw, p2, p3, seconds_in_wait, wait_time, state
from v$session_wait
where event =’latch free’
order by p2, p1raw;

sid p1raw p2 p3 seconds_in_wait wait_time state
---- ---------------- --- --- --------------- ---------- ------------------
38 00000400837d7800 98 1 1 2 waited known time
42 00000400837d7800 98 1 1 2 waited known time
44 00000400837d7800 98 3 1 4 waited known time
58 00000400837d7800 98 2 1 10 waited known time
85 00000400837d7800 98 3 1 12 waited known time
214 00000400837d7800 98 1 1 2 waited known time
186 00000400837d7800 98 3 1 14 waited known time
149 00000400837d7800 98 2 1 3 waited known time
132 00000400837d7800 98 2 1 2 waited known time
101 00000400837d7800 98 3 1 4 waited known time
222 00000400837d7800 98 3 1 12 waited known time
229 00000400837d7800 98 3 1 4 waited known time
230 00000400837d7800 98 3 1 11 waited known time
232 00000400837d7800 98 1 1 20 waited known time
257 00000400837d7800 98 3 1 16 waited known time
263 00000400837d7800 98 3 1 5 waited known time
117 00000400837d7800 98 4 1 4 waited known time
102 00000400837d7800 98 3 1 12 waited known time
47 00000400837d7800 98 3 1 11 waited known time
49 00000400837d7800 98 1 1 2 waited known time
99 00000400837d9300 98 1 1 32 waited known time
51 00000400837dd200 98 1 1 1 waited known time
43 00000400837de400 98 1 1 2 waited known time
130 00000400837de400 98 1 1 10 waited known time
89 00000400837de400 98 1 1 2 waited known time
62 00000400837de400 98 0 1 -1 waited known time
150 00000400837de400 98 1 1 9 waited known time
195 00000400837de400 98 1 1 3 waited known time
67 00000400837de400 98 1 1 2 waited known time

下一步,就是找出这些热点块以及造成latch争用的sql语句。这是因为cache buffers chains latch通常保护很多个块,这些热点块可能属于这些sql中使用的某个表。从oracle8i开始,你可以通过接触点计数(tchtouch count)来发现热点块。一般来说,热点块的tch会比较高。但是要记住,当块从lru列表的冷端移动到热端后,tch会被清0。所以, tch0的块不一定就不是热点块。

-- 这里使用了前面例子中的p1raw (00000400837d7800).
Select a.hladdr, a.file#, a.dbablk, a.tch, a.obj, b.object_name
from x$bh a, dba_objects b
where (a.obj = b.object_id or a.obj = b.data_object_id)
and a.hladdr = ’00000400837d7800’
union
select hladdr, file#, dbablk, tch, obj, null
from x$bh
where obj in (select obj from x$bh where hladdr = ’00000400837d7800’
minus
select object_id from dba_objects
minus
select data_object_id from dba_objects)
and hladdr = ’00000400837d7800’
order by 4;

hladdr file# dbablk tch obj object_name
---------------- ----- ------- ---- ----------- --------------------
00000400837d7800 16 105132 0 19139 route_history
00000400837d7800 16 106156 0 19163 telco_orders
00000400837d7800 26 98877 0 23346 t1
00000400837d7800 16 61100 0 19163 telco_orders
00000400837d7800 16 26284 0 19059 fp_eq_tasks
00000400837d7800 7 144470 0 18892 report_process_queue
00000400837d7800 8 145781 0 18854 pa_equipment_union
00000400837d7800 249 244085 0 4294967295
00000400837d7800 7 31823 1 18719 candidate_events
00000400837d7800 13 100154 1 19251 event
00000400837d7800 7 25679 1 18730 candidate_zoning
00000400837d7800 7 8271 1 18719 candidate_events
00000400837d7800 7 32847 2 18719 candidate_events
00000400837d7800 8 49518 2 18719 candidate_events
00000400837d7800 7 85071 2 18719 candidate_events
00000400837d7800 275 76948 2 4294967295
00000400837d7800 7 41039 3 18719 candidate_events
00000400837d7800 7 37967 4 18719 candidate_events
00000400837d7800 8 67950 4 18719 candidate_events
00000400837d7800 7 33871 7 18719 candidate_events
00000400837d7800 7 59471 7 18719 candidate_events
00000400837d7800 8 8558 24 18719 candidate_events

如前所述,热点块通常是应用程序导致的。找出这些程序,检查他们为什么重复访问相同的块,并且做出相应的调整。

另外一个解决办法,就是尽量将热点块分配到不同的hash chain链表,由不同的cache buffers chains latch来保护。这可以通过调整热点块中的行数据分布到不同的块中来实现。新的块有不同的块地址,这样原来在同一个hash chain上的数据就可能会分布到其他不同的hash chain上。改变块中行数据的分布有很多方法,包括:

n 通过rowid删除并且重新插入某些行。

n 将表exp出来,加大 pctfree,然后再imp表。这样会使每个块中的数据减少,使数据分布到更多的块上。同时,也会导致占用更多的空间,全表扫描的性能也会受到影响。

n

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/464838/viewspace-588909/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-01-14

  • 博文量
    32
  • 访问量
    60514