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

插入意向锁

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

相关推荐
李日华大战鸡红9 小时前
FOC状态空间方程模型推导(学习记录)
python·学习·线性代数
kkkkkkkkkk_Z11 小时前
新手自学嵌入式 | 学习日记:异常与中断基础、i.MX6ULL裸机开发环境搭建、GPIO模块与点灯原理
学习
m4Rk_12 小时前
【论文阅读】Agent 记忆机制(94):MemGen——在推理过程中动态生成并织入潜在记忆
论文阅读·人工智能·学习·开源·github
晓德12 小时前
0、LLM大模型安全学习系列(启)
学习·安全
Titan202413 小时前
MySQL索引学习笔记
笔记·学习·mysql
JWASX13 小时前
Java 转 go 学习 - kitex(5)
学习·golang
AOI小白新手上路13 小时前
VDMamba·AutoDL 复现笔记 · 学习笔记
笔记·学习
~kiss~13 小时前
LangGraph ~ 为图添加跨线程持久化
学习
xianrenli3815 小时前
水肺潜水学习
学习
凌云若寒16 小时前
BarTender提示#807错误:无法在拥有其他许可证的Licensing Service上激活节点锁定的 Professional 版许可证 的解决办法
运维·服务器·前端·学习·软件需求