码迷,mamicode.com
首页 > 其他好文 > 详细

锁的基本原理

时间:2015-02-24 10:20:26      阅读:271      评论:0      收藏:0      [点我收藏+]

标签:锁的基本原理   oracle锁类型   行级锁   锁的兼容性   加锁语句以及锁的释放   

oracle032

锁的基本原理

1、Oracle锁类型
     锁的作用:保护数据,没有锁就没有并发,锁是用来限制并发的
     数据库反应慢不一定是数据负严重,也可能是锁的原因阻止了事务的进行:开两个客户端修改数据会明显发现第二个会很慢就是因为第一个用户锁住了行记录
    
     latch锁:chain,链(server Pro 并发访问时就通过获取latch锁来进行保护链)
     LOCK锁:buffer 、数据块、数据行
          排他锁(X):就是A访问加锁X而B就不能访问加锁了
          共享锁(S):就是A、B都可以加相同的共享S锁
2、行级锁:DML语句;是LOCK锁的最小粒度锁;oracle特有也最影响并发的效率的
     事务锁TX:一个事务一个事务锁,是因为行级锁产生的
          锁的结构
          事务锁的加锁和解锁过程:DML语句(加锁);commit/rollback(解锁)
     只有排他锁(行级锁和事务锁都是排他锁的类型)
          不影响读(CR块)
3、表级锁:TM

     行级排他锁(Row exclusive)RX锁
          当我们进行DML时,会自动在被更新的表上添加RX锁,可以执行LOCK命令显式的在表上添加RX锁
          允许其他事务通过DML语句修改相同表里的其他数据行
          允许使用lock命令对表添加RX锁定
          不允许其他事务对表添加X锁
技术分享
     行级共享锁(Row Shared,简称RS锁)
          select … from for update
     是会产生一个事务,和普通DML语句一样产生行级锁,并在表级别加了一个RS锁没加RX锁;但实际并没有修改数据
    
     共享锁(Share,简称S锁)
          通过lock table in share mode命令添加该S锁
     排他锁(Exclusive,简称X锁):对表的结构进行改变,和表的删除;其他用户不能进行任何操作
          通过lock table in exclusive mode命令添加X锁
     共享行级排他锁(Share Row Exclusive,简称SRX锁)
          通过lock table in share row exclusive mode命令添加SRX锁

     lock table  in [row share][row exclusive][share][share row exclusive][exclusive] mode;

研究锁侧重于两点:锁的兼容性,锁的产生原因
4、锁的兼容性
技术分享
5、加锁语句以及锁的释放
技术分享
6、锁相关视图
     v$transaction
          XIDUSN表示当前事务使用的回滚段的编号
          XIDSLOT说明该事务在回滚段头部的事务表中对应的记录编号(也可以叫做槽号)
          XIDSQN说明序列号
          STATUS说明该事务是否为活动的
     v$lock
          记录了session已经获得的锁定以及正在请求的锁定的信息
          SID说明session的ID号
          TYPE说明锁定锁定级别,主要关注TX和TM
          LMODE说明已经获得的锁定的模式,以数字编码表示
          REQUEST说明正在请求的锁定的模式,以数字编码表示
          BLOCK说明是否阻止了其他用户获得锁定,大于0说明是,等于0说明否

     锁定模式          锁定简称     编码数值
     Row Exclusive          RX           3
     Row Shared           RS          2
     Share                S           4
     Exclusive           X           6
     Share Row Exclusive      SRX           5
     NULL                 N/A           0或者1

     v$enqueue_lock
     该视图中包含的字段以及字段含义与v$lock中的字段一模一样。
     只不过该视图中只显示那些申请锁定,但是无法获得锁定的session信息。
     其中的记录按照申请锁定的时间先后顺序排列,先申请锁定的session排在前面,排在前面的session将会先获得锁定。

     v$locked_object
     记录了当前已经被锁定的对象的信息
     XIDUSN表示当前事务使用的回滚段的编号
     XIDSLOT说明该事务在回滚段头部的事务表中对应的记录编号
     XIDSQN说明序列号
     OBJECT_ID说明当前被锁定的对象的ID号,可以根据该ID号到dba_objects里查找被锁定的对象名称
     LOCKED_MODE说明锁定模式的数字编码

     v$session
     记录了当前session的相关信息
     SID表示session的编号
     SERIAL#表示序列号
     SID和SERIAL#可以认为是v$session的主键,它们共同唯一标识一个session
测试锁:
开启3个session:

SQL>  select sid from v$mystat where rownum=1;

       SID
----------
        29

SQL>

SQL>  select sid from v$mystat where rownum=1;

       SID
----------
        35

SQL>


SQL>  select sid from v$mystat where rownum=1;

       SID
----------
        38

SQL>

使用sessionID为29进行更新t表操作
SQL>  update t set name=‘qq‘ where id = 2;

1 row updated.

SQL>
查询事务: select xidusn,xidslot,xidsqn,status from v$transaction;
                  5     30     1099     ACTIVE
说明当前存在一个活动的事务

下面是查询sessionID为29的连接所产生的事务信息:
 select sid,type,id1,id2,
     decode(lmode,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) lock_mode,
  decode(request,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘)
     request_mode,block
     from v$lock
     where sid=29;

SID, TYPE, ID1, ID2, LOCK_MODE, REQUEST_MODE, BLOCK
29     AE     100     0     Share     None     0
29     TM     74585     0     Row Exclusive     None     0//表级锁
29     TX     327710     1099     Exclusive     None     0//行级锁
SID表示sessionID,TYPE表示锁的类型,ID2表示事务槽被覆盖的次数,ID1中的信息包含两种信息:1.事务表  2.事务表中行
通过:
     将ID1拆解
     select trunc(327710/power(2,16)) as undo_blk#,bitand(327710,to_number(‘ffff‘,‘xxxx‘)) + 0 as slot#
     from dual;
UNDO_BLK#, SLOT#
      5     30//显示的是该事务的信息,这也说明了ID1表示了两种信息的说法。
LOCK_MODE表示锁的模式,REQUEST_MODE是否请求锁,BLOCK表示锁住哪个事务
select OWNER,OBJECT_NAME,OBJECT_ID,OBJECT_TYPE,CREATED,LAST_DDL_TIME,STATUS,NAMESPACE from dba_objects where object_id=74585;//被锁的对象

OWNER, OBJECT_NAME, OBJECT_ID, OBJECT_TYPE, CREATED, LAST_DDL_TIME,    STATUS, NAMESPACE
  SYS     T            74585     TABLE     22-12月-14     04-1月 -15     VALID     1
     对于TM锁来说,ID1表示被锁定的对象的对象ID,ID2始终为0
     对于TX锁来说,ID1表示事务使用的回滚段编号以及在事务表中对应的记录编号,ID2表示该记录编号被重用的次数(wrap)

使用sessionID为35进行更新t表操作:
SQL> update t set name=‘ww‘ where id = 2;
//没有执行结果说明被锁住了
下面是查询sessionID为29、35的连接所产生的事务信息:
     select sid,type,id1,id2,
decode(lmode,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) lock_mode,
decode(request,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘)
request_mode,block
from v$lock
where sid in(29,35)
order by sid;

SID, TYPE, ID1, ID2, LOCK_MODE, REQUEST_MODE, BLOCK
29     TM     74585     0     Row Exclusive     None     0
29     AE     100     0     Share     None     0
29     TX     327710     1099     Exclusive     None     1//锁住了一个事务
35     TM     74585     0     Row Exclusive     None     0
35     AE     100     0     Share     None     0
35     TX     327710     1099     None     Exclusive     0//请求一个排他锁,因为上面的29锁住了

使用sessionID为38进行更新t表操作:
SQL> update t set name=‘ww‘ where id = 2;
//没有执行结果说明被锁住了

查询v$enqueue_lock来获得锁定队列中的session信息:
     select sid,type,
     decode(request,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘)
     request_mode
     from v$enqueue_lock
     where sid in(35,38);

SID, TYPE, REQUEST_MODE
35     AE     None
38     AE     None
35     TX     Exclusive
38     TX     Exclusive
可以知道sessionID为35,38的连接需要锁为X锁

查询几个锁之间的关系:
select a.sid blocker_sid,a.serial#,a.username as blocker_username,b.type,
decode(b.lmode,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) lock_mode,
b.ctime as time_held,c.sid as waiter_sid,
decode(c.request,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) request_mode,
c.ctime time_waited
from   v$lock b, v$enqueue_lock c, v$session a
where  a.sid = b.sid and    b.id1= c.id1(+) and b.id2 = c.id2(+) and c.type(+) = ‘TX‘ and  b.type = ‘TX‘ and  b.block   = 1
order by time_held, time_waited;

BLOCKER_SID, SERIAL#, BLOCKER_USERNAME, TYPE, LOCK_MODE, TIME_HELD, WAITER_SID, REQUEST_MODE, TIME_WAITED
        29     557               SYS     TX     Exclusive     2452     38          Exclusive     274
        29     557               SYS     TX     Exclusive     2452     35          Exclusive     712
BLOCKER_SID:锁的sessionID为29,BLOCKER_USERNAME:锁的用户名是sys,
TYPE:锁的类型为TX(行级锁)LOCK_MODE:锁的模型为排他锁,TIME_HELD:锁所持续的时间
WAITER_SID:该锁被哪个sessionID锁等待,REQUEST_MODE:请求锁的类型,TIME_WAITED:请求时间
通过上面的信息就可以知道某个连接所持有的锁时间,假如时间过长说明该连接存在问题,就可以杀掉该连接
alter system kill session ‘29,557‘;//第一个参数BLOCKER_SID,第二个为SERIAL#参数

一个事务修改多行,产生一个TX锁
select sid from v$mystat where rownum=1;

SQL> update t set name=‘rr‘ where id=2;

1 row updated.

SQL> update t set name=‘rr‘ where id=2;

1 row updated.

SQL> update t set name=‘rr‘ where id=2;

1 row updated.

SQL>

select sid,type,id1,id2,
decode(lmode,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘) lock_mode,
decode(request,0,‘None‘,1,‘Null‘,2,‘Row share‘,3,‘Row Exclusive‘,4,‘Share‘,5,‘Share Row Exclusive‘,6,‘Exclusive‘)request_mode,block
from v$lock
where sid=38;

SID, TYPE, ID1, ID2, LOCK_MODE, REQUEST_MODE, BLOCK
38     AE     100     0     Share     None     0
38     TM     74585     0     Row Exclusive     None     0
38     TX     327680     1099     Exclusive     None     0

可以获得的TX锁定的总个数由初始化参数transactions决定,而可以获得的TM锁定的个数则由初始化参数dml_locks决定:
select name,value from v$parameter where name in(‘transactions‘,‘dml_locks‘);

       NAME, VALUE
dml_locks     1084
transactions     271

查询资源的使用情况:
select resource_name as "R_N",current_utilization as "C_U",max_utilization as "M_U",initial_allocation as "I_U"
from v$resource_limit
where resource_name in(‘transactions‘,‘dml_locks‘);
        R_N,     C_U,  M_U,        I_U
   dml_locks     1     1           1084
transactions     1     1            271
通过上面的参数可以知道dml_locks资源当前使用了1个而且最多的时候也只使用了1个,最大的资源数为1084
transactions同上,通过这个可以判断资源设置是否合理,假如M_U的值等于或者接近于I_U时说明需要增大I_U值因为:
可以获得的TX锁定的总个数由初始化参数transactions决定,而可以获得的TM锁定的个数则由初始化参数dml_locks决定
     grant select on v_$mystat to hr;

死锁
两个session(以A和C来表示),如果A持有C正在申请的锁定,同时C也持有A正在申请的锁定时,这时发生死锁现象。死锁是典型的“双输”情况,如果任其发展,则会出现A和C这两个session正在执行的事务都无法结束的现象。因此,在Oracle数据库中,造成死锁的那个DML语句会被撤销。死锁总是由于应用程序设计不合理引起的。
当某个session的事务引起了死锁时,Oracle会自动将阻塞该事务的其他事务中相应的DML语句撤销,而阻塞该事务的其他事务中的其他DML语句并没有撤销。

session 1
select sid from v$mystat where rownum=1;
update employees set last_name=last_name||‘a‘
where employee_id=100

session 2
select sid from v$mystat where rownum=1;
update employees set last_name=last_name||‘b‘
where employee_id=101;

session 1
update employees set last_name=last_name||‘c‘ where employee_id=101;

session 2
update employees set last_name=last_name||‘d‘ where employee_id=100;

对HR用户进行解锁和密码设置:

SQL>  select username,password,account_status from dba_users where username=‘HR‘;

USERNAME                       PASSWORD
------------------------------ ------------------------------
ACCOUNT_STATUS
--------------------------------
HR
EXPIRED & LOCKED//过期且被锁住的状态



SQL> alter user hr account unlock;

User altered.

SQL>  select username,password,account_status from dba_users where username=‘HR‘;

USERNAME                       PASSWORD
------------------------------ ------------------------------
ACCOUNT_STATUS
--------------------------------
HR
EXPIRED//此时hr只是过期并没有被锁住


SQL> alter user hr identified hr;
alter user hr identified hr
                         *
ERROR at line 1:
ORA-00924: missing BY keyword


SQL>  alter user hr identified by hr;

User altered.

SQL>  select username,password,account_status from dba_users where username=‘HR‘;

USERNAME                       PASSWORD
------------------------------ ------------------------------
ACCOUNT_STATUS
--------------------------------
HR
OPEN//打开状态


SQL>




























锁的基本原理

标签:锁的基本原理   oracle锁类型   行级锁   锁的兼容性   加锁语句以及锁的释放   

原文地址:http://blog.csdn.net/u011218159/article/details/43924233

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!