当前位置: 首页 > news >正文

(小林coding)MySQL有哪些锁,他们各自的特点是什么

MySQL有哪些锁

全局锁

全局锁怎么使用?
执行

flushtableswithreadlock

执行后,整个数据库就处于只读状态。其他线程就无法执行

  • 对数据的增删改查操作(insert,delete,update)
  • 对表结构的更改操作(alert table,drop table)

释放全局锁,执行:

unlocktables

全局锁的应用场景

全库逻辑备份

在备份数据库期间,不会因为数据或表结构的更新,造成备份文件的数据于预期不一样。

加全局锁带来的缺点
造成业务停滞:当数据库中数据很多,备份就会花费很多时间,业务在此时处于只读状态,不能更新数据。

如何避免
如果数据库的引擎事务机制支持可重复读隔离界别,在备份数据库之前先开启事务,会先创建Read View,然后整个事务执行期间都在用Read View,由于MVCC的支持,备份期间还是可以对数据进行更新。

表级锁

表级锁的种类

  • 表锁
  • 元数据锁(MDL)
  • 意向锁
  • AUTO-INC锁

表锁

对具体某一张表进行加锁:
如果我们想对学生表(t_student)加表锁,可以使用下面的命令:

//表级别的共享锁,也就是读锁;//允许当前会话读取被锁定的表,但阻止其他会话对这些表进行写操作。locktablest_studentread;//表级别的独占锁,也就是写锁;//允许当前会话对表进行读写操作,但阻止其他会话对这些表进行任何操作(读或写)。locktablest_stuentwrite;

注意,表锁除了会限制别的线程读写外,也会限制本线程接下来的读写操作。

总结:尽量避免在使用innodb引擎的表使用表锁,业务表锁的颗粒多太大,会影响并发性能,innodb有颗粒对=度更细的行级锁

元数据锁(MDL)

MDL是为了保证当永辉对表执行CRUD操作时,防止其他线程对这个表结构做了变更。
• 对一张表进行 CRUD 操作时,加的是 MDL 读锁;
• 对一张表做结构变更操作的时候,加的是 MDL 写锁;

MDL不需要显示调用,那他是在什么时候释放的?

MDL时在事务提交后才会释放,这说明了:事务执行期间,MDL时一致持有的

那如果数据库有一个长事务(所谓的长事务,就是开启了事务,但是一直还没提交),那在对表结构做变更操作的时候,可能会发生意想不到的事情,比如下面这个顺序的场景:

  1. 首先,线程 A 先启用了事务(但是一直不提交),然后执行一条 select 语句,此时就先对该表加上 MDL 读锁;
  2. 然后,线程 B 也执行了同样的 select 语句,此时并不会阻塞,因为「读读」并不冲突;
  3. 接着,线程 C 修改了表字段,此时由于线程 A 的事务并没有提交,也就是 MDL 读锁还在占用着,这时线程 C 就无法申请到 MDL 写锁,就会被阻塞,
    那么在线程 C 阻塞后,后续有对该表的 select 语句,就都会被阻塞,如果此时有大量该表的 select 语句的请求到来,就会有大量的线程被阻塞住,这时数据库的线程很快就会爆满了。

我为什么线程c因为申请不到MDL写锁,而导致后续的申请读锁的查询操作做也会被阻塞?

答:申请MDL锁的操作会形成一个队列,队列中写锁获取优先级高于读锁,一旦出现MDL写锁等待,会阻塞后续该列表的所有CRUD操作。

为了能安全的对表结构进行变更,在对表结构变更前,先要看看数据库中的长事务,是否有事务已经对表加上了 MDL 读锁,如果可以考虑 kill 掉这个长事务,然后再做表结构的变更。

意向锁

所用:为了快速判断表里是否有记录被加锁
• 在使用 InnoDB 引擎的表里对某些记录加上「共享锁」之前,需要先在表级别加上一个「意向共享锁」;
• 在使用 InnoDB 引擎的表里对某些纪录加上「独占锁」之前,需要先在表级别加上一个「意向独占锁」;
也就是,当执行插入、更新、删除操作,需要先对表加上「意向独占锁」,然后对该记录加独占锁。
而普通的 select 是不会加行级锁的,普通的 select 语句是利用 MVCC 实现一致性读,是无锁的。
不过,select 也是可以对记录加共享锁和独占锁的,具体方式如下:

//先在表上加上意向共享锁,然后对读取的记录加共享锁select...lockinsharemode;//先表上加上意向独占锁,然后对读取的记录加独占锁select...forupdate;

意向共享锁和意向独占锁是表级锁,不会和行级的共享锁和独占锁发生冲突,而且意向锁之间也不会发生冲突,只会和共享表锁(lock tables … read)和独占表锁(lock tables … write)发生冲突。
表锁和行锁是满足读读共享、读写互斥、写写互斥的。
如果没有「意向锁」,那么加「独占表锁」时,就需要遍历表里所有记录,查看是否有记录存在独占锁,这样效率会很慢。
那么有了「意向锁」,由于在对记录加独占锁前,先会加上表级别的意向独占锁,那么在加「独占表锁」时,直接查该表是否有意向独占锁,如果有就意味着表里已经有记录被加了独占锁,这样就不用去遍历表里的记录。

AUTO-INC 锁

AUTO-INC 锁是 InnoDB 给自增列分配唯一值的“排队锁”,确保多个事务插入时不会重复或冲突。
什么是 AUTO-INC 锁
AUTO-INC 锁(也叫自增锁)是 MySQL 为了保证 AUTO_INCREMENT 列在高并发插入时生成连续唯一值而加的一种表级锁。
它是 InnoDB 的表级意向锁的一种特殊实现,用于序列化对自增列的访问,防止并发插入导致自增值冲突。
为什么需要AUTO-INC 锁
假设有一个表

CREATETABLEt1(idINTAUTO_INCREMENTPRIMARYKEY,nameVARCHAR(20))ENGINE=InnoDB;

当多个事务同时执行

INSERTINTOt1(name)VALUES('A'),('B'),('C');

MySQL必须保证:每一条记录获得唯一的id;自增值不会跳号或重复
为了实现,innodb会对表加AUTO-INC 锁,让同一时刻只有一个线程分配自增值

行级锁

InnoDB 引擎是支持行级锁的,而 MyISAM 引擎并不支持行级锁。
普通的select语句是不会对记录加锁的,因为它属于快照读。
如果要在查询时对记录加行锁,可以使用下面这两个方式,这种查询会加锁的语句称为锁定读。

//对读取的记录加共享锁select...lockinsharemode;//对读取的记录加独占锁select...forupdate;

上面这两条语句必须在一个事务中,因为当事务提交了,锁就会被释放,所以在使用这两条语句的时候,要加上 begin、start transaction 或者 set autocommit = 0。
共享锁(S锁)满足读读共享,读写互斥。独占锁(X锁)满足写写互斥、读写互斥。

行级锁主要有三类:

  • Recode Lock:记录所,也就是仅仅把一条记录锁上
  • Gap Lock:间隙锁,锁定一个范围,但不包含记录本身
  • Next-key Lock:Record Lock + Gap Lock的组合,锁定一个范围,并锁定记录本身

Gap Lock

间隙锁,存在于可重复读与串行化隔离级别,目的是为了解决可重复读隔离级别下幻读的现象。
假设,表中有一个范围 id 为(3,5)间隙锁,那么其他事务就无法插入 id = 4 这条记录了,这样就有效的防止幻读现象的发生。

gap lock页存在x型/s型间隙锁,但没什么区别。间隙锁之间是兼容的,两个事务可以同时持有包含共同间隙范围的间隙锁,并不存在互斥关系,因为间隙锁的目的是防止插入幻影记录而提出的

Next-Key Lock

假设,表中有一个范围 id 为(3,5] 的 next-key lock,那么其他事务即不能插入 id = 4 记录,也不能修改 id = 5 这条记录。

所以,next-key lock 即能保护该记录,又能阻止其他事务将新纪录插入到被保护记录前面的间隙中。
next-key lock 是包含间隙锁+记录锁的,如果一个事务获取了 X 型的 next-key lock,那么另外一个事务在获取相同范围的 X 型的 next-key lock 时,是会被阻塞的。

http://www.jsqmd.com/news/668478/

相关文章:

  • CentOS7上从源码编译Zabbix 6.0,我踩过的那些坑和最佳实践
  • Matlab图像处理实战:用flip函数轻松搞定图像翻转、镜像与数据增强
  • c++如何处理文件路径中由于不规范的连续斜杠导致的路径解析错误【避坑】
  • 从ZkClient到Curator:Spring Boot项目里ZooKeeper客户端选型与实战避坑指南
  • 告别官方限制:在Manjaro/Arch上为罗技鼠标解锁LogiOps驱动的完整配置流程
  • 告别Navicat!JetBrains DataGrip 2024.1 保姆级安装与中文汉化指南(附时区问题解决)
  • 如何设置密码复杂度策略以约束MongoDB用户的密码强度
  • Apache Guacamole实战:将远程桌面无缝集成到SpringBoot管理后台
  • 当模数只有50万:从‘球与盒子’问题聊聊竞赛中那些‘不寻常模数’的坑与技巧
  • 代码重构技巧:改善既有代码的设计
  • 别再死记硬背A*算法了!用Python实战8数码问题,手把手教你理解曼哈顿距离的威力
  • 从fmax到qsort:解锁C语言内置工具函数的实战效能与设计哲学
  • 别再只会用Base64了!手把手教你用Python魔改码表,打造自己的“加密”工具
  • 别再手动传配置了!用3CDaemon+SecureCRT给H3C交换机传文件的保姆级教程
  • 【AGI物理交互能力跃迁指南】:20年机器人AI专家揭秘3大硬件耦合瓶颈与5步落地路径
  • Agent 的可解释性怎么做:从决策轨迹到证据引用的产品化
  • 【AGI时代分水岭】:SITS2026正式发布——全球首个面向生产级AGI的多维能力基准测试体系(附权威评测白皮书下载通道)
  • 【卷卷观察】Accel 募集 50 亿美元,硅谷 VC 正在用真金白银回答一个问题
  • 避开Boost电路设计的那些‘坑’:用STM32驱动IGBT,你的栅极电阻和霍尔传感器选对了吗?
  • 网络工程师-实战配置篇(一):深入 BGP 与 VRRP,构建高可靠网络
  • 龙虾配置文件之TOOLS.md 源码分析与配置指南
  • 别再死记硬背了!用Visual Studio 2022创建第一个WinForm窗体的保姆级避坑指南
  • 快速入门python学习笔记
  • 全志V3s开发板避坑指南:手把手教你配置boot.scr和script.bin(附完整代码)
  • 从三相静止到两相旋转:手把手推导永磁同步电机(PMSM)的d-q轴数学模型
  • MCNP5新手避坑指南:从零开始,手把手教你编写第一个蒙特卡罗粒子输运程序
  • 程序员的心理学学习笔记 - 逆火效应
  • Python 功能和特点(新手必学)
  • MySQL主从同步时DDL操作怎么处理_线上执行大表DDL的方案
  • 告别布线烦恼!MIPI C-PHY vs D-PHY:从原理到PCB实战,教你如何为你的摄像头/屏幕选型