设为首页 收藏本站
查看: 1196|回复: 0

[经验分享] Oracle 加在表上的锁类型

[复制链接]

尚未签到

发表于 2016-7-27 10:04:14 | 显示全部楼层 |阅读模式
  下表是在Oracle文档里里面列出的操作会对表加上什么类型的lock,以及该锁和其他类型的操作的兼容性。

  Table 13-3 Summary of Table Locks
SQL StatementMode of Table LockLock Modes Permitted?RSRXSSRXX  SELECT...FROM table...
  none
  Y
  Y
  Y
  Y
  Y
  INSERT INTO table...
  RX
  Y
  Y
  N
  N
  N
  UPDATE table ...
  RX
  Y*
  Y*
  N
  N
  N
  DELETE FROM table...
  RX
  Y*
  Y*
  N
  N
  N
  SELECT ... FROM tableFOR UPDATE OF ...
  RS(自己测试为RX
  Y*
  Y*
  Y*
  Y*
  N
  LOCK TABLE tableIN ROW SHARE MODE
  RS
  Y
  Y
  Y
  Y
  N
  LOCK TABLE tableIN ROW EXCLUSIVE MODE
  RX
  Y
  Y
  N
  N
  N
  LOCK TABLE tableIN SHARE MODE
  S
  Y
  N
  Y
  N
  N
  LOCK TABLE tableIN SHARE ROW EXCLUSIVE MODE
  SRX
  Y
  N
  N
  N
  N
  LOCK TABLE tableIN EXCLUSIVE MODE
  X
  N
  N
  N
  N
  N
  与v$lock里面LMODE字段对应关系为:
  none:0
  
  RS: row share :2

  RX: row exclusive:3
  S: share:4
  SRX: share row exclusive:5
  X: exclusive:6

  1,select 操作不会加任何锁。
  select * from v$lock where sid=‘当前session的id’ 不会查询到结果。

  2,insert into test values(3,'C');在表示加上RX锁。查看v$lock,select * from v$lock where sid=144看到
  ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
32E29C04 32E29D20 144 TX 458760 685 6 0 36 0
32DC4224 32DC423C 144 TM 54148 0 3 0 36 0
  

  type为TM的为在表上加的锁,这里LMODE为3,对应RX,block为0表示没有阻塞别的session。
  typeweiTX的表示在行上加的锁,这里LMODE为6,对应X,block为0表示没有阻塞别的session。
  如果在两session中同时对同一条记录update,会得到下面的结果:

  ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
32DC4224 32DC423C 144 TM 54148 0 3 0 132 0
32E29C04 32E29D20 144 TX 458760 685 6 0 132 1
32DC42E8 32DC4300 159 TM 54148 0 3 0 6 0
33834450 33834464 159 TX 458760 685 0 6 6 0

  
  SID 144先做,block为1表示阻塞了别的session。SID 159 TX类型的锁LMODE为0,而request为6表示申请X锁,但是没有获得,意味着被阻塞了。

  3,lock table test in ROW SHARE MODE;加的是RS锁。
  ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
32DC4224 32DC423C 159 TM 54148 0 2 0 6 0
  

  执行select name from test where id=3 for update of name;发现和文档说的不一样,看到别人也遇到同样迷惑:
  http://www.itpub.net/thread-1145275-1-1.html : 经过测试和查询发现,实际上在oracle 8i和9i(早版本)中,select .... for update产生的确实是RS锁。
  但是在后来的版本中产生的是RX锁。不过oracle的文档一直到10g都没有更新这一变化。这一点非常坑爹。

  ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
32E29C04 32E29D20 144 TX 589869 828 6 0 6 0
32DC4224 32DC423C 144 TM 54148 0 3 0 6 0

  4,LOCK TABLE test IN SHARE MODE;发现加的是S锁。另外创建index的时候也会加上这个锁,会阻塞更新操作。
  当然如果表上面有更新事务,也是不能建index的。Oracle10G现在可以用create index idx_id_test on test(id) online来创建index而不依赖事务更新的影响。

  ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
32DC4224 32DC423C 144 TM 54148 0 4 0 3 0

  在另一个session 做update test set name='A' where id=3;会发现申请RX锁被阻塞,同时看到v$lock只有两条记录,
  证明该session在申请表级锁被阻塞后,没有继续申请TX的X锁。
  ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
32DC4224 32DC423C 144 TM 54148 0 4 0 42 1
32DC42E8 32DC4300 159 TM 54148 0 0 3 3 0
  将144 session 提交,看到159 session 的LMODE由0变为3,同时获取了一个TX类型的X锁。

  ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
32E0D0AC 32E0D1C8 159 TX 589842 829 6 0 3 0
32DC42E8 32DC4300 159 TM 54148 0 3 0 3 0
  

  Lock table语句只会加表级别的锁,insert,update,delete,select for update会先加表级别的锁,然后还会加行级别的锁。

  
DML StatementRow Locks?Mode of Table Lock  SELECT ... FROM table
  INSERT INTO table...
  X
  RX
  UPDATE table ...
  X
  RX
  DELETE FROM table...
  X
  RX
  SELECT ... FROM table... FORUPDATE OF ...
  X
  RS(自己测试为RX
  LOCK TABLE tableIN ...
  ROW SHARE MODE
  RS
  ROW EXCLUSIVE MODE
  RX
  SHARE MODE
  S
  SHARE EXCLUSIVE MODE
  SRX
  EXCLUSIVE MODE
  X
  

  DDL 锁:当DDL操作进行的时候,它参照的表会加上相应的DDL lock,如一个procedure在编译的时候,不能alter或者drop它引用到的表。当alter一个表正在进行的时候不能drop这个表。

  下面是一些经常用到的和锁相关的SQL:
  查看数据库中session的锁的信息,阻塞了别的进程的block为1,被阻塞的session的id1和id2与造成阻塞的session的id1,id2值相同。
  select sid,type,id1,id2,block,
decode(lmode,0,'None',1,'Null',2,'Row share',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') lock_type,
decode(request,0,'None',1,'Null',2,'Row share',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') reqType
from v$lock order by sid,id1,id2

  查看在哪些对象上有锁发生,xidusn,xidslot,xidsqn值为0的是被阻塞的session
  select rpad(oracle_username,10) o_name,session_id sid,object_name ,xidusn,xidslot,xidsqn,
decode(locked_mode,0,'None',1,'Null',2,'Row share',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') lock_type
from v$locked_object,all_objects where v$locked_object.object_id=all_objects.object_id order by object_name;

  查看被阻塞的SQL语句:
  select st.sql_text from v$sqltext st,v$session sewhere st.address = se.SQL_ADDRESS and se.sid=147 (147是被阻塞的session的sid)

  得到Kill掉阻塞进程的SQL,执行得到SQL可以kill掉session:
  select Distinct 'alter system kill session '||chr(39)||b.sid||','||b.serial#||chr(39)||';'As SQL_KILL,
b.username,b.logon_time from v$locked_object a,v$session b
where a.session_id=b.sid and a.xidusn!=0 order by b.logon_time

  去掉a.xidusn!=0可以得到kill阻塞的和被阻塞的session的SQL。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-250075-1-1.html 上篇帖子: 【转】 oracle exception总结(读书笔记) 下篇帖子: Oracle 10g新特性——选择性编译
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表