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

全面解析数据库锁机制:从行锁到死锁的深度剖析

锁是数据库并发控制的核心机制也是面试中绕不开的高频考点。很多开发者对锁的理解停留在“加锁就行了”但遇到死锁、锁等待超时、性能骤降等问题时往往束手无策。本文将系统讲解数据库锁的分类、实现原理、锁与事务隔离级别的关系并结合 MySQL InnoDB 深入分析锁的底层机制最后给出死锁排查与优化实战。一、为什么需要锁数据库需要同时处理多个并发请求如果没有锁机制就会出现丢失更新两个事务同时读取同一数据并修改后提交的覆盖先提交的脏读读到未提交的数据不可重复读同一事务内多次读取结果不一致锁的本质协调多个事务对共享资源的并发访问保证数据的一致性和完整性。二、锁的分类从不同维度1. 按粒度分类锁粒度描述优点缺点适用场景表级锁锁定整张表开销小加锁快不会死锁并发度低MyISAM、内存表、DDL操作行级锁锁定索引记录并发度高锁冲突概率低开销大加锁慢可能死锁InnoDB 在线事务处理页级锁锁定数据页8KB-16KB介于表和行之间BDB 引擎使用现已少见历史遗留2. 按模式分类锁模式英文兼容性说明共享锁Shared LockS锁S 与 S 兼容S 与 X 互斥读锁允许其他事务读取禁止写入排他锁Exclusive LockX锁X 与任何锁互斥写锁禁止其他事务读写加锁语句示例-- 共享锁读锁 SELECT * FROM user WHERE id 1 LOCK IN SHARE MODE; -- 排他锁写锁 SELECT * FROM user WHERE id 1 FOR UPDATE; UPDATE user SET name new WHERE id 1; -- 自动加排他锁 DELETE FROM user WHERE id 1; -- 自动加排他锁 INSERT INTO user VALUES (...); -- 自动加排他锁3. 按意向分类意向锁Intention Lock是表级锁表示事务想要在表中的某些行上加更细粒度的锁。意向锁类型含义加锁时机意向共享锁IS事务想要获得某些行的共享锁SELECT ... LOCK IN SHARE MODE意向排他锁IX事务想要获得某些行的排他锁SELECT ... FOR UPDATE、UPDATE、DELETE为什么需要意向锁如果没有意向锁事务A要加表锁时需要逐行检查是否有行锁效率极低。意向锁的存在让表锁可以快速判断是否有行锁冲突。4. 按算法分类InnoDB 行锁的三种实现锁算法描述锁定范围防止幻读记录锁锁定单个索引记录只锁定匹配的行否间隙锁锁定记录之间的间隙锁定范围不包括记录本身是临键锁记录锁 间隙锁锁定记录及其前面的间隙左开右闭是图示理解数据id 1, 2, 5, 8, 10 临键锁区间(负无穷,1], (1,2], (2,5], (5,8], (8,10], (10,正无穷) -- 执行以下语句可重复读级别 SELECT * FROM t WHERE id 5 FOR UPDATE; -- 锁定区间 (2,5] 和 (5,8]三、InnoDB 锁的底层实现1. 锁的存储结构InnoDB 的锁信息存储在锁管理器Lock Manager中每个锁对应一个lock_t结构体包含锁类型S/X锁模式记录锁/间隙锁/临键锁锁定的行通过 heap_no 标识持有锁的事务ID2. 加锁流程事务执行 SQL ↓ 解析 SQL确定需要锁定的行 ↓ 根据隔离级别和索引类型确定锁算法 ↓ 在锁管理器中创建锁结构尝试获取锁 ↓ 冲突 ├── 无冲突 → 获取锁成功继续执行 └── 有冲突 → 等待进入锁等待队列可能死锁检测3. 不同 SQL 的加锁行为SQL 语句索引情况加锁行为SELECT ... FOR UPDATE使用主键/唯一索引记录锁SELECT ... FOR UPDATE使用普通索引临键锁 回表记录锁SELECT ... FOR UPDATE全表扫描全表所有行的临键锁UPDATE ... WHERE id ?使用唯一索引记录锁UPDATE ... WHERE age ?使用普通索引临键锁INSERT-排他锁 插入意向锁DELETE-排他锁根据条件加临键锁4. 插入意向锁插入意向锁是一种特殊的间隙锁用于提高插入并发性能。事务A在(5,10)区间加了间隙锁事务B要插入id7时会在(5,10)上加插入意向锁插入意向锁之间不互斥多个事务可以同时插入不同位置四、锁与事务隔离级别的关系隔离级别读取方式加锁行为锁释放时机READ UNCOMMITTED不加锁直接读最新数据几乎不加锁-READ COMMITTED每次读取快照不加锁只加记录锁不加间隙锁语句执行完立即释放REPEATABLE READ第一次读取快照临键锁防止幻读事务提交时释放SERIALIZABLE所有读都加共享锁临键锁 共享锁事务提交时释放关键点RC 级别只有记录锁没有间隙锁存在幻读风险RR 级别有临键锁解决幻读但SELECT ... FOR UPDATE仍需注意锁的释放时机RC 级别语句结束释放RR 级别事务结束释放这是锁等待问题的根源五、死锁数据库的交通堵塞1. 什么是死锁两个或多个事务互相持有对方需要的锁形成循环等待谁都无法继续执行。经典死锁示例-- 事务A BEGIN; UPDATE account SET balance balance - 100 WHERE id 1; UPDATE account SET balance balance 100 WHERE id 2; COMMIT; -- 事务B BEGIN; UPDATE account SET balance balance - 50 WHERE id 2; UPDATE account SET balance balance 50 WHERE id 1; COMMIT; -- 并发执行顺序 -- T1: A 锁定 id1 -- T2: B 锁定 id2 -- T3: A 等待 id2 锁B持有 -- T4: B 等待 id1 锁A持有 -- 死锁形成2. 死锁的四个必要条件互斥资源只能被一个事务持有持有并等待事务持有锁的同时等待其他锁不可剥夺已获得的锁不能被强制释放循环等待形成等待环路3. MySQL 死锁处理机制死锁检测InnoDB 通过等待图Wait-for Graph检测死锁时间复杂度 O(n²)回滚策略选择回滚权重较小的事务执行时间短、undo log 少的事务控制参数innodb_deadlock_detect默认 ON高并发下可关闭用lock_wait_timeout替代4. 死锁排查与解决查看最近一次死锁信息SHOW ENGINE INNODB STATUS\G -- 查看 LATEST DETECTED DEADLOCK 部分查看当前锁等待-- 查看当前正在等待锁的事务 SELECT * FROM information_schema.INNODB_LOCK_WAITS; -- 查看当前持有的锁 SELECT * FROM information_schema.INNODB_LOCKS; -- 更直观的查询MySQL 8.0 SELECT * FROM performance_schema.data_locks;死锁优化策略策略说明固定访问顺序所有事务按相同顺序访问资源如先更新 id1再更新 id2缩小事务粒度减少事务持有锁的时间降低冲突概率合理使用索引避免全表扫描导致的锁范围过大降低隔离级别RC 级别锁范围更小死锁概率低于 RR使用NOWAITMySQL 8.0 支持SELECT ... FOR UPDATE NOWAIT不等待直接报错六、锁监控与调优1. 查看锁状态变量-- 查看 InnoDB 锁相关的状态 SHOW STATUS LIKE innodb_row_lock%; -- 输出示例 -- Innodb_row_lock_current_waits: 0 -- 当前等待锁的事务数 -- Innodb_row_lock_time: 123456 -- 总等待时间ms -- Innodb_row_lock_time_avg: 100 -- 平均等待时间 -- Innodb_row_lock_time_max: 5000 -- 最大等待时间 -- Innodb_row_lock_waits: 123 -- 总等待次数2. 分析慢查询中的锁等待-- 开启慢查询日志记录锁等待超过 2 秒的 SQL SET GLOBAL slow_query_log ON; SET GLOBAL long_query_time 2; SET GLOBAL log_queries_not_using_indexes ON;3. 优化建议索引是锁的基础无索引的 UPDATE/DELETE 会锁全表避免大事务事务越大持有锁的时间越长冲突概率越高合理设计业务逻辑将非核心操作移出事务使用乐观锁读多写少场景用版本号代替悲观锁七、乐观锁 vs 悲观锁对比维度乐观锁悲观锁核心思想假设冲突很少发生更新时检查版本假设一定会冲突提前加锁实现方式版本号、时间戳、CAS数据库行锁、SELECT FOR UPDATE适用场景读多写少冲突概率低写多读少冲突概率高性能无锁等待吞吐量高锁等待吞吐量较低重试机制需要业务层重试数据库自动等待乐观锁示例-- 表结构增加 version 字段 ALTER TABLE product ADD COLUMN version INT DEFAULT 0; -- 查询时记录版本 SELECT id, stock, version FROM product WHERE id 1; -- 更新时检查版本 UPDATE product SET stock stock - 1, version version 1 WHERE id 1 AND version #{oldVersion}; -- 影响行数为 0 则重试八、总结与对比表维度要点锁粒度表锁 页锁 行锁粒度越小并发越高锁模式共享锁读、排他锁写锁算法记录锁、间隙锁、临键锁RR 级别默认死锁四要素互斥、持有并等待、不可剥夺、循环等待排查工具SHOW ENGINE INNODB STATUS、performance_schema.data_locks优化方向索引优化、缩小事务、固定顺序、降低隔离级别一句话总结锁是数据库并发控制的基石理解锁的粒度、模式和算法才能写出高性能、无死锁的数据库代码。

相关文章:

全面解析数据库锁机制:从行锁到死锁的深度剖析

锁是数据库并发控制的核心机制,也是面试中绕不开的高频考点。很多开发者对锁的理解停留在“加锁就行了”,但遇到死锁、锁等待超时、性能骤降等问题时往往束手无策。本文将系统讲解数据库锁的分类、实现原理、锁与事务隔离级别的关系,并结合 M…...

MailHog终极指南:如何快速搭建本地邮件测试环境

MailHog终极指南:如何快速搭建本地邮件测试环境 【免费下载链接】MailHog Web and API based SMTP testing 项目地址: https://gitcode.com/gh_mirrors/ma/MailHog MailHog是一款基于Web和API的SMTP测试工具,能够帮助开发者在本地快速搭建安全高效…...

如何用Binance Trade Bot实现加密货币交易自动化?从配置到运行的完整路径

如何用Binance Trade Bot实现加密货币交易自动化?从配置到运行的完整路径 【免费下载链接】binance-trade-bot Automated cryptocurrency trading bot 项目地址: https://gitcode.com/gh_mirrors/bi/binance-trade-bot 在加密货币交易领域,手动操…...

超图神经网络(HGNN)实战:从多模态数据构建到节点特征提取

超图神经网络实战:多模态数据融合与节点特征提取全流程解析 在电商推荐系统中,我们常常需要同时处理用户行为日志、商品图像和评论文本——这三种异构数据如何统一建模?传统图神经网络(GNN)在处理这类多模态关联时往往…...

OpenLiteSpeed实战踩坑记录:为什么我最终回归了LNMP环境?

OpenLiteSpeed实战反思:为什么复杂WordPress环境更适合LNMP? 最近在技术社区里,OpenLiteSpeed被频繁提及,尤其是它宣称的高性能PHP处理能力吸引了不少WordPress站长的注意。作为一个长期使用LNMP环境的开发者,我也被这…...

Python AI用例生成全链路实践(含12个工业级代码片段+GPT-4/Claude/Llama3对比基准)

第一章:Python AI用例生成全链路实践概览AI用例生成是将业务需求快速转化为可执行AI解决方案的关键环节,涵盖从问题定义、数据准备、模型选型、提示工程、评估验证到部署集成的完整闭环。本章聚焦基于Python生态的端到端实践路径,强调可复现性…...

一文搞懂:Agent、Harness Engineering、MCP、Skill 到底是什么

🧭 你是否被这些词搞晕过? Agent Harness Engineering MCP Skill Tool Workflow…… 大模型时代,新概念层出不穷。它们分别是什么?又如何协同工作? 这篇文章是你的概念地图。 大模型生态:四个核心概…...

C语言入门:了解历史与适用人群

要是您身为一名刚开始接触学习事物的人,再者您尚未弄明白何种属于编程语言,那就去瞧瞧这个了:什么是编程语言。 若您先前未曾接触过任何一种编程语言,或者您并不明白为何要是学习C语言来着,请看:为什么C语言…...

5大空间回收功能解决存储焦虑:Czkawka的极速扫描技术革命

5大空间回收功能解决存储焦虑:Czkawka的极速扫描技术革命 【免费下载链接】czkawka 一款跨平台的重复文件查找工具,可用于清理硬盘中的重复文件、相似图片、零字节文件等。它以高效、易用为特点,帮助用户释放存储空间。 项目地址: https://…...

VSCode 高效开发:配置 Pixel Dream Workshop 模型调用的代码片段与插件

VSCode 高效开发:配置 Pixel Dream Workshop 模型调用的代码片段与插件 1. 为什么需要优化开发工作流 如果你经常使用Pixel Dream Workshop这类AI模型进行开发,可能会遇到一个共同痛点:每次调用API时都要重复编写相似的请求代码&#xff0c…...

Sketchfab模型下载完整方案:3个核心技巧获取精美3D资源

Sketchfab模型下载完整方案:3个核心技巧获取精美3D资源 【免费下载链接】sketchfab sketchfab download userscipt for Tampermonkey by firefox only 项目地址: https://gitcode.com/gh_mirrors/sk/sketchfab 如果你经常在Sketchfab上发现惊艳的3D模型却无法…...

Python AI用例生成效率提升300%:从零搭建可复用的Prompt工程流水线

第一章:Python AI用例生成效率提升300%:从零搭建可复用的Prompt工程流水线在AI应用开发中,重复编写、调试和验证Prompt严重拖慢用例迭代速度。本章介绍一种基于Python的轻量级Prompt工程流水线,通过模板化、版本化与自动化执行三重…...

5分钟完成Windows平台Poppler PDF处理工具完整部署指南

5分钟完成Windows平台Poppler PDF处理工具完整部署指南 【免费下载链接】poppler-windows Download Poppler binaries packaged for Windows with dependencies 项目地址: https://gitcode.com/gh_mirrors/po/poppler-windows 在Windows系统上快速部署专业的PDF文档处理…...

GitOps实战:用ArgoCD监控GitLab仓库,实现K8s部署的“无人值守”与一键回滚

GitOps实战:ArgoCD与GitLab深度整合的自动化部署与回滚策略 1. GitOps核心价值:从理论到实践 在云原生技术快速发展的今天,GitOps已成为现代DevOps实践中不可或缺的一环。与传统CI/CD流程相比,GitOps将Git仓库作为唯一可信源&…...

5分钟搞定Netdata监控面板汉化:最新GitHub汉化包一键安装教程

Netdata监控面板极速汉化指南:从零到精通的完整解决方案 对于国内开发者而言,英文界面始终是技术工具使用中的一道隐形门槛。Netdata作为一款功能强大的实时监控工具,其全英文的仪表盘让不少运维人员望而却步。本文将带你彻底解决这一痛点&am…...

Audacity:免费开源的全能音频编辑与录制解决方案

Audacity:免费开源的全能音频编辑与录制解决方案 【免费下载链接】audacity Audio Editor 项目地址: https://gitcode.com/GitHub_Trending/au/audacity Audacity 是一款免费开源的音频编辑与录制软件,支持多轨录音、音频剪辑、效果处理等专业功…...

RDP Wrapper终极指南:解锁Windows多用户远程桌面完整功能

RDP Wrapper终极指南:解锁Windows多用户远程桌面完整功能 【免费下载链接】rdpwrap RDP Wrapper Library 项目地址: https://gitcode.com/gh_mirrors/rd/rdpwrap RDP Wrapper Library是一个革命性的开源工具,它能够让Windows家庭版用户也能享受到…...

Python 数据统计分析全攻略:从基础到实战,一文掌握常用方法

在数据分析、机器学习、业务报表开发等场景中,数据统计分析是核心基础环节。Python 凭借丰富的第三方库,成为数据统计分析的首选工具。本文将系统梳理 Python 中数据统计分析的常用方法、核心库、实战代码,从基础统计量到高级分析&#xff0c…...

运动控制选EtherCAT,过程控制用PROFINET?深入聊聊工业以太网协议背后的设计哲学与取舍

工业以太网协议的设计哲学:EtherCAT与PROFINET的技术抉择 在自动化生产线上,一个机械臂需要以0.1毫米的精度重复定位,而百米外的反应釜温度必须控制在0.5℃范围内——这两种看似相似的工业控制需求,背后却对应着完全不同的通信协议…...

直接上干货,咱们用粒子群算法给PID控制器做个暴力调参。传统PID参数调整像盲人摸象,PSO(粒子群优化)相当于派出一群带雷达的无人机直接扫描整片山区找最优解

基于粒子群算法的PID控制优化算法案例 matlab源代码 代码有详细注释,完美运行先看目标——让这个二阶系统达到最顺滑的响应: % 被控对象传递函数 sys tf(1, [1 3 2]); t 0:0.01:10; % 时间序列 粒子群的核心配置得够骚: %% PSO参…...

解锁小米平板5的Windows潜能:从Android平板到完整PC体验的驱动革命

解锁小米平板5的Windows潜能:从Android平板到完整PC体验的驱动革命 【免费下载链接】MiPad5-Drivers Based on Surface Duo Drivers. 项目地址: https://gitcode.com/gh_mirrors/mi/MiPad5-Drivers 你是否曾想过,将手中的小米平板5从一台Android设…...

Ice终极指南:3步打造Mac菜单栏的清爽工作空间

Ice终极指南:3步打造Mac菜单栏的清爽工作空间 【免费下载链接】Ice Powerful menu bar manager for macOS 项目地址: https://gitcode.com/GitHub_Trending/ice/Ice Ice是一款专为macOS设计的强大菜单栏管理器,能够帮助用户有效整理和优化混乱的菜…...

终极macOS菜单栏管理指南:从杂乱到整洁的完美蜕变 [特殊字符]

终极macOS菜单栏管理指南:从杂乱到整洁的完美蜕变 🚀 【免费下载链接】Ice Powerful menu bar manager for macOS 项目地址: https://gitcode.com/GitHub_Trending/ice/Ice macOS菜单栏是每个苹果用户每天都要面对的重要界面,但随着安…...

CMD脚本开发避坑指南:为什么你的bat文件总是报错?

CMD脚本开发避坑指南:为什么你的bat文件总是报错? 每次双击运行精心编写的bat文件时,看到那个刺眼的"不是内部或外部命令"错误提示,是不是感觉血压瞬间飙升?作为Windows系统中最基础的自动化工具&#xff0c…...

如何用 PyTorch Grad-CAM 快速掌握 CLIP 模型可视化分析:终极指南 [特殊字符]

如何用 PyTorch Grad-CAM 快速掌握 CLIP 模型可视化分析:终极指南 🎯 【免费下载链接】pytorch-grad-cam Advanced AI Explainability for computer vision. Support for CNNs, Vision Transformers, Classification, Object detection, Segmentation, I…...

SiameseUIE保姆级教程:3步部署nlp_structbert_siamese-uie_chinese-base

SiameseUIE保姆级教程:3步部署nlp_structbert_siamese-uie_chinese-base 信息抽取不再需要标注数据,一个模型搞定NER、关系抽取、事件抽取、情感分析四大任务 1. 什么是SiameseUIE?为什么值得一试 如果你正在处理中文文本信息抽取任务&#…...

ESP32开发终极指南:5个关键更新助你构建更强大的物联网设备

ESP32开发终极指南:5个关键更新助你构建更强大的物联网设备 【免费下载链接】arduino-esp32 Arduino core for the ESP32 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 ESP32 Arduino核心项目为ESP32系列芯片提供了完整的Arduino开发环境…...

GuwenBERT:古文自然语言处理的技术革新

GuwenBERT:古文自然语言处理的技术革新 【免费下载链接】guwenbert GuwenBERT: 古文预训练语言模型(古文BERT) A Pre-trained Language Model for Classical Chinese (Literary Chinese) 项目地址: https://gitcode.com/gh_mirrors/gu/guwe…...

终极AI图像增强神器Upscayl:让每一张照片重获新生

终极AI图像增强神器Upscayl:让每一张照片重获新生 【免费下载链接】upscayl 🆙 Upscayl - Free and Open Source AI Image Upscaler for Linux, MacOS and Windows built with Linux-First philosophy. 项目地址: https://gitcode.com/GitHub_Trending…...

保姆级教程:在ROS2 Humble和Gazebo 11中配置FAST_LIO_ROS2进行三维SLAM仿真

从零搭建ROS2与Gazebo环境:FAST_LIO_ROS2三维SLAM实战指南 刚接触机器人仿真的开发者常被环境配置的复杂性劝退——依赖冲突、参数配置错误、话题不匹配等问题层出不穷。本文将手把手带您完成ROS2 Humble、Gazebo 11与FAST_LIO_ROS2的完整集成,实现一个可…...