MySQL的行级锁
author:陈镇坤27
创建时间:2021年11月12日00:30:06
编辑时间:2021年11月22日20:35:45
文章目录
——————————————————————————————
二阶段锁协议
问:介绍下Innodb的行锁。
答:innodb引擎支持行级锁,同样是共享读、排他写,该锁遵循二阶段锁协议。
所谓二阶段锁协议,是指在事务中,需要加锁时才加锁,提交事务时才释放。
因此在使用行级锁时,尤其注意要将会争用行级锁资源的操作放到接近事务结束位置,最大程度减少锁等待。
问:解释下死锁。
答:已知二阶段锁协议的定义,当两个事务同时启动,并相互等待对方的一个资源做释放的时候,就会陷入死锁。
问:有个场景,频繁更新一条数据的时候,CPU急速飙升,但事务又没解决几个,是什么原因导致的?用行级锁相关的内容解释下。
答:应该是过多的死锁检测导致的。对同一行数据进行更新时,在默认情况下,进入锁等待的线程会检测自己是否陷入死锁,时间复杂度为O(n),短时间的高并发会导致CPU飙升,例如1000个线程则死锁检测次数为1000^2次方。
问:一般怎么解决死锁?
答:
1、锁等待超时;
show variables like 'innodb_lock_wait_timeout'
2、死锁检测;
show variables like 'innodb_deadlock_detect'
一般通过死锁检测。
问:什么是死锁检测?
答:一个线程进入锁等待后,要检查锁住F的线程R是否被锁,如果无,则没有死锁,如果R被D锁,则继续检测锁住R的D线程是否就是F,如果否,则继续检测该线程,直到临界条件为闭环F或者没有被锁。如果形成闭环,则是判定发生死锁。
问:针对更新热点数据时产生的死锁检测问题,有什么方案可以处理?
答:
从客户端层面限制,但如果应用客户端过多,这个方法不奏效;
从并发度层面限制,但要求高:了解MySQL源码或者会相关中间件;
从关系设计层面限制,将热点数据进行拆分;
从代码规范层面:尽量减少产生锁等待;
问:假如删表一万行数据,下面哪几种方式比较好?
1、一个连接一次性执行删除一万行
2、一个连接,二十次循环执行删除500行
3、二十个连接,一次性同时执行删除500行
答:第二个好:减少单语句锁的长时间占用,和大事务。无锁冲突。