MySQL读写锁(元数据锁、意向锁、行锁、间隙锁、临键锁)

目录

一、概述

锁机制用来保证多线程(同一事务、不同事务之间)并发访问同一行数据引发的数据一致性问题。

MySQL的锁分为以下三类:

  • 全局锁:线程串行访问数据库
  • 表级锁:在一张表上加锁,线程串行访问该表
  • 行级锁:在一行记录上加锁,每次操作锁住对应的行数据

二、全局锁

对整个数据库实例加锁,加锁后其他线程可以读数据库内容,但是创建表、增删改操作会被阻塞

全局锁一般用于备份整个数据库时 使用,防止涉及多表更新的业务 在备份文件中出现数据不一致问题。

数据库备份过程:

  1. 添加全局锁:flush tables with read lock;
  2. 执行备份:mysqldump -h服务器IP地址 -u用户名 -p密码 数据库名 > 备份保存绝对路径D:/.../xxx.sql
  3. 释放锁:unlock tables;

备份后数据会发生变化,所以可以参考redis将备份后执行的MySQL指令记录下来,便于数据库宕机后使用指令日志和备份文件恢复数据。
全局锁对于备份主从数据库存在的问题:

  • 备份主库则写操作相关的业务会全部阻塞。
  • 备份从库则备份期间无法执行主库同步来的数据,导致主从延迟。

在InnoDB中通过添加-single-transaction参数可以实现不加锁的一致性数据备份。(原理是快照,应该是MVCC的内容)

三、表级锁

表级锁分为三类,本质都是基于读写锁

  • 表锁 :对整张表加锁,解决DML之间的并发冲突
  • 元数据锁MDL :解决DML和DDL的并发冲突
  • 意向锁 :解决表锁和行锁的冲突

1.表锁

表锁又分为read lock和write lock两类。这里和缓存更新的读写锁原理一样。

  • 加锁:lock tables 表名... read/wirte;
  • 释放锁:unlock tables; 持有锁的线程断开连接会自动释放锁。

1.1 read lock

表共享读锁,又叫读锁,共享锁。执行读操作业务的线程申请读锁或不加锁 ,可以被多个读线程同时持有,持有锁的线程可以对该表进行读操作,但所有线程不能进行写操作

如果有多个线程都持有同一个表的读锁,那么只要还有一个线程持有读锁,写操作就会被阻塞,直到所有读线程都释放锁,因此写线程会有饥饿问题。

  • 在任何隔离级别下,select lock in share mode、update、delete、insert操作,共享锁和排它锁在事务提交时释放
  • 在serializable隔离级别下,普通的select操作会自动添加lock in share mode后缀。
  • 在读未提交、读已提交、可重复读隔离级别下,普通的select操作不会加锁

1.2 write lock

表独占写锁,又叫写锁,排它锁,独占锁。执行写操作业务的线程申请写锁,写锁只能由一个线程持有,期间其他线程的增删改查都会被阻塞,直到写线程释放锁。

2.元数据锁

元数据锁是为了防止DML和DDL冲突

MySQL会为执行增删查改操作的表自动加元数据共享锁 ,期间不允许表结构被修改,直到所有线程都不持有共享锁。当要alter table 修改表结构时会自动对表加元数据排它锁,期间不允许任何的增删查改操作。

3.意向锁

意向锁是为了解决行锁与表锁的冲突,加表锁前不必逐行遍历判断是否有行锁,直接判断意向锁即可。

读线程在加行锁时 会额外将意向锁设为 意向共享锁,写线程在加行锁时 会额外将意向锁设为 意向排它锁。

读线程加表锁前判断意向锁是共享锁,那么可以加表锁。意向锁为空时也可以加表锁。其他任何情况都不能加表锁。

四、行级锁

因为InnoDB中的数据存储结构是索引,所以行锁是对记录在索引B+树上的索引项加锁,而不是对记录加锁。

  • 行锁:锁定单个索引项 ,防止其他线程对该项进行update和delete,应用在读已提交、可重复读 事务隔离级别。

  • 间隙锁:锁定索引项之间的间隙 ,确保索引记录之间的间隙不变,防止其他线程在间隙进行insert,解决幻读 ,应用在可重复读 事务隔离级别。

  • 临键锁:同时锁定单个索引项和索引项前的间隙 ,应用在可重复读 事务隔离级别。

1.行锁

行锁实现还是读锁和写锁。在InnoDB中,对insert、update、delete加排它锁,对select不加锁。 其中,排它锁解决了脏读问题,MVCC解决了不可重复读和幻读问题。

2.临键锁

InnoDB在可重复读 事务隔离级别下使用的是临键锁防止幻读

  • SQL执行时若针对unique索引 的B+树进行搜索且是等值匹配 时会降级为行锁
  • SQL执行时若针对unique索引 的B+树进行搜索且是等值匹配 ,且索引项不存在 时会降级为间隙锁。例如索引项1,2,4,5,此时对索引项3进行增删改会先将2,4之间的间隙上锁。
  • SQL执行时若针对非unique索引 的B+树进行搜索且是等值匹配 ,且索引项不存在 时会降级为间隙锁。例如索引项1,2,2,4,5,此时对索引项3进行增删改会先将2,4之间的间隙上锁。
  • SQL执行时若不走任何索引,那么会升级为表锁。
相关推荐
阿坤带你走近大数据20 分钟前
ORACLE里length和lengthb函数的异同点分别是
数据库·oracle
航Hang*36 分钟前
第3章:复习篇——第1节:创建和管理数据库---题库
数据库·笔记·sql·学习·期末·复习
机器视觉知识推荐、就业指导1 小时前
Qt 小技巧:如何用 Q_PROPERTY 管理属性
服务器·数据库·qt
R-sz1 小时前
如何将json行政区划导入数据库,中国行政区域数据(省市区县镇乡村五级联动)
java·数据库·json
闲人不梦卿1 小时前
数据库安全和事务以及sql
数据库·sql
@22061 小时前
银河麒麟系统离线环境下用docke方式部署(Postgres、Nginx、Redis、JDK)
运维·数据库·redis·nginx
阿坤带你走近大数据2 小时前
oracle的varchar2(200)和mysql的varchar(200) 最大支持的字节数和字符数都一样吗
数据库·mysql·oracle
马克学长2 小时前
SSM新能源汽车销售管理系统gooct(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·汽车·ssm框架·新能源汽车销售管理·车辆库存
小蜗的房子2 小时前
Oracle 19C RAC Public IP单网卡改为bond模式操作指南
运维·网络·数据库·sql·tcp/ip·oracle·oracle rac
不吃饭的猪2 小时前
nacos默认数据库密码查询
数据库