深入解析 MySQL 并发控制:读写锁、锁粒度与高级优化

深入解析 MySQL 并发控制:读写锁、锁粒度与 InnoDB 实现细节

在高并发数据库应用中,确保数据一致性的同时最大化性能是永恒的挑战。MySQL 通过精巧的 锁机制(Locking)多版本并发控制(MVCC) 来解决这个问题。本文聚焦于锁机制的核心:读写锁(共享/排他锁)锁粒度(表锁/行锁),并深入探讨 InnoDB 存储引擎的具体实现和高级优化。


一、读写锁(Read-Write Locks)深入剖析

读写锁的核心思想是区分 读取(Read)写入(Write) 操作,因为它们对数据一致性的要求不同。

  1. 共享锁(Shared Lock, S Lock)

    • 目的: 允许多个事务 同时读取 同一份数据(通常是一个记录或页面)。
    • 行为:
      • 获取:事务执行 SELECT ... LOCK IN SHARE MODE 语句时申请 S 锁。
      • 兼容性:多个事务可以同时持有同一资源的 S 锁。这是 共享 的核心体现。
      • 冲突:S 锁与 X 锁互斥。如果一个事务持有 S 锁,其他事务无法获得该资源的 X 锁;反之亦然(但持有 S 锁的事务可以再获得 S 锁)。普通 SELECT (SELECT ...) 通常不需要 S 锁(利用 MVCC)。
    • 典型场景:REPEATABLE READSERIALIZABLE 隔离级别下,需要确保两次读取之间数据不被修改,但又允许其他事务读取时使用。
  2. 排他锁(Exclusive Lock, X Lock)

    • 目的: 保证同一时间 仅有一个事务 能够 修改 特定数据。
    • 行为:
      • 获取:事务执行数据修改语句(INSERT, UPDATE, DELETE)或 SELECT ... FOR UPDATE 时申请 X 锁。
      • 兼容性:X 锁与所有其他锁(包括 S 锁和其他 X 锁)互斥。事务获得资源的 X 锁后,其他事务的任何锁请求(S 或 X)都将被阻塞,直到该 X 锁释放。事务自己持有的 X 锁之间可能兼容也可能冲突(如锁定同一行则冲突)。
      • 强制性:在修改数据时,X 锁是必须获得的,无法回避。
    • 典型场景: 所有需要修改数据的操作以及在高隔离级别下需要“锁定读取”确保不被其他事务修改的场景。
  3. 锁兼容性矩阵(核心关系)

    当前持有锁 \ 请求新锁共享锁 (S)排他锁 (X)
    共享锁 (S)✅ (兼容)❌ (冲突)
    排他锁 (X)❌ (冲突)❌ (冲突)

    解读:

    • 一行: 表示一个事务当前持有了什么锁(S 或 X)。
    • 一列: 表示这个事务或者另一个事务想请求什么新锁(S 或 X)。
    • 单元格(✅/❌): 表示在持有锁的状态下,请求新锁是否被允许(是否兼容)。
    • 关键点: X 锁的存在会阻止任何其他锁(S 或 X)的获取;S 锁只阻止 X 锁的获取,但允许多个 S 锁共存。

二、锁粒度(Lock Granularity)深度解析

锁的粒度决定了锁定时资源的最小单位,直接影响并发度和开销。

  1. 表级锁(Table-Level Locks)

    • 锁定对象: 整个数据库表。
    • 实现引擎: MyISAM, MEMORY, MERGE 等非事务引擎的默认锁策略。
    • 锁类型:
      • 表共享读锁 (Table Read Lock - 类似 IS):
        • 允许:其他会话可以同时获取表读锁(执行 SELECT 但非 LOCK IN SHARE MODE/FOR UPDATE 时,MyISAM 引擎会隐式加读锁)。允许并发
        • 禁止:其他会话无法获得表写锁。所有操作被阻塞。
      • 表独占写锁 (Table Write Lock - 类似 IX):
        • 允许:只有持有锁的会话可以读写该表。
        • 禁止:其他会话对该表的所有读写操作(无论是隐式读锁还是显式写锁请求)都会被阻塞。
    • 优点:
      • 实现简单。
      • 开销极低(内存占用少,获取/释放速度快)。
    • 缺点:
      • 并发度最低: 写操作会阻塞所有其他操作;读操作也会阻塞所有写操作。在高并发读写混合场景下性能极差。
      • 易成瓶颈: 一个耗时写操作会“锁死”整个表。
    • 使用场景: 主要用于只读表、读远大于写的低并发场景,或非常小的表。强烈不建议在高并发 OLTP 环境中使用表级锁引擎。
  2. 行级锁(Row-Level Locks)

    • 锁定对象: 单个数据行(实际上是锁住索引记录)。
    • 实现引擎: InnoDB(默认且推荐)。NDB 集群也支持。
    • 锁类型(InnoDB 主要锁模式):
      • 记录锁 (Record Lock):
        • 锁定索引中单一行记录(即使没有显式索引,InnoDB 也会隐式创建聚簇索引)。
        • 防止其他事务修改(加 X Lock)或 SELECT ... FOR UPDATE/LOCK IN SHARE MODE(加 S/X Lock)被锁定的具体行。
      • 间隙锁 (Gap Lock):
        • 锁定索引记录之间的间隙(Gap),或者第一个索引记录之前或最后一个索引记录之后的“无限”间隙。
        • 目的: 防止其他事务将新记录插入到该间隙中(避免“幻读”)。
        • 特性:
          • 只锁定间隙,不锁定已有记录本身。允许其他事务修改间隙两端的记录。
          • 只与其他试图在同一个间隙插入记录的意向锁冲突。
          • 仅在 REPEATABLE READ (默认) 和 SERIALIZABLE 隔离级别下生效。 READ COMMITTED 级别会禁用间隙锁(通过半一致读避免部分幻读)。
      • 临键锁 (Next-Key Lock):
        • 记录锁 + 间隙锁的组合。锁定索引记录以及该记录之前的间隙
        • 例如,索引有值 10, 11, 13。Next-Key Lock 可能锁定:
          • (negative infinity, 10]
          • (10, 11]
          • (11, 13]
          • (13, positive infinity]
        • 这是 InnoDB 在 REPEATABLE READ 级别下默认的行锁算法。它能同时避免“脏读”、“不可重复读”和一部分“幻读”
      • 插入意向锁 (Insert Intention Lock):
        • 一种特殊的间隙锁 (Gap Lock)
        • 在执行 INSERT 操作之前设置。
        • 意图: 表示一个事务想在一个索引间隙中插入一个新行。
        • 特性:
          • 不相互阻塞: 多个事务可以在同一个间隙的不同位置插入意向锁(只要插入位置不同),允许并发插入。
          • 冲突: 会与已经持有的该间隙上的 间隙锁 (Gap Lock)临键锁 (Next-Key Lock) 冲突。这是插入操作阻塞的主要根源之一。
    • 优点:
      • 高并发度: 不同的事务可以同时修改表的不同行(只要它们不锁定同一行)。
    • 缺点:
      • 高开销: 获取、维护和释放锁需要大量系统资源(内存、CPU)。锁管理器需要为大量行维护锁信息。
      • 管理复杂: 检测和解决死锁更复杂。
      • 潜在死锁: 多个事务按不同顺序请求行锁极易导致死锁。
    • 使用场景: 高并发 OLTP(在线事务处理)系统的绝对首选。
  3. 页面锁 (Page-Level Locks - 已逐渐淡出主流)

    • 锁定数据页(通常 16KB)。
    • 早期存储引擎(如 BDB)使用。
    • 介于表锁和行锁之间。
    • 现今重要性较低。

锁粒度选择建议:

  • 追求最高并发写 (OLTP): 绝对选择支持行级锁的引擎,尤其是 InnoDB。这是现代 MySQL 应用的标配。
  • 极端读密集型、极少更新 (如数据仓库报表读取、静态配置表): 若性能关键且能接受表锁缺点,可考虑 MyISAM(但需注意崩溃恢复、备份等问题),但 InnoDB 通常是更安全、更全面的选择
  • 避免使用 LOCK TABLES 语句:它会强制加表锁,破坏 InnoDB 的行锁机制,引发严重性能问题和死锁。

三、InnoDB 锁机制深入实现细节
  1. 意向锁 (Intention Locks):行级锁与表级锁的桥梁

    • 目的: 快速判断表级锁与行级锁的兼容性,避免逐行检查。
    • 类型:
      • 意向共享锁 (Intention Shared Lock, IS): 事务打算在中的某些行上设置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88250.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88250.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【深度学习加速探秘】Winograd 卷积算法:让计算效率 “飞” 起来

一、为什么需要 Winograd 卷积算法?从 “卷积计算瓶颈” 说起 在深度学习领域,卷积神经网络(CNN)被广泛应用于图像识别、目标检测、语义分割等任务。然而,卷积操作作为 CNN 的核心计算单元,其计算量巨大&a…

前端项目脱离后端运行,备份后端API数据

问题描述: 开发过的项目老是打不开,因为离开公司后服务器用不了了。所以想着在公司开发的时候把数据都备份一下,供之后参考项目代码。 实现方法: 建一个Express服务,前端请求Express,Express代理目标服务器…

Windows下利用DevEcoStudio的交叉编译工具链编译assimp库给OpenHarmony使用

文章目录 准备编译使用 准备 安装DevEco Studio,并且安装好对应OpenHarmony版本的SDK 比如我这里安装了API 11 的sdk 对应的文件夹 然后下载ASSIMP的源文件,我这里下载的是5.4.3版本 【assimp 5.4.3】 解压放在一个文件夹里面,并在源码文…

批量大数据并发处理中的内存安全与高效调度设计(以Qt为例)

背景 在批量处理大型文件(如高分辨率图片、视频片段、科学数据块)时,开发者通常希望利用多核CPU并行计算以提升处理效率。然而,如果每个任务对象的数据量很大,直接批量并发处理极易导致系统内存被迅速耗尽,出现程序假死、崩溃,甚至系统级“死机”。 Qt自带的线程池(Q…

微信小程序课程设计美食点餐订餐系统

文章目录 1. 项目概述2. 项目思维导图3. 系统架构特点4. 核心模块实现代码1. 登录注册2. 首页模块实现4. 分类模块实现5. 购物车模块实现6. 订单模块实现 5. 注意事项6. 项目效果截图7. 关于作者其它项目视频教程介绍 1. 项目概述 在移动互联网时代,餐饮行业数字化…

Linux中使用grep查看日志

Linux中使用grep查看日志 文章目录 Linux中使用grep查看日志1、使用 grep 查找字符或字符串示例常用选项例子 2、显示前后上下文选项说明示例命令 结果示例 3、显示出现的次数使用示例选项说明示例其他方法总结 4、其他命令1. 基本用法2. 常用选项3. 正则表达式支持4. 其他实用…

DataWhale-零基础络网爬虫技术(二er数据的解析与提取)

课程链接先给各位 ↓↓↓ (点击即可食用.QAQ Datawhale-学用 AI,从此开始 一、数据的解析与提取 数据提取的几种方式: re解析bs4解析xpath解析 1.1正则表达式(Reuglar Experssion) RE是一种用于字符串匹配的规则描述方式。它…

Gin框架与Apifox

第一部分:技术栈概述 1. Go语言简介 Go(又称Golang)是Google开发的一门静态类型、编译型编程语言,具有以下特点: 高性能:编译为机器码,执行效率接近C/C 简洁语法:没有复杂的OOP概…

Docker 容器技术入门与环境部署

一、Docker 技术概述与核心概念解析 (一)Docker 技术本质与定位 Docker 是当前主流的操作系统级容器虚拟化技术,其核心价值在于通过轻量化隔离机制解决开发、测试与生产环境的一致性问题。与传统虚拟机(如 VMware)相…

π0源码(openpi)剖析——从π0模型架构的实现:如何基于PaLI-Gemma和扩散策略去噪生成动作,到基于C/S架构下的模型训练与部署

前言 ChatGPT出来后的两年多,也是我疯狂写博的两年多(年初deepseek更引爆了下),比如从创业起步时的15年到后来22年之间 每年2-6篇的,干到了23年30篇、24年65篇、25年前两月18篇,成了我在大模型和具身的原始技术积累 如今一转眼已…

Vui:轻量级语音对话模型整合包,让交互更自然

Vui:轻量级语音对话模型,让交互更自然 🗣️✨ Vui 是 Fluxions-AI 团队推出的一款开源轻量级语音对话模型,其核心架构基于 LLaMA。这款模型经过了长达 4 万小时的真实对话数据训练,能够逼真地模拟人类对话中的语气词、…

【STL】深入理解 string 的底层思想

一、STL的定义 STL是C标准库的一部分它不仅是一个可复用的组件库还是一个包含数据结构和算法的软件框架。 二、STL的历史和版本 原始版本: Alexander Stepanov、Meng Lee在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运…

深入剖析Linux epoll模型:从LT/ET模式到EPOLLONESHOT的实战指南

一、epoll:高性能I/O复用的核心引擎 epoll是Linux内核2.6引入的高效I/O多路复用机制,专为解决C10K问题而生。相比select/poll,epoll在连接数激增时性能优势显著: // 创建epoll实例 int epollfd epoll_create1(0);// 事件注册 s…

网络安全之某cms的漏洞分析

漏洞描述 该漏洞源于Appcenter.php存在限制,但攻击者仍然可以通过绕过这些限制并以某种方式编写代码,使得经过身份验证的攻击者可以利用该漏洞执行任意命令 漏洞分析 绕过编辑模板限制,从而实现RCE 这里可以修改模板文件,但是不…

Nginx-前端跨域解决方案!

1 Nginx 核心 Nginx 是一个开源的高性能 HTTP 和反向代理服务器,以轻量级、高并发处理能力和低资源消耗著称。除作为 Web 服务器外,还可充当邮件代理服务器和通用的 TCP/UDP 代理服务器,广泛应用于现代 Web 架构中。 在 Windows 系统中使用…

RedisVL 入门构建高效的 AI 向量搜索应用

一、前置条件 在开始之前,请确保: 已在 Python 环境中安装 redisvl。运行 Redis Stack 或 Redis Cloud 实例。 二、定义索引架构(IndexSchema) 索引架构(IndexSchema)用于定义 Redis 的索引配置和字段信…

基于ssm移动学习平台微信小程序源码数据库文档

摘 要 由于APP软件在开发以及运营上面所需成本较高,而用户手机需要安装各种APP软件,因此占用用户过多的手机存储空间,导致用户手机运行缓慢,体验度比较差,进而导致用户会卸载非必要的APP,倒逼管理者必须改…

【Python】Tkinter模块(巨详细)

专栏文章索引:Python 有问题可私聊:QQ:3375119339 本文内容系本人根据阅读的《Python GUI设计tkinter从入门到实践》所得,以自己的方式进行总结和表达。未经授权,禁止在任何平台上以任何形式复制或发布原始书籍的内容。如有侵权,请联系我删除。 目录 一、Tkinter与GUI …

【C++特殊工具与技术】局部类

在 C 的类体系中,除了全局类、嵌套类(在类内部定义的类),还有一种特殊的存在 ——局部类(Local Class)。它像函数内部的 “封闭王国”,作用域严格限制在所属函数内,既拥有类的封装特…

《C#图解教程 第5版》深度推荐

《C#图解教程 第5版》深度推荐 在 C# 编程语言的浩瀚学习资源中,《C#图解教程 第5版》宛如一座灯塔,为开发者照亮前行之路。通过其详实的目录,我们能清晰窥见这本书在知识架构、学习引导上的匠心独运,无论是编程新手还是进阶开发者…