Mysql中的锁

文章目录

MySql中的锁

锁是协调多个进程或者线程访问某一共享资源的机制。数据库是用来保存数据的,自然其中也有锁机制。对整个数据库加锁,对某一整张表加锁,对某一记录行加锁,对应了锁粒度的从粗到细。

全局锁

全局锁粒度最大。对整个数据库加锁,加锁之后,整个数据库就处于只读状态,只能读取,不能修改(DML、DDL语句都不能再使用)。主要用于全库的数据备份操作时使用到。

无锁备份: 加了全局锁之后,所有对数据库的更新操作都会失败。这样效率就很低,那么我们能不能进行无锁实现备份呢?有方法,使用

sql 复制代码
mysqldump --single-transaction 

参数进行备份,新增--single-transaction ,利用到了Innodb引擎中的MVCC机制,在不加全局锁的情况下,在备份开始的时候自动发起一个事务,在这个事务中执行所有的select语句,这个select语句就只会去读这个事务开始时的数据快照。

表级锁

表锁

表共享读锁: 加了读锁后,所有的读操作都不受影响,当前客户端的写操作会直接失败,其他客户端的写操作会阻塞等待读锁释放。

表独占写锁: 加了写锁后,当前客户端既可以读也可以写,其他所有客户端都不能读也不能写。

元数据锁

元数据锁,meta data lock(MDL),是在访问一张表的时候自动加上的,不需要手动加上。

在对表进行增删改查(DQL、DML)的时候,会自动为这个表加上MDL读锁(共享);

在对表结构(DDL)进行变更的时候,会自动为这个表加上MDL写锁(排他)。读锁之间兼容,写锁和写作、读锁之间都互斥。

注:DDL语句不是事务性的,不能被事务控制,这种语句会被一个隐式事务(这条语句结束后会自动提交事务)控制,如果它在一个事务中,会在执行完后提交这个事务之前所有的操作。DQL和DML语句都是事务性的。

意向锁

如果使用一个DML语句对一个表中的其中一行数据进行修改,那么会对这行数据加上行锁,那么如果这个时候另外一个线程想要来给这个表加上表锁的话,就会扫描整个表的所有行记录,看是否有行锁,这样扫描整个表效率太低,所以就有了意向锁的出现。

有了意向锁之后,线程在使用DML语句加上行锁的时候,也会对整个表加上一个意向锁,这样别的线程再来上表锁的时候,就会先去检查与这张表的意向锁的兼容情况,如果兼容的话,才会加上表锁,如果不兼容,就会阻塞。有了意向锁之后就不用逐行检查了。

意向共享锁: 由语句select ... lock in share mode 添加。与表锁的共享锁兼容、与表锁排他锁互斥。

意向排他锁: 由insert、update、delete、select ... for update 添加。与表锁的共享锁及排他锁都互斥。

意向锁之前不会互斥。

行级锁

以下加锁规则都是在RR(REPEATED READ)隔离级别下。RC隔离级别的加锁机制就有所不同。

锁是加在索引上,行级锁分为 行锁间隙锁临健锁(next-key lock)

  • 唯一索引+等值查询的记录,那么对应记录加行锁。
  • 唯一索引+等值查询的记录不存在,加间隙锁(Gap Lock),锁住插入位置所在的间隙。
  • 普通索引 + 等值查询时,若该值对应多条记录(非唯一),则 InnoDB 会对所有命中的记录加记录锁,并可能对相邻的间隙加 Gap Lock,以防止插入相同索引值的新记录,从而避免幻读。
  • 任意索引 + 范围查询,加 Next-Key Lock,从首个命中记录起,锁住记录和之间所有间隙。

行锁

行共享读锁: select ... lock in share mode 语句会加上,给查询的这个记录的索引加上行共享读锁。

行排他写锁: select ... for update, update, insert, delete语句都会加上,其它线程再获取读锁或者写锁时都会被阻塞。

间隙锁

间隙锁锁住的是一个间隙,会在行锁的基础上升级来,当唯一索引而且等值查询的记录不存在时,就会把行锁升级为间隙锁,在这个不存在的记录两边存在的记录之间加上间隙锁,不允许再插入新纪录。

临健锁

临健锁是行锁+间隙锁的组合,将当前行记录加上锁并且锁住与这行记录相邻的一个间隙。是[a,b)或者(a,b]的意思。而间隙锁两边是开区间。

相关推荐
安审若无13 分钟前
Oracle 打补丁指南
数据库·oracle
樱花的浪漫36 分钟前
Cuda reduce算子实现与优化
数据库·人工智能·深度学习·神经网络·机器学习·自然语言处理
啊森要自信43 分钟前
【MySQL 数据库】MySQL用户管理
android·c语言·开发语言·数据库·mysql
kkkkk0211061 小时前
Redis八股
数据库·redis·缓存
Liu1bo2 小时前
【MySQL】表的约束
linux·数据库·mysql
胖胖的战士2 小时前
Mysql 数据库迁移
数据库·mysql
星光一影2 小时前
大型酒店管理系统源码(多酒店版)
mysql·php
czhc11400756632 小时前
LINUX1012 mysql GLIBC安装
数据库·mysql
小草儿7992 小时前
gbase8s之.net8连接8s之mysql模式(windows)demo
windows·mysql·.net
DemonAvenger2 小时前
深入 Redis Hash:从原理到实战,10 年经验的后端工程师带你玩转哈希结构
数据库·redis·性能优化