ITPub博客

首页 > Linux操作系统 > Linux操作系统 > row cache lock与seq竞争

row cache lock与seq竞争

原创 Linux操作系统 作者:v_fantasy 时间:2009-01-06 15:32:39 0 删除 编辑
row cache lock
oracle将数据字典存于sga内的行高速缓冲区(dictionary cache)内。行高速缓冲区位于共享池区域,可通过如下命令进行确认。
sql> select pool,name,bytes from v$sgastat
where name='row cache';
想要修改数据字典内容的进程,应对其相应的row cache object获得row cache lock。其中最具代表性的是sequence,在获取sequence的nextval过程中需要修改数据字典信息是应该对row cache object 以ssx 模式获得row cache lock。
row cache lock 不使用enqueue结构,而通过row cache object信息内保存的锁拥有者列表和锁等待者列表,体现阻碍(blocking)机制。这些结构与library cache lock,library cache pin,fuffer lock相同,例如缓冲区头上存在用户列表和等待者列表,通过 这两个列体现阻碍机制。通常,将row cache lock称为row cache enqueue,这只是为了准确表达含义所使用的术语,但是与tx锁不同,它不使用enqueue结构。
利用v$rowcache视图和v$rowcache_parent视图,可以分析row cache的争用。row cache lock等待事件有一点也不方便,那就是它只提供对象类型信息,而不提供实际对象信息。所以很难准确掌握哪些row cache object有问题。利用行高速缓冲区转储,可以获取实际对象信息。
许多进程同时使用没有cache属性的sequence时,可能大量发生row cache lock事件等待。对没有使用cache 的sequence,如果调用nextval,则每次数据字典信息都应被修改,以ssx模式获取row cache lock。因为ssx之间不存在共享性,所以在此过程中发生争用。
以下测试,从行高速缓冲区转储和v$rowcache_parent视图确认准确的对象信息的方法
【测试 26】 sequence 和row cache lock
sql>
--创建nocache属性的sequence
create sequence seg_seg nocache;
--取得sequence的object id后,将其转换为16进制数,只有利用了16进制数,才能引用行高速缓冲区转储内的sequence相关信息。
sql> select object_id from dba_objects where object_name='SEG_SEG';

sql> select to_hex(..) from dual;

...<--利用这个值查找行高速缓冲区转储

---使用以下命令,对row cache进行转储
sql> alter session set events 'immediate trace name row_cache level 12'

---行高速缓冲区转储文件内容如下:
..
..
---接下来,观察大量nextval过程中,怎样获得row cache lock.
-- 如下,调用10000次seq_seq.nextval.
--因为对row cache lock的获得和释放时间非常短,所以只有执行多次才能观察。
sql> declare
v_seq number;
begin
for idx in 1 .. 10000 loop
select seq_seq.nextval into v_seq from dual;
end loop;
end;
/

--上述pl/sql执行期间,利用通过转储获得的address= 查看
sql> exec print_table9('select * from v$rowcache_parent where address='' ''');
除了sequence之外,几乎没有如此频繁地修改行高速缓冲区信息的。因此,出现row cache等待时,需要确认sequence上是否赋予了nocache属性,ops环境下,为了保障sequence的顺序,以nocache属性创建了sequence时,经常出现row cache lock等待现象。rac环境下,使用cache属性的同时,可以保障各节点之间sequence的顺序是可能的。
对于sequnce之外的对象发生row cache lock等待,除了减少并发性外,没有什么其他更好方法。若广泛出现不明原因的row cache lock等待,因通过metalink确认是否与oracle的缺陷有关。

6.2 enq:SQ-concention,DFS lock handle(SV)
oracle为了管理sequence使用了以下三种锁
*row cache lock :调用sequence.nextval过程中(nocache)
* SQ锁 : 调用sequence.nextval过程中(cache+noorder)
* SV锁(dfs lock handel) :RAC上节点之间顺序得到保障的的前提下,调用sequence.nextval期间拥有。赋予了cache + order属性的sequence上发生。 (cache+order)
创建sequence赋予的cache值较小时,有enq:sq-contention等待增加的趋势。cache的默认缺省值是20.因此创建使用量多的sequence时,cacheh值应取1000以上的较大值。偶尔一次性同时创建多个会话时,有时发生enq:sq-contention等待事件。其理由是v$session.audsid列值是利用sequnce创建的,许多会话同时连接时,可以将sys.audses$sequence的cache大小扩大至1000,以此解决enq:sq-contention等待问题。
Rac上创建sequence时,在赋予了cache属性的状态下,若没有赋予order属性,则各节点将会把不同范围的sequence值cache到内存上。
若两个节点之间都通过递增方式使用sequence,必须 赋予如下的order属性
sql> create sequence ordered_sequence cache 100 order;
如果是已赋予了cache+order属性的sequence,oracle使用SV锁进行同步。SV锁争用问题发生时的解决方法与sq锁的情况相同,就是将cache 值进行适当调整,这也是唯一的方法。
在RAC多节点环境下,Sequence的Cache属性给性能带来的影响比单节点环境更严重。因此尽量赋予cache+noorder属性,并要给予足够的cache值。如果需要保障顺序,必须赋予cache+order属性。但这时为了保障顺序,实例之间需要不断的交换数据。因此性能稍差。

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

请登录后发表评论 登录
全部评论

注册时间:2008-10-07

  • 博文量
    98
  • 访问量
    179852