35、lock_1(表锁、事务锁)

lock锁的相关概念

oracle数据库里有一个sga,叫共享全局区(系统全局区),很多进程都可以访问;还有很多的后台进程,也可以访问部分sga区,或者全部sga区

对于同一个buffer,sp1可以访问,sp2也可以访问,这就存在一个并发的问题,所以使用锁来解决共享资源的并发问题

锁一般是个内存结构

latch

提到锁,来回顾一下latch锁;latch是个内存结构:

图解:
sp1以S的方式想遍历其中一个链,要访问数据,就要持有一个latch,然后访问链低下的sql,然后sp2以X的方式想修改同一个链,这个时候,sp2发现这个latch正被sp1所持有着,sp2就不能持有这个latch,这时候sp2就赌,sp1能很快的释放这个latch; 这时候sp2就采取措施(不排队的机制):
1、占着cpu不出来(空转着),等一段时间再来持有这个latch;(这个的前提是:sp1能在非常短的时间内释放latch的情况下)
2、再次尝试持有这个latch(在这期间可能其他进程(sp3)抢先持有,这里sp2没有排队,如果排队的话,sp2就要退出cpu),多次无法持有将释放cpu

latch和mutex的工作机制都一样(不排队)
1、如果无法持有latch,不退出cpu,随机的等待;
2、再次尝试持有(在这期间可能其他进程抢先持有,没有排队),多次无法持有将释放cpu(也就是sleep)

锁(lock)的粒度

图解:
sp1持有着一个链所对应的latch,然后找到一个buffer,找到buffer以后,就释放了latch,然后修改的瞬间pin住这个buffer,修改buffer里面的0行数据,修改完之后就释放pin锁,然后修改完之后没有提交;然后sp2修改第1行数据,虽然在数据块里面,sp1和sp2修改的两行数据在数据块的级别并没有发生冲突,oracle里面,DML的时候,加的是行锁(RX),而不是块锁,所有这里它的粒度就是行锁;只要加上行锁就是排它锁
因为持有latch,pin住一个buffer是一瞬间的事,所有sp1和sp2在latch和pin争用概率是非常小的,也就是粒度很小,产生冲突的可能性很小
然后sp1和sp2修改之后,长时间之内没有提交,没关系,因为他们是修改不同的行,只要事务不提交,行锁就一直在
对于微软的sql server来说,叫页锁

表锁(TM)

oracle数据库也可能加表锁:
一个表,有一百万行,然后sp1修改了表里面的一行,加了一个行锁(RX),事务没有提交;然后sp2过来,要drop掉这个表,删除一个表就会在表级别上加一个X锁,加了一个X锁之后,谁都不能对这个表进行任何操作了;
但是因为sp1没有提交事务,sp2就加不上tm:X锁;还有就是:sp2要加表锁,必须把表里面所有的行锁都释放了才能加上;比如这个表有一百万行,就要一行行去读,看看是不是所有的行锁都释放了,这就需要消耗很大的IO,使我们所不希望的,这时候,oracle就会做几件事:1、sp1修改表里的一行数据,加一个tm:rx表锁,2、然后再在这一行上加一个rx行锁,3、sp2想在表上加一个tm:x表锁,加不上,sp2就不能做DDL了,就能保证sp1顺利的修改完,然后commit,之后行锁和表锁就释放了

还有就是:for update一行数据,表上是tm:rs锁,行上是rx锁

1、修改一个行,就加了一个行锁tm:rx锁
2、要删除drop一个表就在表上加tm:x锁
sp1修改了一个表中的行在一个表上加tm:rx锁,未提交,sp2要drop掉了这个表,要在tm:x,sp2就加不上锁

表锁的关系(兼容性):
tm:rx和tm:x冲突
tm:rx和tm:rx是不冲突
tm:x和tm:x冲突

dml不阻塞select:就是构造CR块,虽然dml修改数据的时候,在行上加了一个行锁,但是select的时候不阻塞,oracle会读undo块,找到修改之前的数据,构造出一个CR块,然后再读取出来;
如果是select......for update(dml阻塞select......for update),这时候就会阻塞了,因为dml修改数据的时候,在行上加了一个rx行锁,for update的时候也要加上一个rx行锁,这时候就加不上了

事务锁

sp1开始一个事务(xid1),修改数据块里面的一行数据,这时候sp2也要修改同一行数据,sp2就发现,这一行上有一个锁标记(没有提交的事务),sp2就不能修改这一行了,这时候,sp2(xid2)这一个事务就跑到xid1后面排队等着,就产生一个事务锁(TX)
然后sp3也要修改这一行数据,sp3发现xid1未提交,xid2排在xid1后面,这时候,xid3就排在xid2后面,由事务等待引起的排队

锁的排队机制:

图解:
sp1以S的方式持有一个锁,sp1所在的队列叫持有者队列;然后sp2、sp3、sp4...以X的方式在等待着sp1释放锁,sp5以S的方式也持有着锁,然后sp5想把S方式转换为X方式,这时候,sp1提交了,提交以后,先考虑转换者队列,sp5就转换为X的方式持有着锁

锁的排队机制,很有可能造成数据库hang住了

posted @ 2024-11-22 14:27  一只c小凶许  阅读(10)  评论(0编辑  收藏  举报