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 bucket和hash chain上是由块地址(dba:data block address)和hash bucket的个数决定的,和hash latch的个数没有关系。只要块地址和hash bucket数没有改变,这些热点块还是会分布在原来的hash bucket和hash 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 和00000400837de400的latch保护的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开始,你可以通过接触点计数(tch:touch count)来发现热点块。一般来说,热点块的tch会比较高。但是要记住,当块从lru列表的冷端移动到热端后,tch会被清0。所以, tch为0的块不一定就不是热点块。
如前所述,热点块通常是应用程序导致的。找出这些程序,检查他们为什么重复访问相同的块,并且做出相应的调整。
另外一个解决办法,就是尽量将热点块分配到不同的hash chain链表,由不同的cache buffers chains latch来保护。这可以通过调整热点块中的行数据分布到不同的块中来实现。新的块有不同的块地址,这样原来在同一个hash chain上的数据就可能会分布到其他不同的hash chain上。改变块中行数据的分布有很多方法,包括:
n 通过rowid删除并且重新插入某些行。
n 将表exp出来,加大 pctfree,然后再imp表。这样会使每个块中的数据减少,使数据分布到更多的块上。同时,也会导致占用更多的空间,全表扫描的性能也会受到影响。
n[@more@]来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/18921899/viewspace-1017389/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/18921899/viewspace-1017389/