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

[经验分享] DB2锁机制

[复制链接]

尚未签到

发表于 2016-11-13 07:57:17 | 显示全部楼层 |阅读模式
  DB2锁机制
    相比较Oracle来说,DB2的锁机制麻烦了很多,而且这个麻烦带来的不是性能的上升而是下降,
不过如果细致了解的话,只能感慨不愧是数据库理论诞生的公司,在实现数据库理论上比Oracle全面得多。
    Oracle没有实现一般数据库理论里的锁机制,带来的并发性与性能上的提升以及相关的问题上文已经介绍了,
现在来说说几乎完全实现一般数据库理论锁机制的DB2数据库这方面的实现。
    下面的资料来源于IBM资料库DB2和 Oracle的并发控制(锁)比较
    首先是锁是属性,有如下几个基本属性:锁定对象,锁定大小,锁定时间,锁定状态。
锁定对象表示锁定的数据资源,DB2支持对表空间,表,行,索引(大型机里支持对数据页)的锁定。通常考虑表锁与行锁。
锁定大小表示锁定的数据大小。
锁定时间通常由事务的隔离级别控制。
锁定状态就是锁的类型,下面将会介绍。
表 1:DB2支持的表级锁定
名称缩写     全名                                    描述
IN           无意图锁(Intent Node),不需要行锁     拥有者可以读取包括其他事务未提交数据在内的所有数据,但不能对表中的数据作出修改
IS       意图共享锁(Intent Share),需要行锁配合    拥有者可以在拥有相应行上的S锁时可以读取该行的数据,但不能修改数据
IX   意图排他锁(Intent eXclusive),需要行锁配合    拥有者可以在拥有相应行上的X锁时可以修改该行的数据
SIX 共享并且意图排他锁(Share with Intent eXclusive),需要行锁配合   拥有者可以读取表中的任何数据,如果在相应的行上可以获得X锁,可以修改该行。SIX的获取比较特殊,当程序拥有IX锁时请求S锁,或者在已经拥有S锁的时候请求IX锁时产生
S                 共享锁(Share),不需要行锁配合    可以读取表上的任何数据,如果表上被加了S锁,表上的数据只能被读取而不能做出任何修改
U                更新锁(Update),不需要行锁配合    拥有者可以读取表中的任何数据,如果升级为X锁,则可以更改表中的任何数据,该锁是等待对数据进行修改的一种中间状态
X             排他锁(eXclusive),不需要行锁配合    拥有者可以读取或者修改表中的任意数据,如果加上了X锁,除了未提交读事务外,其他程序都不能对表进行任何读取或者修改
Z   超级排他锁(Super eXclusive),不需要行锁配合    该锁一般不是由DML产生,而是由Drop,Alter或者创建删除索引时产生的,加上Z锁后,所有程序(包括未提交读程序)都不能对表进行读取或者修改
具体来说,IS,IX,SIX用于表一级并且需要行锁配合,用于阻止其他程序对表加上排他锁。区别如下:
·  如果一个程序获得表的IS锁,程序可以获得某一行上的S锁用于只读操作,其他程序也可以读取该行,或者对表中其他行作出修改。
·  如果一个程序获得表的IX锁,程序可以获得某一行的X锁用于更改操作,其他程序可以更改或者读取表中其他的行。
·  如果一个程序获得表的SIX锁,程序可以获得某一行的X锁用于更改操作,其他程序只能对表中的其他行进行只读操作。
S,U,X,Z用于表一级,不需要行锁的配合。区别如下:
·  如果程序得到表的S锁,则程序可以读表中的任意数据,同时允许其他程序获得表上的只读锁请求,如果有程序需要更改表上的数据,必须等到S锁释放。
·  如果程序得到U锁,程序可以读取表中任意数据,最终可以通过获得X锁得到对表中任意数据的修改权,其他程序只能读取表中的数据,U锁与S锁的区别在于修改意图,U锁的设计主要是为了避免两个程序在拥有S锁的情况下同时申请X锁导致死锁。
·  如果程序得到表上的X锁,程序可以读或者修改表上任意数据,其他程序无法读或者修改表上的数据。
·  如果程序获得Z锁,程序可以读或者修改表中任意数据,其他程序包括未提交读程序在内不能对表执行读或者修改操作。
IN锁用于表上以允许未提交读这一概念。
DB2支持的行锁如下所示:
名称缩写      全名               需要表锁最低级别                 描述
S           共享锁(Share)         IS                            该行正在被读取,其他程序只能执行读操作
U           更改锁(Update)        IX                            某个程序正在读取并有可能修改该行,其他程序只能读取该行
X           排他锁(eXclusive)     IX                            该行正在被某个程序修改,其他程序不能访问该行
W    弱排他锁(Weak eXclusive)     IX                            一行被插入表后,该行会加上W锁,只有锁的拥有者可以修改该行,与X锁的不同在于该锁与NW锁兼容
NS   下一键共享锁(Next Share)     IS                            拥有者与其他程序都可以读取该行,但不能进行修改,当程序处于RS或者CS隔离级别下时,该锁可以代替S锁
NX  下一键排他锁(Next  eXclusive) IX                            一行的数据被插入到索引或者从索引被删除时,该行的下一行会被加上NX锁,锁的拥有者可以读该行的数据但不能修改。该锁与X锁类似,但与NS锁兼容
NW  下一键弱排他锁(Next  Weak eXclusive) IX                     一行的数据被插入到索引时,该行的下一行会被加上NW锁,锁的拥有者可以读但不能修改该行的数据,与X锁及NX锁类似,但与W锁以及NS锁兼容
默认情况下,DB2总是尝试获取行锁,但可以使用ALTER TABLE语句修改为总是获取表锁,也可以使用LOCK TABLE语句获取表锁。
    以上就是DB2复杂的锁机制,相比较Oracle,DB2没有做任何乐观假设,写必须阻塞读,读必须阻塞写,不然会影响读一致性,这是最正统的数据库理论。
不过对于开发人员来说,这种锁机制就是一个噩梦,在写任何并发性程序之前,首先就是要分析锁,我前后用了两天才理顺DB2里各种锁之间的关系,话说,
如果可以理解上面两张锁阻塞表,估计就可以对DB2锁机制有一个清醒的认识了。
    下面是DB2的事务隔离级别,话说我一直以为只有事务级与语句级隔离级别,直到我看了DB2的事务隔离级别。
    首先是可重复读(RR-RepeatableRead)级别,这一级别怎么说呢,概括一点,这个级别会锁定所有使用到的表,直到事务结束,
保证事务开始一直到结束所可能需求的数据没有任何变化。即事务运行时,其他程序无法修改其所用到的表,
这一级别类似oracle的事务级隔离级别,但Oracle没有锁定表,只是假定没有人去修改所需求的数据。
    下一个是读稳定性(RS-ReadStability)级别,这一级别只锁定真正使用到的行(包括修改的行以及检索到的行),而且可以读到其他已提交事务的数据。
    在往下是游标稳定性(CS-CursorStability)级别,这一级别类似Oracle的语句级隔离级别,锁定的只有修改了的行,可以读取已提交事务的数据。
    最后是未提交读(UR-UncommittedRead)级 别,这一级别如题,可以读到未提交的数据,不过如果修改了数据,则其表现与CS相同,即锁定修改了的行防止别的会话修改。
    四个事务级别,确保所有可能需要的数据不要被人修改->确保已经读取的数据不要被人修改->确保修改的数据不要被别人修改->可以读取别人未提交的数据(修改的数据同样不允许被别的程序修改)。
  下一个讨论的是锁转换。
    当程序向数据库请求它已经加锁的对象上面的锁的时候,数据库会比较对象上现在的锁与所请求的锁的模式,如果所请求的锁级别更高,则把现在的锁升级为请求的锁。
    锁级别比较:
    表锁:IN<IS<S<IX<U<X<Z
    行锁:S<U<X
    有一个特殊例子是,如果持有S锁请求IX锁,或者持有IX锁请求S锁,锁转换结果为SIX锁。
    下面来谈谈DB2里著名的锁升级问题。
    在学Oracle的时候,我从来不知道锁升级这个概念,这是由于Oracle中,锁并不是稀缺资源,没必要把多个锁合并为同一个锁来减少资源占用。
    DB2里有两个参数,LOCKLIST与MAXLOCKS,LOCKLIST表示数据库分配的用来储存锁列表的空间大小,MAXLOCKS表示程序最大允许占用锁列表大小的百分比,
当超过这个百分比的时候,就会进行锁升级,这里我就不发那长长的一大串DB2锁列表计算公式了,只需要知道,DB2会在一个程序锁定过多行的时候,
会把锁定多行变更为锁定整个表。这是一个Oracle里没有的概念,如果从Oracle转为DB2,需要注意。
    最后说说锁等待,这里类似Oracle里的nowait选项,DB2里面有一个参数LOCKTIMEOUT,可以设置这个参数的值来设定遇到锁阻塞后的等待时间,如果超时的话就会回滚语句。
    在DB2的开发建议里,为了实现并行化与数据完整性,有如下几个建议,比较Oracle的类似建议的话,相当有意思。
·  频繁使用commit来使多个用户可以并发地访问数据(Oracle中的建议是尽可能维护业务事务的完整性,而不是切割成小事务)
·  发出commit语句前,关闭CURSORWITH HOLD来确保所有锁都得到释放(Oracle中事务提交或者回滚后自动解锁,不需要其他操作)
·  指定适当的隔离级别。DB2会借助一切机会锁定行,需要不同的隔离级别来协调(Oracle在必要的时候使用事务级隔离,一般只需要语句级隔离级别)
·  适当使用LOCKTABLE语句(尽可能不要使用也很少有必要使用LOCL TABLE语句)
DB2的开发建议还有很多,感兴趣的可以去看看相关资料,与Oracle的开发建议比较相当有意思的。
关于两个数据库锁与并行的介绍就到这里,这篇文章中没有介绍DB2并发性的问题,但其实也没必要介绍,在锁机制部分已经到达并发性的瓶颈,并发性在DB2的锁机制下受到的限制太大了。

运维网声明 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-299460-1-1.html 上篇帖子: DB2 日期 时间 下篇帖子: DB2客户端的配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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