ITPub博客

首页 > 数据库 > Oracle > 关于锁机制

关于锁机制

原创 Oracle 作者:fiona8953 时间:2015-01-16 18:02:31 0 删除 编辑
为了实现并发,oracle数据库使用了锁机制。要了解锁,首先要了解视图v$lock。
v$lock这个视图列出 Oracle 服务器当前拥有的锁以及未完成的锁请求。如果你觉着 session 处于等待事件队列当中,那你应该检查视图v$lock。

v$lock中的常用列有以下列:
     sid:持有锁的会话SID,通常与v$session关联。

     type:锁的类型,其中TM表示表锁或DML锁,TX表示行锁或事务锁,UL表示用户锁。我们主要关注TX和TM两种型的锁,其它均为系统锁,会很快自动释放,不用关注。当 Oracle执行 DML 语句时,系统自动在所要操作的表上申请 TM 类型的锁。当 TM锁获得后,系统再自动申请 TX 类型的锁,并将实际锁定的数据行的锁标志位进行置位。TM 锁包括了SS 、 SX、 S 、X 等多种模式,在数据库中用 0 -6 来表示。不同的 SQL 操作产生不同类型的 TM锁。

     lmode:会话保持的锁的模式。
          0=None;
          1=Null ;
          2=Row-S (SS,行级共享锁,其他对象只能查询这些数据行),sql操作有select for update、lock for update、lock row share;
          3=Row-X (SX,行级排它锁,在提交前不允许做DML操作),sql操作有insert、update、delete、lock row share;
          4=Share(共享锁),sql操作有create index、lock share;
          5=S/Row-X (SSX,共享行级排它锁),sql操作有lock share row exclusive;
          6=Exclusive(排它锁),alter table、drop table、drop index、truncate table、look exclusive等DDL

     ID1,ID2:  ID1,ID2的取值含义根据type的取值而有所不同,对于TM 锁ID1表示被锁定表的object_id 可以和dba_objects视图关联取得具体表信息,ID2 值为0;对于TX 锁ID1以十进制数值表示该事务所占用的回滚段号和事务槽slot number号,其组形式: 0xRRRRSSSS,RRRR=RBS/UNDO NUMBER,SSSS=SLOT NUMBER,ID2 以十进制数值表示环绕wrap的次数,即事务槽被重用的次数。实际上这两个字段构成了事务在回滚段中的位置。

当锁产生时,以下图为例说明v$lock:
1、图中存在两个session分别是133和135,session135的BLOCK=1意味着该session拥有一个锁,并阻塞了其他session的对该锁的请求。该锁的类型由TY定义,模式由LMODE字段定义;
2、session133的request=6说明该session正在等待一个lmode为6的锁,而该锁的拥有者正是session135。
3、对于TM锁,ID1Z值就是加锁的段对象,可以是表或者表分区,此时ID2一般为0;对于TX锁,这两个字段构成该事务在回滚段中的位置。

对于死锁的处理流程:
1,查找锁:
select ls.osuser os_user_name,
ls.username user_name,
ls.type lock_type,
o.object_name object,
decode(ls.lmode,1,null,2,'Row Share',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive',null) lock_mode,
o.owner,
ls.sid,
ls.serial# serial_num,
ls.id1,ls.id2,
ls.paddr
 from sys.dba_objects o,
(select s.osuser,s.username,l.type,s.paddr,l.lmode,s.sid,s.serial#,l.id1,l.id2  from v$session s,v$lock l where s.sid=l.sid) ls
where o.object_id=ls.id1 and o.owner<>'SYS' order by o.owner,o.object_name
2,查找spid
select a.spid,a.username,b.program  from v$process a,v$session b where a.addr=b.paddr and a.addr='000007FF2DC8E578';
3、kill进程
alter system kill session 'sid,serial#' immediate;
orakill sid spid
sid:表示要杀死的进程属于的实例名
thread:是要杀掉的线程号,即第2步查询出的spid。    


理解V$LOCK.ID1和ID2字段的含义

第一段理解:
TM
For the lock type TM (table lock), column ID1 is the object_id (or the
  data_object_id) for that table (could be joined with DBA_OBJECTS). 
TX
For a
  lock of type TX (transaction lock), TRUNC( ID1 / 65536 ) shows which
  rollback segment that is used for the transaction and ID1 - 
  ( rollbacksegment# * 65536 ) shows which slot number in the transaction
  table that this sessions is using (or want to used).

第二段理解:
TM        
id1:被修改表的标识(object_id)
id2:0
TX
id1:以十进制数值表示该事务所占用的回滚段号与该事务在该回滚段的事务表(Transaction table)中所占用的槽号(slot number,可理解为记录号)。其组成形式为: 0xRRRRSSSS ( RRRR = RBS number, SSSS = slot )。
id2:以十进制数值表示环绕(wrap)次数,即该槽(slot)被重用的次数。

第三段理解:
TX
TX的id1经过分解对应V$transaction 的 XIDUSN,XIDSLOT。
id2对应 XIDSQN。

        上面的三段理解实际是一个含义,TX锁所在的ID实际是由回滚段号和槽号组成,可分解成V$TRANSACTION的XIDUSN和XIDSLOT字段,ID1/65536就等于V$TRANSACTION.XIDUSN。ID2是事务对应的槽号所使用的次数,对应V$TRANSACTION.XIDSQN字段。

下面通过多个会话事务向主键表插入重复值的例子讨论ID1和ID2的含义:
1).表结构:
SQL> desc x1
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                        NOT NULL NUMBER
 NAME                                               VARCHAR2(20)
其中ID是主键。

2).会话1:
SQL> insert into x1 values(5,'SB');

1 row created.

3).会话2:
SQL> insert into x1 values(5,'SBB');
由于插入了ID=5的重复值,执行被卡住。

4).会话3:
SQL> select sid,type,id1,id2,lmode,request,block from gv$lock where (id1,id2) =(
select id1,id2 from gv$lock where block=1);  2

       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       141 TX     196612       1240          6          0          1
        16 TX     196612       1240          0          4          0

SQL> select sid,blocking_instance,blocking_session from v$session where blocking_instance is not null;

       SID BLOCKING_INSTANCE BLOCKING_SESSION
---------- ----------------- ----------------
        16                 1              141


SQL> select sid,type,id1,id2,lmode,request,block from gv$lock where sid=141;

       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       141 AE        100          0          4          0          2(11gR2新出现的锁)
       141 TX     196612       1240          6          0          1
       141 TM      74637          0          3          0          2

V$TRANSACTION视图:
SQL> select xidusn,xidslot,xidsqn,xid from v$transaction ;

    XIDUSN    XIDSLOT     XIDSQN XID
---------- ---------- ---------- ----------------
        10          5        883 0A00050073030000
         3          4       1240 03000400D8040000

        从上面的执行可以观察出以下几点:
         1.会话141阻塞了会话16。
         2.TM表锁的ID2始终等于0。
         3.会话16的REQUEST等于4,表明该会话在等待被TX锁住的其他资源。
         4.会话141和会话16的ID1和ID2完全相同,这ID1和ID2表示的是BLOCK=1的事务的ID1和ID2。根据这个特性通常查找一个会话或一个数据库阻塞的锁就可以执行以下的两条SQL:
SELECT * FROM V$LOCK WHERE (ID1,ID2) IN(SELECT ID1,ID2 FROM V$LOCK WHERE SID=&SID);
SELECT * FROM V$LOCK WHERE (ID1,ID2) IN (SELECT ID1,ID2 FROM V$LOCK WHERE BLOCK=1);
         5.会话141的ID1=196612,196612/65536=3=V$TRANSACTION.XIDUSN,会话141的ID2=1240=V$TRANSACTION.XIDSQN。



深入浅出oracle锁---原理篇
http://blog.csdn.net/tangyangbuaa/article/details/4526146

What's blocking my lock?


http://www.orafaq.com/node/854

http://logicalread.solarwinds.com/oracle-locking-and-enqueue-waits-dr01/#.VLjBGkeUeI8
http://blog.csdn.net/indexman/article/details/42293007

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

上一篇: 关于SID & SERIAL#
请登录后发表评论 登录
全部评论

注册时间:2014-06-13

  • 博文量
    284
  • 访问量
    222500