锁与阻塞学习笔记

一、锁类型 按类型分,可分为排他锁(X锁)和共享锁(S锁)。 排他锁:如果一个对象被加了X锁,在这个锁被采用commit或rollback释放之前,该对象上不能施加任何其它类型的锁。 共享锁:如果一个对象被施加了S锁,该对象上可以再加其他类型的S锁,但是,在该锁释放之前,该对象不能被加任何其它类型的X锁。 按照锁定的对象来分,可分为DML锁、DDL锁与内存锁(latch)。[@more@]一、锁类型 按类型分,可分为排他锁(X锁)和共享锁(S锁)。 排他锁:如果一个对象被加了X锁,在这个锁被采用commit或rollback释放之前,该对象上不能施加任何其它类型的锁。 共享锁:如果一个对象被施加了S锁,该对象上可以再加其他类型的S锁,但是,在该锁释放之前,该对象不能被加任何其它类型的X锁。 按照锁定的对象来分,可分为DML锁、DDL锁与内存锁(latch)。 1、DML锁 1)TX锁,事务锁,当一个事务数据更新,如insert、update、delete、merge或者select … for update的时候,会对所操作的行产生一个TX锁,直到这个事务被commit或rollback。 Oracle的TX锁是行级别的,但可以一次性锁定多行,行锁的标志被记录在数据块上。 在数据行上不存在S锁。 2)TM锁,可以是手工的lock命令,或者是DML及select … for update的时候加在表对象上的锁,可以防止其他对象对表结构加X类型的锁(如变更表结构、truncate、drop等)。 TM锁分五个级别,对应于v$lock中的LMODE字段: 2(RS,row share)、3(RX,row exclusive)、4(S,share)、5(SRX,share row exclusive)、6(X,exclusive)。 DML操作表数据的时候,是先加TM锁,如果能加上,才再加TX锁。 例如:DML和select … for update都是先在表上加RX锁,然后再在修改的数据行上加TX锁。 TM锁除了DML语句外,还可以通过lock table命令来加锁: Lock table table_name in row share mode; -- 加RS锁,只不允许X锁,和同一行上的RX Lock table table_name in row exclusive mode; -- 加RX锁,允许不同行的RS和RX锁 Lock table table_name in share mode; -- 加S锁,允许RS和S锁 Lock table table_name in share row exclusive mode; -- 加SRX锁,只允许RS锁 Lock table table_name in exclusive mode; -- 加X锁,都不允许 DML和select for update加RX锁允许RS和RX锁再存在,所以一个表上面可以加多个RX锁,可以并发DML。 在一个会话中,TX锁一般只有一个,因为只有一个事务,TX是对应的事务锁;而TM锁可以有多个,因为在一个会话中,可能更新多个表。 2、DDL锁 Oracle的DDL语句,类似于下面的伪代码: Begin commit; DDL语句 commit; Exception when others then rollback; end; 因为DDL总是提交,所以,操作DDL的时候,需要注意是否不小心提交了本会话的其他事务。 (小心DDL之前的未提交DML事务在DDL回退时被自动提交。) eg: Session1 Delete from a where a=1; Session2 Delete from a; Session1 Truncate table a; ERROR at line 1: ORA-00054:resource busy and acquire with NOWAIT specified DDL锁主要有两类: 1)X类型的DDL,排他类型的DDL,多发生在truncate,drop,alter table drop/add/modify等绝大部分DDL上面。这样的语句也会在操作期间给表加一个X(独占)类型的TM锁。 2)S类型的DDL,如online操作,会在表上加一个RS类型的TM锁,因为RS类型的锁是可以再加RX锁的,所以online操作不阻塞DML语句。 Eg1: Alter table test drop column owner;期间,在另一个会话上查询这个会话的锁类型,发现这个DDL在表上加的TM锁是级别为5的SRX锁,这个级别的锁只能允许最低级别的RS锁在表上出现,即会阻止DML和DDL操作。 eg2: 会话1: Create index ind_test1 on test(object_id); 会话2: Select sid,type,id1,id2,lmode from v$lock where sid=1005;可看到,建索引时在TEST表上加的是级别为4的S锁,这个锁也阻塞RX锁,影响DML的正常使用。 如果采用online方式创建索引,则不同: 会话1: Create index ind_test1 on test(object_id) online; 会话2: Select sid,type,id1,id2,lmode from v$lock where sid=1005;可看到,在online建索引的时候,在TEST表上加的是最低级别的RS锁(级别为2),允许建索引的同时DML操作。 以online方式创建索引时,将产生一个中间的日志表,在其上加级别为4的TM锁,而在主表上加级别为2的RS锁,故它对主表的操作没有任何影响。 3、内存锁(Latch) 是一个运行在内存中,保护内存结构的轻量级的锁。如果处理得不好,将耗费大量的cpu来管理内存锁,较为典型的就是硬分析。 Runstats_pkg包,用来对比两次不同的执行所耗费的资源。 二、阻塞 1、TX阻塞 会话1: Select * from test where a=100 for update; 会话2: Update test set b=100 where a=100;--被阻塞 查看这两个会话的锁类型: Select sid,type,lmode,request,block from v$lock where sid in(150,160); sid TY LMODE REQUEST BLOCK ----------------------------------------------------- 150 TX 0 6 0 160 TM 3 0 0 150 TM 3 0 0 160 TX 6 0 1 2、TM阻塞 会话1: 用lock table table_name in share mode来模拟表创建索引。 Lock table test in share mode; 会话2: Update test set b=100 where a=100; 阻塞。 3、Latch阻塞 TX与TM阻塞不会阻塞select语句,因为select语句并不在表上加任何锁,所以也不会被阻塞,而且,根据oracle特有的一致性读规则,select将保证获得一致性的数据。 而latch却可以阻塞select,如Library cache lock等待,典型的例子就是大表建约束: 在一个大表上面创建一个唯一/主键约束,此时oracle会自己创建索引。但是因为创建约束导致oracle的这个表对象的属性变化,而如果创建索引的时间又很长,将导致select语句阻塞在library cache lock上,不能获得表的句柄(handle)信息,所以不能分析该语句,更不用说执行(select)该语句了。 会话1:(SID=160) Select count(*) from test where rownum

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

转载于:http://blog.itpub.net/86728/viewspace-1008882/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值