数据库锁定机制简单来说,就是数据库为了保证数据的一致性,而使各种共享资源在被并发访问变得有序所设计的一种规则。
MySQL 数据库由于其自身架构的特点,存在多种数据存储引擎,每种存储引擎的锁定机制都是为各自所面对的特定场景而优化设计,所以各存储引擎的锁定机制也有较大区别。
lock tables 表名.. read; -- 是指可以对多张表加锁
lock tables 表名... write; -- 可以对多张表加独占锁
unlock tables; -- 释放锁,客户端短裤连接
2.间隙锁(Gap Lock):锁定索引记录间隙(不含该记录),确保索引记录间隙不变,防止其他事务在这个间隙进行insert,产生幻读。在RR隔离级别下都支持。
3.临键锁(Next-Key Lock):行锁和间隙锁组合,同时锁住数据,并锁住数据前面的间隙Gap。在RR隔离级别下支持。
InnoDB实现了以下两种类型的行锁:
1.共享锁(S):允许一个事务去读一行,阻止其他事务获得相同数据集的排它锁。
2.排他锁(X):允许获取排他锁的事务更新数据,阻止其他事务获得相同数据集的共享锁和排他锁。
间隙锁(Gap Locks)
间隙锁是封锁索引记录中的间隔,或者第一条索引记录之前的范围,又或者最后一条索引记录之后的范围。
产生间隙锁的条件(RR事务隔离级别下;)
1). 使用普通索引锁定;2). 使用多列唯一索引;3). 使用唯一索引锁定多行记录。对于使用唯一索引来搜索并给某一行记录加锁的语句。只会产生记录锁,不会产生间隙锁。
打开间隙锁设置
查看是否启用间隙锁
show variables like 'innodb_locks_unsafe_for_binlog';
[mysqld]
innodb_locks_unsafe_for_binlog = 1
2.对于查找某一范围的查询语句,会产生间隙,如:WHERE ID BETWEEN 5 AND 7 FOR UPDATE;
3.在普通索引列上,不管是何种查询,只是加锁,都会产生间隙锁。
临键锁(Next-key Locks)
临键锁,是记录锁与间隙锁的组合,它的封锁范围,既包含索引记录,又包含索引区间。
临键锁的主要目的,也是为了避免幻读(Phantom Read)。如果把事务的隔离级别降级为RC,临键锁则也会失效。
select * from Table where id=2 lock in share mode;
commit 或 rollback;
select ... for update;
●大事务拆小事务。大事务更倾向于死锁,如果业务运行,将大事务拆小。
●在同一个事务中,尽可能做到一次锁定所需所有资源,减少死锁概率。
●降低隔离级别。如果业务允许,将隔离级别调低也是比较好的选择,比如将隔离级别从RR调整为RC,可以避免很多原因gap锁造成的死锁。
●为表添加合理的索引。可以看到如果不走索引将会为表的每一行记录添加上锁,死锁的概率大大增加。
2.合理设计索引,尽量缩小锁的范围
3.尽可能减少索引条件及索引范围,避免间隙锁
4.尽量控制事务大小,减少锁定资源量和时间长度
5.尽可使用低级别事务隔离(需要业务层面满足需求)
免责申明:
本文系转载,版权归原作者所有,如若侵权请联系我们进行删除!
《数据治理行业实践白皮书》下载地址:https://fs80.cn/4w2atu
《数栈V6.0产品白皮书》下载地址:https://fs80.cn/cw0iw1
想了解或咨询更多有关袋鼠云大数据产品、行业解决方案、客户案例的朋友,浏览袋鼠云官网:https://www.dtstack.com/?src=bbs
同时,欢迎对大数据开源项目有兴趣的同学加入「袋鼠云开源框架钉钉技术群」,交流最新开源技术信息,群号码:30537511,项目地址:https://github.com/DTStack