如果对一个pipe有多个读者,此时对于这个pipe的library cache object的library cache pin等待将会很正常routine,仅仅是短暂的.除了这个情况,
library cache waits相比很少发生,尽管更可能被延长.这些等待会超时(在3秒),如果超时的话,会发现死锁。如果发生死锁的话,lock或pin的请求会中断并返回一个
ora-4020错误。这个错误一般就是由于ad hoc ddl所引起的.当然没有必要专门编码处理这个错误.
dml locks
library cache pins和相关的row cache enqueue locks保护解析期间及执行调用期间的对象定义。但是,包括一系列语句的事务,同理也要在这个事务持有一个lock,以保护这个事务.
而且(除此以外),锁模式可能在这个事务期间会发生变化。比如,一个表首先被查询,然后进行更新。也就是说锁转换是必要的。如果已存在的锁被release,甚至暂时(立刻),有可能发生引用的对象被删除或改变,这样事务可能不能继续或者rollback.
rollback可能性,尤其rollback到某个保存点,增加复杂度到dictionary locking字典锁定。换句话说,如果一个事务rollback不在这个锁升级的保存点范围之内,此时这个锁必须发生对应的降级,作为rollback操作一部分,为了减少人工死锁的可能性.
运行事务需要dictionary locking,而且,特别要维护lock conversions的历史变化信息表(就是把事务中锁转换的信息全记录下来),它是通过dml lock及tm enqueues结合来达到这个目的。每个持有dml lock的事务同时会包含一个tm enqueue lock.
enqueue会提供基本的锁定功能,dml lock会维护转变历史(锁转换)的信息表.
dml lock结构的固定队列,由dml_locks来控制。它的自由列表由dml lock allocation latch给于保护,查询v$locked_object会看到active slots.对于入队资源和锁,dml lock固定队列的slots数目,对于性能的影响关系不大,只要你没有用完free slots,否则会发生ora-55.
另外,v$resource_limit可以调整dml_locks,这样确保不会发生以上情况。每个slot占用116 bytes的顺序,因此占用大量的slots不是什么问题.
disabling dml locks
dml locks和对应的tm enqueue locks可以被禁用,你可以全部禁用,或者仅仅禁止用某些表。为了全部禁用这个锁,
dml_locks必须被设置为0。在一个并行服务器数据库中,在所有实例中必须设置为0.为了禁用对于某个表的locks.必须要显式指定alter table disable table locks.
如果禁用了某个表的锁,这样dml 语句可以修改这个表的块,同时持有row-level locks。但是,不会持有用于查询情况的sub-shared mode的表锁及用于dml的sub-exclusive mode的表锁。相反它采用这样的机制,在对一个表实行事务时,如果同时发生ddl操作,它只是简单通过阻止所有对这个表加锁的请求,而且防止所有对这个表的ddl操作.
禁用dml locks和table locks有两种原因。第一种,避免过多的得到锁。在ops环境下,每个事务很短,这特别重要。在这种情况下,可能要花更多时间获得tm instance lock比完成一个事务。
在单实例数据库下,获得锁的成本是很小的(微不足道)。但是,禁止表锁会有效防止blocking lock问题.比如长期的blocking lock问题是由于锁定整个表导致的,有时是由于ad hoc ddl,比如像一个索引,但往往可能是由于对引用表实行ad hoc dml引起的,这里的关系没有使用外键索引.
引用主表的外键经常要构建索引,防止出现这种情况。但是,对于对这个表进行dml操作时,构建这种索引也会增加更多的成本。最好不用创建索引,防止禁用表锁引起blocking locks问题。当然,在实行更新一个引用数据(表)或者重建索引时,需要暂时持有表锁。但是,这并不难于实现,因为这种操作正常情况在一个特定的维护时间内进行.
当然,最好是针对每个表禁用表锁,而不是设置dml_locks为0来全部禁用它们。如果配置dml_locks为0,你可以创建临时表,但不能删除它们。如果你要进行某些维护操作:重建索引 ,你必须关闭和重启系统二次.
buffer locks
采用enqueue locking保护缓存的database blocks.每个database buffer cache的buffer,都有一个buffer header.这些buffer headers在共享池固定内存部分组成一个固定队列。这些buffer headers起到buffer locks的资源结构作用(或者讲buffer header就是buffer lock的资源结构).sessions会话操作buffer headers,进而操作buffers,通过buffer handles动态分配资源结构。这些
buffer handles相当于buffer locks的lock structures.
buffer lock只能要共享和排它模式下持有。buffer headers通过对buffer handles实现一个双向链表,服务使用buffer的sessions,以及另外等待这些buffer会话,它们想拿到buffer handles.等待buffer lock的会话会报告可能是:buffer busy waits,或者buffer busy due to global cache waits,或者write complete waits.
buffer busy waits的参数如下:
wait parameters(buffer busy waits)
参数 描述
p1 数据块的文件号
p2 文件中数据块的块号
p3 等待原因.a或1014表明buffer被另一个会话以排它模式锁定。这个会话正在从磁盘从一个block读入到buffer中,因此这个读不能完成目前.a表示用于consistent gets,这里1014用于并发模式block gets,其它任何数字表明:buffer被另一个会话以排它模式锁定
buffer busy waits超时可能会在1到3秒之间被中断或放弃。如果cache中某个block不能被进程持有buffer lock时,同时经历了多次超时,如果会话对一个或多个其它的buffers持有buffer locks,这时会产生buffer lock deadlock.buffer lock deadlock之前的超时次数与尝试的操作有关系,与它是否是离散事务的一部分也有关.因为离散事务不会持有事务锁和行级锁,它们必须
获得在更新之前必须获得所有的buffer locks,持有这些buffer locks直到事务准备完成这个更改和提交.这意味着离散事务会比正常的事务持有或占有更多的buffer locks,且持有时间更长.
如果怀疑出现buffer lock deadlock,想获取一个buffer lock超时的会话,将会release持有其它buffers的lock,同时马上又把这些released lock入队,因此falling to到等待会话队列的末端。它也给第一个进程(等待相关buffers的lock)发送通知,然时让出对应的cpu.虽然让出cpu不是真正组成的等待,buffer deadlock wait会记录下来,交换deadlocks统计的值会递增。如果buffer lock
deadlocks发出event 370,分析它可以研究这个问题.
在并行服务器库ops下,比如global cache操作(全局缓存操作)的写操作为了响应ping请求,会锁定buffers,块服务器进程进行直接内存传递时的一致性读取consistent reads.如果请求一个buffer lock不能继续下去,因为global cache operation会锁定这个buffer,这时会生产(记录下来)一个buffer busy due to global cache wait.
同理,当请求buffer lock不能满足(操作继续下去),因为buffer被dbwn进程锁定,用于以批处理方式写入这些块(从内存buffer cache到disk),这时会记录write complete waits。这些等待的超时是1秒,具体参数如下:
wait parameters(write complete waits)
参数 描述
p1 数据块所在的文件号
p2 文件中数据块的块号
p3 等待原因。正常的原因码是1029;但是你会一直看到其它值
sort locks
用于产生磁盘排序操作的磁盘空间.这里有两类sort locks:temprary table locks和sort segment locks.这些分别对应于
permanent表空间的临时segments和termporary tablespace。在sga固定队列会存储及处理每种类型的sort lock(也就是刚说到的)。这两个arrays大小由sessions来控制,请考虑使用sort locks的最大使用量.
sort locks仅仅用于trace disk sort space使用情况,不会遭遇或碰到lock冲突,等待或死锁。但是,你不要搞混sort locks和st(space transaction) enqueue,这特别可能产生锁冲突,等待和一致even的死锁。竞争st enqueue经常与disk sorts有关,因为创建,扩展,回收temporary segments要用到它。
parameters参数
参数 描述
_distrubuted_lock_timout 分布式事务上面锁的超时。默认是60秒.
_enqueue_hash enqueue hash table大小
_enqueue_hash_chain_latches 用于访问enqueue hash table的latch数目,默认是cpu count
_enqueue_locks enqueue lock结构的数量
dml_locks dml locks固定队列的大小。如果可能,禁用dml locking可以减少locking成本和出现blocking locks的风险
enqueue_resources enqueue resource队列的大小
parallel_transaction_resource_timeout 在oracle 8.0中并行事务分支和另一个事务出现死锁的超时
temporary_table_locks 在oracle8中已经废弃。它在oracle8.0存在,但已经不起任何作用了.
event事件
事件 描述
60 这是enqueue deadlock错误。如果重复发生这个情况,这种神秘的死锁问题,你可能需要采用这个事件作一个systemstate dump,以分析或诊断引起死锁问题的根源
370 buffer cache deadlock会发出这个事件,用于调查或分析严重的buffer locking竞争,使用processstate dumps.
4020 这是library cache deadlock检测错误,采用这个事件实行一个systemstate dump,你就会发现到底发生了什么。反之,你不会发现这个。
4021 这是library cache deadlock超时错误。为何需要超时呢,因为library cache deadlock检测机制不是exhaustive,而是过于昂贵。再次出现时,这个错误正常是由于ad hoc ddl引起
statistics统计
统计 资源(源处) 描述
enqueue conversions v$sysstat 本地入队转化次数
enqueue deadlocks v$sysstat 发现和中断的本地入队死锁
enqueue releases v$sysstat 本地入队releases次数
enqueue requests v$sysstat 本地入队请求数
enqueue timeouts v$sysstat 被中断的本地入队操作次数
enqueue waits v$sysstat 要等待入队操作的次数,而不是等待的次数
exchange deadlocks v$sysstat 本地buffer deadlock的数量。统计名字反映一个事实:索引 块交换也可能是这种死锁产生的原因之一
waits
事件 描述
buffer busy due to global cache 获取一个buffer上的本地buffer lock,因为当时发生global cache operation,如ping操作,而被阻塞
buffer busy waits 等待一个以非兼容模式对本地buffer持有的锁
buffer deadlock 等待一个本地buffer lock发生死锁
enqueue 对本地和全局入队的等待
library cache load lock 如果两个会话尝试同时加载load一个对象的library cache information,就会发生这个锁。相反,同时reload会引起library cache pin waits
library cache lock 等待引用或查找处于(that is in flux)的library cache object
library cache pin 等待修改处于flux状态的library cache object
row cache lock 等待获取本地一个row cache enqueue或者一个row cache instance lock
write complete waits 等待一个block上面的一个buffer lock(它是正常批量写的一部分)
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9240380/viewspace-660657/
,如需转载,请注明出处,否则将追究法律责任。