暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle锁概念与常见锁分析详谈(起始篇)

OCM之家 2021-08-19
4318

裴征峰,现就职于北京海天起点,二线专家成员,南京办事处负责人,持有OCP 10g、OCP 11g、OCM 11g证书,
主要从事客户的现场维护,重大问题的解决,数据库性能分析,二线服务质量保证等工作。
拥有超过八年的Oracle服务经验,具备丰富的行业服务背景,对Oracle数据库有深刻的理解,
在Oracle数据库RAC以及高可用解决方案方面具有深厚的实践经验,擅长数据库故障诊断,数据库性能调优。

1、概述

本篇只注重相关原理研究,不涉及诊断案例。

Oracle的锁(lock)机制用于管理对共享资源的并发访问,注意,是“共享资源”而不是“数据库行”。当然Oracle会在行级对表数据锁定,这固然不错,不过Oracle也会在其他多个级别上使用锁,从而对多种不同的资源提供并发访问。例如,执行一个存储过程时,过程本身会以某种模式锁定,以允许其他用户执行这个过程,但是不允许另外的用户以任何方式修改这个过程。数据库中使用锁是为了支持对共享资源进行并发访问,与此同时还能提供数据完整性和一致性。


2、锁的相关知识

经常把锁分为3大类: 

  1. DML锁(Data Manipulation Locks)-用来保护数据的完整性和一致性。

  2. DDL锁(Data Dictionary Locks-用来保护数据对象的结构,如table,index的定义。

  3. 系统级锁(Latch、mutex、library cache pin/lock)- 用来保护数据库内部结构,如sga内存结构。


2.1Oracle锁视图

Oracle中ddl锁和dml锁的视图有:dba_ddl_locks、dba_dml_locks

其中dba_ddl_locks的视图定义如下:

create orreplace view dba_ddl_locks as

select  ……

   from v$session s, x$kglob ob, x$kgllk lk

   where lk.kgllkhdl = ob.kglhdadr

   and  lk.kgllkuse = s.saddr

   and  ob.kglhdnsp != 0;


而dba_dml_locks的视图定义如下:

create orreplace view dba_dml_locks as

select ……

from (selectl.laddr addr, l.kaddr kaddr,  * 1040651:Defn for v$lock */

                   s.ksusenum sid, r.ksqrsidttype, r.ksqrsid1 id1,

                   r.ksqrsid2 id2, l.lmodelmode, l.request request,

                   l.ctime ctime, l.block block

              from v$_lock l, x$ksuse s, x$ksqrsr

              where l.saddr = s.addr andl.raddr = r.addr and

                    s.inst_id =USERENV('Instance')) l, obj$ o, user$ u

      where l.id1 = o.obj#

      and  o.owner# = u.user#

      and  l.type = 'TM';


所以,在Oracle中,DDL锁其实应该是与x$kgllk有关的library cache方面的锁(library cache lock),而DML锁是指enqueue上的TM锁,$ksqrs是指kernel service enqueue resource。而enqueue中的其它类型,既不属于DDL锁与不属于DML锁,我们就称之为系统级enqueue。所以我们讨论DML锁,其实就是讨论TM enqueue。而讨论DDL锁,实际应该是讨论library cache方面的内容。


2.2Enqueue概念

enqueue是共享内存结构,用于串行化访问数据库资源。enqueue又分为用户级enqueue和系统级enqueue。

用户类型的enqueue有:

  • TM - DML (Table Manipulation)

  • TX - Transaction Enqueue used to protecttransaction information.

  • UL - User Lock Enqueue used when anapplication makes use of the DBMS_LOCK package.


系统类型的enqueue有:

  • BF enqueue

  • CF Controlfile Enqueue

  • DX Distributed Transaction Enqueue

  • FB Block Format Enqueue

  • HW High Water Enqueue

  • JS Job Scheduler Enqueue

  • RO Fast Object Reuse Enqueue

  • SQ Sequence Cache Enqueue

  • ST Space Transaction Enqueue

  • TO Temporary Table Object Enqueue

  • TT Tablespace Operations Enqueue

  • US Undo Segment Enqueue


2.3Library Cache概念

Librarycache是Shared pool的一部分,它几乎是Oracle内存结构中最复杂的一部分,主要存放shared curosr(SQL)和PLSQL对象(function,procedure,trigger)的信息,以及这些对象所依赖的table,index,view等对象的信息。

LibraryCache的结构如下所示:


LibraryCache中保存的对象,可以查看v$db_object_cache视图。从v$db_object_cache视图的定义可以看出,在该视图上有librarycache object对象上存在多少个pin和lock,但是具体是哪个会话加了pin或lock,在该视图上没有表现。

SQL> descV$DB_OBJECT_CACHE



2.4锁等级

在enqueue、library cache和latch中都有锁的等级概念,但我们一般只讨论enqueue中的锁等级概念,latch和library cache中锁等级涉及的方面较少。

x$kgllk中锁等级的定义:在kgllkmod和kgllkreq字段上定义了持有和请求x$kgllk资源的锁级别,其中锁级别如下:0, 'None', 1, 'Null', 2, 'Share', 3, 'Exclusive',这个可以通过dba_ddl_locks视图的定义可以观察到。

而enqueue中的锁等级可以参考:VIEW: "V$LOCK"Reference Note [ID 29787.1]

  • 0 - none

  • 1 - null (NULL)

  • 2 - row-S (SS)

  • 3 - row-X (SX)

  • 4 - share (S)

  • 5 - S/Row-X (SSX)

  • 6 - exclusive (X)


2.5锁冲突

如果会话请求相关锁的锁级别,和其它会话持有该锁的锁级别有冲突,那申请锁的会话会被挂住。总体原则如下:如果申请的锁级别小于持有的锁级别,那申请会话会被挂住等待。


如:某个会话持有4级TM锁(v$lock中LMODE=4),而某个会话想以3级(v$lock中REQUEST=3)来请求TM锁,那请求会话是得不到TM锁的,这就是锁冲突,除非持有4级TM锁的会话释放TM锁。


关于锁冲突的情况,需要关注和研究的一般是enqueue锁,具体可以参考:VIEW: "V$LOCK"Reference Note [ID 29787.1]


而其实Library Cache中也是存在锁冲突,这从v$db_object_cache的定义中可以看出来,只是Library Cache锁的级别较少,只有3级。

selectinst_id,

       kglnaown,

       ......

       decode(kglhdlmd,             

              0,              'NONE',               

                  1,              'NULL',               

                  2,              'SHARED',             

                  3,              'EXCLUSIVE',

              'UNKOWN'),

       decode(kglhdpmd,

              0,              'NONE',

              1,              'NULL',

              2,              'SHARED',

              3,              'EXCLUSIVE',

              'UNKOWN'),

       decode(kglobsta,

              1,              'VALID',

              2,              'VALID_AUTH_ERROR',

              3,              'VALID_COMPILE_ERROR',

              4,              'VALID_UNAUTH',

              5,              'INVALID_UNAUTH',

              6,              'INVALID',

              'UNKOWN'),

......

  from x$kglob

 where kglnaobj is not null。


enqueue锁冲突的表现为enq类型的等待事件,而实际上锁的详细情况(如持有者,阻塞者或者其它情况)是在v$lock表中。而很多enq类型的等待事件,其中p1、p2、p3列的信息就是v$lock中的id1和id2。当然其它的enq类型的等待事件的p1、p2、p3,其实也是v$lock的id1和id2的反映。

具体检查等待事件p1、p2、p3字段的含义,可以查询v$event_name。而查看v$lock的id1、id2的含义,可以查询v$lock_type。

而在libarary cache上的锁冲突的表现为:library cache %类型、cursor:%类型的等待事件,其中library cache类型的等待事件是library cache lock、library cache pin相关的锁,而cursor:%类型的等待事件对应的是相关的mutex。



中国OCM之家

专注数据    共现梦想

QQ群:554334183






文章转载自OCM之家,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论