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

MySQL 当中的锁

MySQL 当中的锁

文章目录

  • MySQL 当中的锁
    • MySQL 中有哪些主要类型的锁?请简要说明
    • MySQL 的全局锁有什么用?
    • MySQL 的表级锁有哪些?作用是什么?
      • 元数据锁(MetaData Lock,MDL)
      • 意向锁(Intention Locks)
      • 自增锁(AUTO-INC Locks)
    • MySQL 的行级锁有哪些?作用是什么?
      • 记录锁
      • 间隙锁
      • 临键锁
      • 插入意向锁
    • 什么情况下 InnoDB 的行级锁会升级为表级锁?
    • 什么是死锁?MySQL 中如何检测和处理死锁?
    • 解释意向锁的作用及其工作原理
    • 什么是乐观锁和悲观锁?MySQL 中如何实现?
    • 解释 MySQL 8.0 新增的 SKIP LOCKED 和 NOWAIT 特性

本篇文章对 MySQL 当中的锁机制进行学习,具体的参考资料来自 csview,参考链接如下:https://www.csview.cn/mysql/lock.html。
在这里插入图片描述

MySQL 中有哪些主要类型的锁?请简要说明

按锁粒度划分

  • 表级锁:锁定整张表;
  • 行级锁:锁定表中的行;
  • 页级锁:锁定数据页;

按锁的性质划分

  • 共享锁(S锁):允许并发读,阻塞写;
  • 排他锁(X锁):禁止任何其他锁;
  • 意向锁:表明事务将要获取的锁类型;

特殊锁

  • 元数据锁:属于表级锁,用于保护表结构在事务执行期间不被修改;
  • 自增锁:同样属于表级锁,用于保护自增主键的列,以确保主键的递增性;
  • 间隙锁:属于行级锁,主要用于在可重复读隔离级别下解决幻读问题。

MySQL 的全局锁有什么用?

作用
整个数据库将处于只读状态,增删改会被阻塞。

使用场景
全局锁主要用于做全库逻辑备份

缺陷
当数据库中记录过多时,备份会花费很多时间。备份期间,业务职能读数据,而不能更新数据,这样会造成业务停滞。

改进
在可重复读隔离级别下,备份数据库之前会先开启事务,会先创建 Read View,然后整个事务执行期间都使用这个 Read View。由于 MVCC 的支持,备份期间业务依然可以对数据进行更新操作。即使其他事务更新了表的数据,也不会备份数据库时的 Read View,这样备份期间备份的数据一直是事务开启时的数据。

MySQL 的表级锁有哪些?作用是什么?

元数据锁(MetaData Lock,MDL)

当事务访问数据库当中的表时,自动为表加 MDL 锁。作用是防止表的结构被修改,保证表结构的一致性。MDL 在事务提交后才会被释放。

意向锁(Intention Locks)

意向锁为 InnoDB 引擎所独有。意向锁进一步细分为意向共享锁和意向排他锁。

  • 意向共享锁(IS):表示事务打算在表中的某些行上设置共享锁;
  • 意向排他锁(IX):表示事务打算在表中的某些行上设置排他锁;

意向锁的作用是快速判断表里是否有记录被加锁,以:

  • 提高锁冲突检测效率;
  • 避免逐行检测锁状态。

自增锁(AUTO-INC Locks)

作用
表中主键通常会被设置为自增,之后在插入数据时,可以不指定主键的值,数据库会自动给这条新增的记录的主键赋值,通过 AUTO-INC 锁来实现。具体来说,在插入数据时,会加一个表级的 AUTO-INC 锁,然后为被 AUTO_INCREMENT 修饰的字段赋递增的主键值。待插入语句完毕时,才会把 AUTO-INC 锁释放掉。在此期间,其他事务若想要向该表插入数据,都将被阻塞,从而保证插入数据的字段的值是连续递增的。

缺陷
大量数据插入的场景下,会影响数据库的性能。

改进
InnoDB 提供了一种轻量级锁实现自增。插入数据时,会为 AUTO_INCREMENT 修饰的字段加上轻量级锁,然后给该字段赋一个自增值,之后就释放轻量级锁,而不需要等待整个插入语句执行完毕才释放锁。

MySQL 的行级锁有哪些?作用是什么?

记录锁

细分为排他锁和共享锁,锁住表中的单条记录。

当表没有索引时,记录锁将锁定隐式主键。

间隙锁

间隙锁仅用于可重复读隔离级别,目的是为了解决该级别下的幻读现象。间隙锁确保数据表当中的某个区间的记录不会被修改。两个事务可以同时持有包含相同间隙范围的间隙锁,不存在互斥关系。

临键锁

临键锁是记录锁和间隙锁的组合,它会锁定一个范围,并且锁定记录本身。临键锁既能保护该记录,又能防止其它事务将新记录插入到被保护的记录前面的间隙当中。

临键锁是 InnoDB 默认的行锁算法(注意,可重复读隔离级别也是 InnoDB 默认的隔离级别,由于临键锁包含间隙锁,而间隙锁只能用于可重复读隔离级别,意味着临键锁也只能用于可重复读隔离级别)。

插入意向锁

一个事务在插入记录时,需要判断插入位置是否被其它事务加了间隙锁。如果有锁,插入操作会阻塞,直到拥有间隙锁的那个事务执行完毕提交为止,在此期间会生成一个插入意向锁,表明当前有事务想要在某个区间插入新记录,但目前处于等待状态。

什么情况下 InnoDB 的行级锁会升级为表级锁?

  1. 无合适索引:当 SQL 语句不能通过索引过滤数据时,会导致全表扫描;
  2. 高比例锁定:当要锁定的数据超过阈值时,行锁升级为表锁;
  3. 显式请求:使用 LOCK TABLES 语句明确要求表锁时;
  4. 特定 DDL 操作:如执行 ALTER TABLE 等操作时;

什么是死锁?MySQL 中如何检测和处理死锁?

死锁指的是两个或多个事务互相持有和请求锁资源,形成循环等待情况。

MySQL 检测和处理死锁的方式:
检测机制

  • 使用等待图(wait-for graph)算法;
  • 定期检查锁依赖关系;

处理方式

  • 选择回滚代价最小的事务作为牺牲者;
  • 返回 ERROR 1213 死锁错误;
  • 其他事务可以继续执行。

解释意向锁的作用及其工作原理

意向锁是表级锁,用于提高行锁冲突检测效率。

意向锁的作用是:

  1. 表明事务即将在表的某些行上加何种类型的锁;
  2. 避免逐行检查锁的状态,提高性能。

意向锁的类型:

  • 意向共享锁(IS):表明事务打算在某些行上加 S 锁;
  • 意向排他锁(IX):表明事务打算在某些行上加 X 锁。

什么是乐观锁和悲观锁?MySQL 中如何实现?

悲观锁假设会发生冲突,故先加锁再访问:

SELECT * FROM table WHERE id = 1 FOR UPDATE:
SELECT * FROM table WHERE id = 1 LOCK IN SHARE MODE;

乐观锁假设不会发生冲突,提交时检查版本:
添加版本号字段:

ALTER TABLE products ADD COLUMN version INT DEFAULT 0;

更新时检查:

UPDATE products
SET stock.= stock - 1, version = version + 1
WHERE id = 1 AND version = 1;

检查影响行数确认是否成功。

解释 MySQL 8.0 新增的 SKIP LOCKED 和 NOWAIT 特性

SKIP LOCKED 跳过已被锁定的行,应用场景是“任务队列处理”。

NOWAIT 遇到锁立即返回错误而非等待,应用场景是“快速失败场景”。

上述两个特性特别适合高并发队列系统和需要快速响应的应用。

相关文章:

  • 网络运维学习笔记(DeepSeek优化版)026 OSPF vlink(Virtual Link,虚链路)配置详解
  • 深度学习 Deep Learning 第13章 线性因子模型
  • PyQt6实例_批量下载pdf工具_批量pdf网址获取
  • 3.30学习总结 Java包装类+高精度算法+查找算法
  • 开发环境解决Secure Cookie导致302重定向
  • VUE实现框架搭建(纯手写)
  • 【Python爬虫神器】requests库常用操作详解 ,附实战案例
  • RocketMQ - 从消息可靠传输谈高可用
  • Cookie可以存哪些指?
  • 一区严选!挑战5天一篇脂质体组学 DAY1-5
  • Flink介绍——实时计算核心论文之S4论文详解
  • RS232转Profinet网关扫码器在西门子1200plc快速配置
  • MySQL中的CREATE TABLE LIKE和CREATE TABLE SELECT
  • 关于为什么使用redis锁,不使用zk锁的原因
  • LeetCode知识点整理
  • golang 的time包的常用方法
  • 通过 Adobe Acrobat DC 实现 Word 到 PDF 的不可逆转换
  • HTML5和CSS3的一些特性
  • fastdds:传输层端口号计算规则
  • IPython 使用技巧整理
  • 无忧中英繁企业网站系统 破解/百度怎么推广自己的作品
  • 济宁做网站哪家比较好/优化关键词的公司
  • 换空间对网站排名的影响吗/24小时网站建设
  • 网站全网建设 莱芜/安卓优化大师旧版
  • 网站建设沟通/如何推广普通话
  • 怎样做网站赚钱/运营和营销是一回事吗