Latch和等待

Latch是Oracle为了保护内存结构而发明的一种资源。就如同在SGA中,各种数据被反复从磁盘读取到内存,又重新写回到磁盘上,如果有并发用户做相同的事情,Oracle必须有一种机制,来保证数据在读取的时候,只能由一个会话来完成,这种保护机制就用到了Latch。Latch是一种轻量级锁,它不会引起阻塞,只会导致等待。导致latch争用而等待的原因很多,内存中很多资源都可能存在争用。有两类常见的Latch争用,他们都会导致数据库性能下降。

1. 共享池中的latch争用:共享池中如果存在大量的sql被反复分析,会造成很大的latch争用和长时间的等待,最常见的是没有绑定变量。 可以通过select * from v$latchname where name like 'library cache%'来查看共享池中常见的latch。在分析系统性能时,如果看到有library cache这样的latch争用,就可以断定共享池出现问题,这种问题基本上由sql语句导致,如没有绑定变量或一些存储过程被反复执行。

2. 数据缓冲池中的latch争用。当很多用户一起去访问某几个数据块时,就会导致一些latch争用,最常见的是:buffer busy waits和cache buffer chain,这两个latch争用发生在访问数据块的不同时刻。

cache buffer chain:当一个会话需要去访问一个内存块时,它首先要去一个像链表一样的结构中去搜寻这个数据块是否在内存中,当会话访问这个链表时就需要获得一个latch,如果获取失败,就会产生cache buffer chain等待,导致产生这个等待的原因是访问相同数据块的会话太多或者这个链表太长(如果读到内存中的数据块太多,需要管理数据块的hash列表就会很长,这样会话扫描列表的时间就会增加,持有cache buffer chain Latch的时间就会变长)

buffer busy waits: 当一个会话要访问一个数据块,而这个数据块正在被另外的一个用户从磁盘读取到内存中或者这个数据块正在被另一个会话修改时,当前的会话就要等待,就会产生buffer busy waits等待。产生这些Latch争用的直接原因是太多会话去访问相同的数据块导致热块(访问频率非常高的数据块)问题,造成热块的原因可能是数据库设置导致或者是重复执行的sql频繁访问一些相同的数据块。

热块有以下几种热块类型,他们产生的原因不同,处理方式都是不同的:

  • 表数据块:在OLTP系统中,对于一些小表,会出现某些数据块被频繁查询或修改的操作,这些数据块就成为热块,导致内存中latch争用,出现这样情况,如果表不太大,可以将表数据分布在更多的数据块上,但是这样也会使读取性能降低,会读取更多的数据块。
  • 索引数据块,通常发生在RAC环境,当许多用户在RAC的不同实例中来向表插入主键时,就会出现相同的索引数据块在不同实例内存中被调用,形成一种数据块的争用,这种热块类型使用反向索引可以缓解latch争用,原来主键的索引123,124,125使用反向索引后就是321,421,521.
  • 索引根数据块,当B-tree索引的根,枝数据都集中在几个数据块上时,可能发生热块,可以考虑对索引做分区,使根,枝数据分布到不同的数据段(分区)上,减少数据块并行访问的密度。
  • 文件头数据块
原文地址:https://www.cnblogs.com/PerOpt/p/3733241.html