MySQL 学习

MySQL 中的锁

全局锁

全局锁是将整个数据库都锁上,一般用于备份数据库。整张表都属于只读状态。如果支持可重复读的级别,可以在备份之前生成一份 ReadView,用这个 ReadView。

表级锁

表锁

表锁有读锁和写锁,读锁就是让这张表大家都可以读,但是没有人可以写。写锁就是只有当前这个线程可以读或写,别的线程读和写都不行。表锁除了锁住了表,其实也把自己线程给锁住了。比如执行 lock tables t1 read, t2 write 这条语句,当前线程在解锁之前只能读表 t1,写表 t2,不允许做其他操作。

元数据锁

元数据锁也称 MDL 锁,我们不需要显式地调用 MDL 锁,因为操作数据库的时候会自动加上 MDL 锁。MDL 锁分为读锁和写锁。MDL 读锁就是在增删改查的时候,不允许其他线程读。MDL 写锁就是在对表进行修改时,不允许其他线程读。

由于 MDL 锁存在写优先级 且有队列等待机制,一个长事务可能会拖死整个数据库:

事务 A:开启长事务,做了一个慢查询(持有 MDL 读锁)。

事务 B:想改字段名(申请 MDL 写锁),因为 A 没结束,B 只能排队。

后续所有请求 :新的 SELECT 请求虽然也是读锁,但因为 B 在排队且优先级高,导致后面所有的请求全都在 B 后面排队。

后果:数据库连接数瞬间爆满,整个系统瘫痪

意向锁

这是 InnoDB 引擎为了让表锁和行锁共存而设计的一种"旗语"。当你想给某一行加锁时,InnoDB 会自动先给表加一个意向锁:

意向共享锁 (IS):打算给行加 S 锁。

意向排他锁 (IX):打算给行加 X 锁。

它的意义在于:如果有人想给整张表加"写锁",他不需要去逐行检查有没有行锁,只需要看一眼表上有没有"意向锁"的标志位即可。

AUTO-INC 锁

Auto-Inc 锁是用来保证生成的主键严格自增的。它并不在整个事务期间都上锁,而是执行完插入语句之后就会立刻释放锁。

由于AUTO-INC 锁会等到所有数据都插入完成之后才释放锁,如果有大量数据插入速度会很慢,所以 InnoDB 提供了一种轻量级的互斥锁。

轻量级互斥量(Mutex)不再锁定整张表,它只锁定**"自增计数器"这个数字本身**。

执行逻辑:

申请:事务 A 说"我要 5 个 ID"。

获取:它迅速去访问内存中的计数器(通过 Mutex 保证同一时刻只有一个线程在拨动数字)。

分配:计数器从 100 变成 105,把 101-105 分给事务 A。

释放:重点来了! 只要 A 拿到了这组数字,Mutex 就会立刻释放,不需要等待 A 的插入操作完成。

行级锁

Record Lock

RecordLock 锁的是单独的一条记录。

Gap Lock

幻读就是读了两次数据库,前后数据多了或者少了。 MySQL 中解决幻读的方法有两个:第一个是通过 MVCC 的快照机制,采用可重复读级别,在事务开始前获得一个快照,后面一直用这个快照。第二个是通过Next-key lock,让你根本没办法插进去新的数据。

Next-key Lock

插入意向锁

前面的意向锁,你要插入一行,意向锁会对这个表做标记,告诉数据库这个表现在有人在用,就不需要一行行地去扫描了。插入意向锁不是意向锁。下面是一个例子。

相关推荐
蓝祁子yoky1 小时前
Qt学习日记 Day13:网络编程(一)-TCP基础与Socket实战
网络·qt·学习
架构师伯子明2 小时前
Ros 学习十三:IK Demo
学习
小羊没烦恼!2 小时前
关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁
java·服务器·网络·学习·负载均衡
幼儿园蛋小黄2 小时前
从 STM32N647 的 AI 部署入门嵌入式:一条可落地的学习路线
人工智能·stm32·学习
Y.9994 小时前
电脑黑屏只有鼠标能动
学习
架构师伯子明4 小时前
FFmpeg C++学习(一):编译和demo
开发语言·c++·学习
叼烟扛炮4 小时前
[LangChain] 学习笔记(02):LCEL 链式调用与动态模型配置实战
服务器·开发语言·网络·笔记·学习·langchain
程序员梅雨4 小时前
【从零开始学习数据仓库 | 第二篇】: 拉链表 & 数仓分层
大数据·数据仓库·学习
一木 之林5 小时前
Dify学习笔记 04 · 检索底座:Embedding、Rerank与向量数据库(第46-54集)
笔记·学习·embedding·dify
芯思路5 小时前
STM32开发学习笔记之十【AI部署】
笔记·stm32·学习