MySQL----锁

一、概述

首先为什么需要锁,这是因为在高并发的情况下,如果没有锁,很容易出现脏读,不可重复读,幻读的问题,而锁的合理使用就可以很大程度上避免这些情况,MySQL的锁,在主流的Innodb引擎下,按照锁的粒度分为 全局锁,表级锁,行级锁。全局锁:锁住整个数据库;表级锁:锁住整个表;行级锁:锁住对应的行数据。这些锁,就是MySQL实现不同事务隔离级别的基础。

二、介绍锁

1.全局锁

锁的粒度很大,主要应用场景就是数据库的全局备份,加上全局锁可以保证数据的一致性,保证数据的完整性。加上全局锁后,数据库中还是可以进行select查询的。

语法

加锁:flush tables with read lock;

解锁:Unlock tables;

可以通过使用:

复制代码
mysqldump --single-transation -u+用户名 -p+数据库密码 数据库名 > 文件名.sql;

来实现在不加全局锁的情况下也能完成全局备份。

2.表级锁

表级锁分为3类:

1.表锁

表锁又分为表共享读锁/读锁,表独占写锁/写锁/排他锁,其中加读锁的情况下是所有客户端都只能读不能写,而加写锁的情况下是只有加了写锁的客户端可以读和写,其他客户端都不能进行读写。

语法:

加锁:lock tables 表名 read/write;

解锁:Unlock tables/客户端断开连接。

2.元数据锁

元数据其实就是指数据库中的表结构,当表中有活跃事务时,如果此时进行表结构修改,此时就会因为有元数据锁的存在而失败,元数据锁的存在,就是为了避免DML和DDL语句的冲突。

元数据锁简称MDL,也分为读锁和写锁/排他锁。

在MySQL5.5版本后,当执行DDL语句时,会自动加上MDL读锁,此时不能进行表结构的修改,当执行DML语句时,会自动加上MDL写锁。

3.意向锁

意向锁是用于解决在添加表锁时,需要一行一行的查找是否有活跃事务,从而导致效率过低的情况。意向锁也分为两类:意向共享锁IS,意向排它锁IX。和DML一样,也是自动加锁。

IS:与表锁中的读锁兼容,与表锁中的写锁互斥。由 select ..... lock in share mode;语句触发。

IX:与表锁的读锁和写锁冲突,但是意向锁之间是不互斥的。由 insert,update,delete以及 select....

for update来触发。

我们可以通过以下语句来查看当前数据库中锁的情况:

复制代码
select object_schema,object_name,index_name,
lock_type,lock_mode,lock_data from performance_schema.data_locks;

但是注意一下,在MySQL中,存在隐式提交事务的情况,就是在一个还未提交的事务中进行添加表锁/全局锁时,即使此时存在冲突的意向锁,但是添加表锁或全局锁时会自动提交事务,从而使得意向锁失效,此时仍可以加上表锁。

3.行级锁

行锁在Innodb中是通过对索引上的索引项加锁来实现的,并非是对数据行进行加锁。行级锁是最小粒度的锁,也是并发性能最高的。

分为 行锁,间隙锁,临建锁。

1.行锁

锁定单个行记录的锁,防止其他事务进行update/delete,很显然,它不能解决幻读问题,所以在RR和RC隔离级别中都有。

行锁又分为读锁/共享锁S和写锁/排他锁X,S:允许一个事务去读这一行,但是阻止其他事务来获得X。

X:允许获得锁的事务来更新和查询这一行数据,但是不允许其他事务获得S和X。

不同SQL语句触发的锁

|------------------------------|------|--------|
| SQL语句类型 | 行锁类型 | 获得锁的方式 |
| insert | X | 自动 |
| update | X | 自动 |
| delete | X | 自动 |
| select(普通类型) | 不加锁 | |
| select....lock in share mode | S | 自动 |
| select....for update | X | 自动 |

还有下面两种情况:

1.当针对唯一索引进行检索时,对已经存在的记录进行等值匹配时,会自动优化为行锁。这是因为行锁是和索引息息相关的,如果索引查询出的值唯一且存在,当然会成为行锁。

2.当不通过索引来查询数据时,将会上升为表锁。

2.间隙锁/临建锁

这俩哥们放一块,是因为它们经常相互转换。它们主要是解决幻读问题的,将间隙加上锁,就是让这个区域不能进行insert,在普通索引的情况下,这样有效避免了多次查询结果不一样的情况。间隙锁也是可以共存的。

在RR隔离级别下,Innodb默认使用临建锁。当发生一下情况下时:

1.进行唯一索引的等值查询时,如果给不存在的记录进行加锁时,或优化为间隙锁。将目标索引(如Id)的相邻的两个值之间进行加锁。

2.进行普通索引的等值查询时,因为普通索引可能会重复,所以当向右遍历到最后一个值不满足查询条件时,临建锁会退化为间隙锁。此时就是将目标值到前一个索引和到后一个索引的间隙都加上锁。

3.索引上的范围查询,而且是唯一索引时,会访问到不满足条件的第一个值为止,如果是>的情况,就会将正无穷到条件值都加上间隙锁。

相关推荐
玄同76528 分钟前
SQLite + LLM:大模型应用落地的轻量级数据存储方案
jvm·数据库·人工智能·python·语言模型·sqlite·知识图谱
吾日三省吾码30 分钟前
别只会“加索引”了!这 3 个 PostgreSQL 反常识优化,能把性能和成本一起打下来
数据库·postgresql
chian-ocean31 分钟前
百万级图文检索实战:`ops-transformer` + 向量数据库构建语义搜索引擎
数据库·搜索引擎·transformer
那个村的李富贵1 小时前
解锁CANN仓库核心能力:50行代码搭建国产化AIGC图片风格迁移神器
mysql·信息可视化·aigc·cann
小Tomkk1 小时前
数据库 变更和版本控制管理工具 --Bytebase 安装部署(linux 安装篇)
linux·运维·数据库·ci/cd·bytebase
qq_12498707531 小时前
基于JavaWeb的大学生房屋租赁系统(源码+论文+部署+安装)
java·数据库·人工智能·spring boot·计算机视觉·毕业设计·计算机毕业设计
倒流时光三十年2 小时前
SpringBoot 数据库同步 Elasticsearch 性能优化
数据库·spring boot·elasticsearch
码农小卡拉2 小时前
深入解析Spring Boot文件加载顺序与加载方式
java·数据库·spring boot
怣502 小时前
MySQL多表连接:全外连接、交叉连接与结果集合并详解
数据库·sql
wjhx3 小时前
QT中对蓝牙权限的申请,整理一下
java·数据库·qt