1.串行化概述
串行化 - 数据库系统本身是一个多用户并发处理系统,在同一个时间点上,可能会有多个用户同时操作数据库, 多个用户同时在相同的物理位置上写数据时,不能发生互相覆盖的情况,这叫做串行化,串行化会降低系统的并发性,但这对于保护数据结构不被破坏来说则是必需的。在Oracle数据库中,通过闩锁(latch)和锁定(lock)来解决这两个问题。
闩锁和锁定既有相同点又有不同点。相同点在于它们都是用于实现串行化的资源。而不同点则在于闩锁(Latch)是一个低级别、轻量级的锁,获得和释放的速度很快,以类似于信号灯的方式实现。而锁定(Lock)则可能持续的时间很长,通过使用队列,按照先进先出的方式实现。也可以简单地理解为闩锁是微观领域的,而锁定则是宏观领域的。
2.latch概述
Oracle数据库使用闩锁(latch)来管理SGA内存的分配和释放.Latch是用于保护SGA区中共享数据结构的一种串行化锁定机制。Latch的实现是与操作系统相关的,尤其和一个进程是否需要等待一个latch、需要等待多长时间有关
Latch是一种能够极快地被获取和释放的锁,它通常用于保护描述buffer cache中block的数据结构。与每个latch相联系的还有一个清除过程,当持有latch的进程成为死进程时,该清除过程就会被调用。Latch还具有相关级别,用于防止死锁,一旦一个进程在某个级别上得到一个latch,它就不可能再获得等同或低于该级别的latch
Latch 不会造成阻塞,只会导致等待。 阻塞是一种系统设计上的问题,等待是一种系统资源争用的问题
总结:
latch的目的:1.保证资源的串行访问: 保护SGA的资源访问,保护内存的分配 2.保证执行的串行化:保护关键资源的串行执行,防止内存结构的损坏
3.何时会出现latch
资源的请求和分配:
共享池:比如sql解析,sql重用
数据缓冲池: 比如说数据访问,数据写入磁盘,数据读入内存,修改数据块,数据段扩展
4.Oracle中有哪些latch?
select name from V$LATCHNAME where ROWNUM<10; name PC and Classifier lists for WLM PC and Service Request Count lists for WLM post/wait queue hot latch diags test excl. non-parent l0 test excl. parent l0 test excl. parent2 l0 test shared non-parent l0 test excl. non-parent lmax
select count(*) from v$latchname; --->993种
5.Latch工作机制
当在多个cpu中,并发访问SGA中的某一个latch资源时,当一个进程A获取了一个latch,另外一个进程B只有当进程A释放掉,它才能获取
6.Latch获取的方式
1.wait方式 -- 如果无法获取请求的latch,则:
- spin
- 当一个会话无法获取需要的latch时,会继续使用cpu(cpu空转),达到一个间隔后,再次尝试申请latch,直到达到最大的重试次数
- sleep
- 当一个会话无法获取需要的latch时,会等待一段时间(sleep),达到一个间隔后,再次尝试申请latch,如果反复,直到达到最大的重试次数
2. no wait方式 -- 如果无法获取请求的latch,则:
- 不会发生sleep或者spiin
- 转而获取其他的可用的latch
7.与latch相关的几个重要的视图
1.v$latch : 这个视图实际上是oracle对每个latch的统计信息的一个汇总,每一条记录表示一种latch
SQL> select name,gets,misses,sleeps,IMMEDIATE_MISSES,IMMEDIATE_GETS from V$LATCH where name like 'cache%'; NAME GETS MISSES SLEEPS IMMEDIATE_MISSES IMMEDIATE_GETS ------------------------------ ---------- ---------- ---------- ---------------- -------------- cached attr list 0 0 0 0 0 cache buffers lru chain 148106 31 31 9 92382 cache buffers chains 15182068 53 54 6 100303 cache buffer handles 3635 0 0 0 0 cache table scan latch 1367 0 0 0 1367
- name: latch 名称
- gets: 以Willing to wait请求模式latch的请求成功数
- misses: 以Willing-to-wait尝试请求不成功的次数
- sleeps: 以Willing-to-wait请求一个latch不成功后,进程获取等待latch的次数
- immediate_gets:以immediate请求类型成功获取的一个latch的次数
- immeidate_misses:以immeidate请求类型请求一个latch不成功的次数
2. v$latchholder
SQL> desc v$latchholder; Name Null? Type ----------------------------------------- -------- ---------------------------- PID NUMBER SID NUMBER LADDR RAW(8) NAME VARCHAR2(64) GETS NUMBER CON_ID NUMBER
包含了当前latch持有者的信息
通过视图中的pid和sid信息,关联视图v$session,v$session_wait,可以定位相应持有资源的会话信息。
9.Latch优化思路
Latch导致的性能问题,通常是一个系统层面的问题,所以:
- AWR报告是一个比较好的入口
- 通过动态视图v$latch,可以分析当前系统的latch资源情况
- 确定争用最大的latch
- 分析可能的原因
- 从应用层面和数据库层面考虑解决途径
10.补充
作为DBA关心的主要应有以下几种:
Cache buffers chains latch: 当用户进程搜索SGA寻找database cache buffers时需要使用此latch。
Cache buffers LRU chain latch: 当用户进程要搜索buffer cache中包括所有 dirty blocks的LRU (least recently used) 链时使用该种latch。
Redo log buffer latch: 这种latch控制redo log buffer中每条redo entries的空间分配。
Row cache objects latch: 当用户进程访问缓存的数据字典数值时,将使用Row cache objects latch。
下 面我们将着重介绍一下如何检测和减少redo log buffer latch的冲突。对redo log buffer的访问是由redo log buffer latch来控制的,这种latch有两种类型, redo allocation latch和redo copy latch。
Redo allocation latch控制redo entries在redo log buffer中的空间分配。Oracle的一个用户进程只有得到redo allocation latch后才能为redo entries在redo log buffer中分配空间,又由于一个instance只有一个redo allocation latch,所以一次只有一个用户进程在buffer中分配空间。当用户进程获得latch后,首先为redo entry分配空间,然后进程继续持有latch并拷贝entry到buffer中,这种拷贝称为“在redo allocation latch上的拷贝”(copying on the redo allocation latch),拷贝完毕后,用户进程释放该latch。
一个“在redo allocation latch上的拷贝”的redo entry的最大值是由初始化参数LOG_SMALL_ENTRY_MAX_SIZE定义的,根据操作系统的不同而不同。
Redo Copy Latch只应用于多CPU的系统。在多CPU的instance中,如果一个redo entry太大,超过了LOG_SMALL_ENTRY_MAX_SIZE定义值,则不能进行“在redo allocation latch上的拷贝”, 此时用户进程必须获取redo copy latch。一个instance中可以有多个redo copy latch,其数目由初始参数LOG_SIMULTANEOUS_COPIES决定,缺省值为CPU数目。
在单CPU情况下,不存在redo copy latch,所有的redo entry无论大小, 都进行“在redo allocation latch上的拷贝”。
对redo log buffer的过多访问将导致redo log buffer latch的冲突,latch冲突将降低系统性能,我们可通过如下查询来检测这种latch冲突:
col name for a40; SELECT ln.name,gets,misses,immediate_gets,immediate_misses FROM v$latch l,v$latchname ln WHERE ln.name IN('redo allocation','redo copy') AND ln.latch#=l.latch#;
若misses与gets的比例超过1%或immediate_misses与(immediate_gets+immediate_misses)比例超过1%时,应考虑采取措施减少latch的冲突。
大多数的redo log buffer latch冲突是在多个CPU情况下,两个或多个Oracle进程试图同时得到相同的latch发生的。由于一个instance只有一个redo allocation latch,为减少redo allocation latch的冲突,应减少单个进程持有latch的时间,这可以通过减小初始参数LOG_SMALL_ENTRY_MAX_SIZE以减小redo entry的数目和大小来实现。如果观察到有redo copy latch冲突,可以通过增大LOG_SIMULTANEOUS_COPIES 初始参数来加大latch数目,其缺省值为CPU数目,最大可增大到CPU数目的两倍。
标签:Latch,buffer,allocation,进程,深入,Oracle,latch,redo From: https://www.cnblogs.com/zmc60/p/17018479.html