ITPub博客

首页 > 数据库 > Oracle > latch与等待(1)--cache buffer yl

latch与等待(1)--cache buffer yl

Oracle 作者:liutongxuerp 时间:2014-02-25 16:33:46 0 删除 编辑

 

latch简单理解

1.1Latch可以理解为一种清量级的锁, Latch是一种快速的被获取和释放的内存锁,用于防止共享内存结构被多个用户同时访问,Latch是一种快速的被获取和释放的内存锁,用于防止共享内存结构被多个用户同时访问。他不会造成阻塞,只会造成等待。阻塞时系统设计问题,等待是资源征用问题。最常见的latch争用而等待的----共享池中latch争用,数据缓冲池latch的争用。

1.2、对于Latch的请求,不用排队等待资源,由于Latch的分配相当随机,所以当Latch释放后,不管哪个会话请求都可能得到它,当不能获得Latch的会话,就会在后续不断的重试(spin->sleep->spin…->get latch

在一台多CPU 的机器上,如果Latch不能立即获得,那么会话就会自旋,即在循环中反复地尝试来或得Latch。如果不这样的话,那么就会导致上下文切换(context switching),这样对资源开销更大。

 

1.3Latch请求的类型:willing-to-waitimmediate 

1.3.1 对于willing-to-wait类型的latch 

如果一个进程在第一次尝试中没有获得latch,那么它会等待并且再尝试一次,如果经过_spin_count次争夺不能获得latch, 然后该进程转入睡眠状态,睡眠醒来后,按顺序重复以前的步骤。睡眠的时间会越来越长。 

1.3.2 对于immediate类型的latch 

如果该闩不能立即得到的话,那么该进程就不会为获得该latch而等待。它将继续执行另一个操作。 

1.3.3 可以通过v$latch视图查看latch的具体信息,在v$latch中: 

(以下字段反映了Willing-to-wait类型请求) 

GETS:成功地以Willing-to-wait请求类型请求一个latch的次数。 

MISSES:初始以Willing-to-wait请求类型请求一个latch不成功的次数。 

SLEEPS:初始以Willing-to-wait请求类型请求一个latch不成功后,进程等待获取latch的次数。 

(以下字段反映了Immediate类型请求) 

IMMEDIATE_GETS:以Immediate请求类型成功地获得一个latch的次数。 IMMEDIATE_MISSES:以Immediate请求类型请求一个latch不成功的次数。 

Buffer cache介绍与latch

BUFFER CACHE相关的主要Latch有:cache buffer lru chaincache buffers chains

buffer cache就是一块含有许多数据块的内存区域,这些数据块主要都是数据文件里的数据块内容的拷贝,那么数据的查询和修改都要通过它来完成。接下来就看看访问数据的流程是怎样的

:当一个进程要访问数据时,首先要查找BUFFER CACHE看看数据是否已经存在? 
(Y) 
如果数据在BUFFER CACHE中存在,则根据数据的状态来判断是否可以直接访问还是需要构造一致性读取? 
(N) 
如果数据在BUFFER CACHE中不存在,则需要从数据文件中读取数据块到BUFFER CACHE中去。这个时候,需要查找在BUFFER CACHE中寻找足够的内存空间来读取相关的数据。

:现在BUFFER CACHE那么大,一个BUFFER一个BUFFER的扫描过去是相当的消耗资源以及查询的时间,那我们怎样才能快速地查到数据了? 可以看看下面关于BUFFER CACHE的示图:

latch与等待(1)--cache <wbr>buffer

 

2.1图中右边的有一块Buffers Memory,其中每一块小格就是一个Buffer(用来存放从数据文件中读取的数据块Block)

2.2图中左边的有许多Buffer Header用线指向Buffers Memory中的相应:Buffer 

2.3:图中左边的有许多实线箭头,这些箭头(其实就是数据结构的链表结构中的指针)将不同的Buffer Header连接成一条Hash Chain,这边也就是Cache Buffers Chain(双向链表。 

2.4:另外,还有一个Hash: Bucket,其实这只是一个逻辑上的概念,即每一个Hash Bucket都会有一条Hash Chain来将Buffer Header(按照HASH算法分类后)连接起来,并由一个Cache Buffers Chains Latch来进行管理其并发操作。

 

每当将一个Block读入到Buffer Cache的时候,首先会构造一个与之对应的Buffer Header,然后根据HASH算法 Hash Bucket MOD(Data Block Address, _DB_BLOCK_HASH_BUCKETS) ,将Buffer Header放到对应的Hash BucketCache Buffers Chain中去,并在Buffer Header中记录如下信息

1.存放该BlockBuffer Cache中实际存储地址 
2
.存放该Block的类型(data,segment header,undo header,undo Block等类型) 
3
.由于此Buffer Header 所在的Hash Chain,是通过在Buffer Header保存指向前一个Buffer Header的指针和指向后一个Buffer Header的指针方式实现,所以还存指针 

4.存储lru,lruw,ckptq等队列,一样是通过记录前后Buffer Header指针方式实现

5.当前该Buffer Header所对应的数据块的状态以及标记 

6.Buffer Header被访问的次数(touch次数
7
.正在等待该Buffer Header的进程列表(waiter list)及正在使用此Buffer Header(user list)

2.5:最后,在看看Hash Latch,即Cache Buffers Chains Latch,在Oracle 8i之前,对应每一个Hash BucketOracle使用一个独立的Latch来维护。Oracle 8i开始,Oracle增加了Hash Bucket的数量,这样每个Latch需要维护多个Bucket,由于每个Hash Bucket 上的Buffer Header数量大大减低,也使得Latch的性能反而提高。其中,BUFFER CACHEHash Bucket的个数由隐含参数_db_block_hash_buckets决定,Cache Buffers Chains Latch的个数由隐含参数_db_block_hash_latches决定。

SYS@ prod>select count(*) from x$bh; --用这句查出buffer的个数,

  COUNT(*)
----------
     13322

查询隐含参数可参考

select

  x.ksppinm  name,

  y.ksppstvl  value,

  y.ksppstdf  isdefault,

  decode(bitand(y.ksppstvf,7),1,'MODIFIED',4,'SYSTEM_MOD','FALSE')  ismod,

  decode(bitand(y.ksppstvf,2),2,'TRUE','FALSE')  isadj

from

  sys.x$ksppi x,

  sys.x$ksppcv y

where

  x.inst_id = userenv('Instance') and

  y.inst_id = userenv('Instance') and

  x.indx = y.indx and

  x.ksppinm like '%_&par%'

order by

  translate(x.ksppinm, ' _', ' ')

/

 

NAME                                     VALUE      ISDEFAULT ISMOD      ISADJ

---------------------------------------- ---------- --------- ---------- -----

_db_block_hash_buckets                   32768      TRUE      FALSE      FALSE

_db_block_hash_latches                   1024       TRUE      FALSE      FALSE

 

关于_db_block_hash_buckets参数的取值:据说在8i下,该参数缺省db_block_buffers×2;但是到了9i以后,该参数似乎取的是小于且最接近于db_block_buffers×2的素数。
ORACLE 10G11G中,默认值是大于2倍的buffer数量的最小的2的幂的值。举例如buffer数量是133222倍就是26644,那么大于26644的最小的2的幂的值是32768,也就是就会有32768hash bucket

一条hash chain上的buffer header数量,没有固定限制(CR块有限制,一条hash chain上的CR块不能超过6个)。从隐含参数_db_block_max_cr_dba中可以查到这个限制:

NAME                                     VALUE      ISDEFAULT ISMOD      ISADJ

---------------------------------------- ---------- --------- ---------- -----

_db_block_max_cr_dba                     6          TRUE      FALSE      FALSE

判断是否有过长的hash chain的语句:过长的hash chain更容易引起热链进而引起CBC LATCH  

SYS@ prod>select * from (select hladdr,count(*) from x$bh group by hladdr order by 2 desc) where rownum<5;    ----------------x$bh.hladdr表示的是hash chain latch address

HLADDR     COUNT(*)

-------- ----------

3E2A7088         26

3E27D788         25

3E2AABE8         24

3E2BD9C0         24

 

hash latch:就是latch:cache buffers chains --CBC LATCH

用于保护hash chain结构,一个CBC LATCH管理着多个hash chain

1.服务进程需要扫描hash chain上的buffer header时或者叫要读取buffer cache中数据块,
2.
服务器进程要将新读入的数据块挂载到hash chain上时

SYS@ prod>select count(*) from v$latch_children where name like '�che buffers chains%';

  COUNT(*)

----------

      1024

每个pool会有至少8“Latch:cache buffers lru chain”.

NAME                                     VALUE      ISDEFAULT ISMOD      ISADJ

---------------------------------------- ---------- --------- ---------- -----

_db_block_lru_latches                    8          TRUE      FALSE      FALSE

working setlru latch一一对应。lru latch的数量是由一个隐藏参数:_db_block_lru_latches决定的。该参数缺省值为DBWR进程的数量×8。该参数最小必须为8,如果强行设置比8小的数值,oracle将忽略你设置的值,而使用8作为该参数值。

 

<!-- 正文结束 -->

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

上一篇: 没有了~
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2009-07-08