mysql 中的锁

一.锁的介绍

锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,除了传统的计算资源(cpu,ram,i/o)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性,有效性是所有数据库必须解决的一个问题。锁冲突也是影响数据库并发访问性能的一个重要因素。

二.mysql锁的分类

三.mysql中锁的介绍

mysql中的锁,按照锁的粒度分可以分为

全局锁:锁定数据库中的所有表

3.1什么是全局锁

全局锁是针对整个数据库的锁。(我的理解就是一个数据库锁,锁的就是整个数据库)

全局锁里面又分为读锁和写锁。

读锁(共享锁):可以多个线程来读取数据,但是不可写入数据。

写锁(排他锁):不允许其他线程来读取和写入数据。

3.2 应用场景

dump表中所有数据的时候可以加入全局锁,保证数据的一致性。

利用mvcc机制也同样可以实现数据dump,但是不用加锁

3.3 全局锁具体示例

开启读锁:flush tables with read lock;

开启读锁,其他线程不可以 修改操作,阻塞中或报错,查询可以

释放锁后可以修改成功

表级锁: 每次操作锁住整张表。

3.1什么是表级锁

每次操作锁住整张表,开销小,加锁快,不会出现死锁,锁定的粒度大,发生锁冲突的概率最高,并发低。

表级锁里面又分为表共享读锁和表独占写锁。

表共享读锁 :{读锁(共享锁)}:可以多个线程来读取数据,但是不可写入数据。

表独占写锁 : {写锁(排他锁)}:不允许其他线程来读取和写入数据。

3.2 应用场景

1.读密集型的场景

2.写操作不是很密集的场景

3.3 表级锁具体演示

1.执行 alter table;

2.执行drop table 或者 truncate table;

3.lock tables t1 write,t2 read.

以上命令给表1加上写锁,给表2 加上读锁。

开启读锁的效果:

开启写锁

查看 锁的状态:show open tables where in_use > 0;

总结:

在同一个客户端中:

开启表的读锁,不可以进行修改,只可以查询

开启表的写锁,可以修改,可以查询

在不同的客户端中:

开启表的读锁,不可以进行修改,只可以查询

开启表的写锁,不可以修改,不可以查询

开启表的写锁:下面是在不同的客户端中查询阻塞

缺点:并发性能下降。

行级锁:每次操作锁住对应的行数据。

3.1什么是行级锁

锁定的是数据的一行,粒度小,能提供更好的并发性,需要更多的资源。

行级锁里面又分为共享锁和排他锁。

共享锁 :{读锁(共享锁)}:可以多个线程来读取数据,但是不可写入数据。

排他锁 :{写锁(排他锁)}:不允许其他线程来读取和写入数据。

3.2使用场景

1.高并发

2.遇到事物的操作

查看那些是行级锁:select * from performance_schema.data_locks;

行级锁, 如果不在事物中执行,语句执行完毕,锁释放

在事物中执行,在没有commit之前这个排他锁一直存在

案例演示:

执行排他锁(写锁):select ... for update

第一个窗口开始事物,设置排他锁

第二个窗口可以查询,不可以修改

执行共享锁(读锁):select......lock in share mode

第一个窗口开启 事物,开启共享锁

第二个窗口 可以查询,不可以修改

总结: 开启行的共享锁和排他锁不同窗口都可以读,不可以修改。

造成的问题:

  1. 在多个事物当中会发生死锁(事物可以理解为多个线程)。

2.锁升级 (锁定多行后,发现还不如锁定整个表)

3.不同的事物隔离级别会影响锁的性能和行为,根据具体的场景来调整事物隔离级别。

按照锁的状态范围分类

共享意向锁

排他意向锁

意向锁个人理解就是一个"信号标记性能锁",以前要去一行一行遍历表中的数据,判断是否存在行锁,现在去看一下,信号标记就可以。

概念 :意向锁是表锁,为了协调行锁和表锁的关系,支持多粒度(表锁与行锁)的锁并存。

作用:当有事物(线程)A有行锁时,mysql会自动为该表添加意向锁,事物(线程)b如果想申请整个表的写锁,那么不需要遍历每一行判断是否存在行锁,而直接判断是否存在意向锁,增强性能。

查看那些是行级锁:select * from performance_schema.data_locks;

案例演示:

1.第一个窗口开启事物,并开启排他锁

2.查看当前的锁

查看LOCK_TYPE,LOCK_MODE 第一个是表级的意向排他锁 lX显示为排他锁

X是排他锁 LOCK_TYPE显示为 record 行级别。

3.在另一个窗口中添加写锁是阻塞状态:

总结:

间隙锁(范围锁)

和临界锁类似,是一个范围锁。两个值之间的空隙加锁。

演示示例:

1.查看当前的表结构

2.开启事物设置间隙锁(查询的id一定要不存在)

3.开启一个窗口,看到 id < 7的可以正常插入,id > 7 < 10的数据插入失败

临界锁

什么是临界锁 next-key 可以理解为一种特殊的间隙锁,也可以理解为一种特殊的算法。通过临界锁可以解决幻读的问题。每个数据行上的非唯一索引列上都会存在一把临界锁,当某个事物持有该数据的临界锁时,会锁住一段左开右闭区间的数据。innodb中行级锁是基于索引实现的,临界锁只与非唯一索引列有关,在唯一索引列上不存在临界锁。(把下面的演示做一遍才理解的更深刻)

演示案例

第一个窗口开启事物设置,设置临界锁为2000,表里面已经有1000的数据,

所以区间是1000-2000

第二个窗口在插入大于1000 小于 2000范围的数据是阻塞状态,插入不进去

发现插入小于1000也处于阻塞状态,拉拉了。一定要是 (**每个数据行上的非唯一索引列上都会存在一把临界锁)**才会有临界锁

mysql锁总结:

|------------|--------------------------------------|-----------------------------|
| mysql中锁的分类 | 可以多事物(线程)操作 | 不可以多事物(线程)操作 |
| 数据库锁(全局锁) | 读锁 | 写锁 |
| 表级锁 | 共享 lock tables t2 read. | 排他 lock tables t1 write; |
| 行级锁 | 共享锁 select ..... lock in share mode; | 排他锁 select..... for update; |

共享锁 ,读锁 都可以理解为 共享读锁

排他锁 ,写锁 都可以理解为 排他写锁

间隙锁是innodb引擎为了解决幻读,临界锁也是为了解决幻读。

参考:阿里一面:MySQL锁你了解吗?说一下什么是mysql间隙锁?招架不住啊。。_哔哩哔哩_bilibili

相关推荐
松涛和鸣14 小时前
72、IMX6ULL驱动实战:设备树(DTS/DTB)+ GPIO子系统+Platform总线
linux·服务器·arm开发·数据库·单片机
likangbinlxa15 小时前
【Oracle11g SQL详解】UPDATE 和 DELETE 操作的正确使用
数据库·sql
r i c k15 小时前
数据库系统学习笔记
数据库·笔记·学习
野犬寒鸦15 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
IvorySQL16 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·16 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德16 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫17 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i17 小时前
完全卸载MariaDB
数据库·mariadb
纤纡.17 小时前
Linux中SQL 从基础到进阶:五大分类详解与表结构操作(ALTER/DROP)全攻略
linux·数据库·sql