mysql数据库锁的基本概念_mysql锁入门解析

发布时间 - 2026-02-03 00:00:00    点击率:
锁的是索引项而非数据行;InnoDB行级锁实际作用于聚簇索引或二级索引记录,无索引时锁全表索引项,导致等效表锁。

锁到底锁的是什么?不是数据行,而是索引项

MySQL 的行级锁(尤其是 InnoDB)**不直接锁数据行,而是锁索引上的记录**。哪怕你没建任何索引,InnoDB 也会创建一个隐藏的聚簇索引(GEN_CLUST_INDEX),所有行锁都落在这个索引结构上。

这意味着:

  • 用主键(如 WHERE id = 100)更新,只在聚簇索引上加一把 X 锁;
  • 用二级索引(如 WHERE name = 'Alice')更新,则先在 name 索引上加 X 锁,再回表到聚簇索引上对对应主键加 X 锁——共两把锁;
  • 如果 WHERE 条件没走索引(例如 WHERE status+0 = 1LIKE '%abc'),InnoDB 无法精准定位,会退化为扫描全表,并对**每条匹配记录的聚簇索引项加锁**,极端情况下等效于锁整张表。

共享锁 vs 排他锁:什么时候该用 LOCK IN SHARE MODE

S 锁(共享锁)和 X 锁(排他锁)是底层基础,但日常开发中你几乎不会手动加 S 锁——除非你需要显式阻塞其他写操作,同时允许并发读。

典型场景是「防超卖」中的读-改-写闭环:

  • 普通 SELECT 是一致性读(MVCC),不加锁,可能读到旧库存;
  • SELECT stock FROM goods WHERE id = 123 LOCK IN SHARE MODE,能确保读到当前最新值,且阻止其他事务对这行加 X 锁(即不能扣减);
  • 后续紧跟 UPDATE goods SET stock = stock - 1 WHERE id = 123,此时已持有 S 锁,InnoDB 会自动升级为 X 锁完成更新;
  • 若跳过 LOCK IN SHARE MODE 直接 UPDATE,虽也加 X 锁,但中间存在窗口:两次请求可能同时读到 stock=1,然后都执行 -1 → 变成 -1。

别被“行锁”骗了:为什么 UPDATE 有时卡住整张表?

InnoDB 的“行锁”只是默认行为,**是否真锁单行,完全取决于执行计划是否命中索引**。

常见踩坑点:

  • UPDATE users SET status = 1 WHERE phone LIKE '%138%':无索引 + 模糊前缀 → 全表扫描 → 对每行聚簇索引加 X 锁 → 等效表锁;
  • UPDATE orders SET paid = 1 WHERE created_at > '2025-01-01':若 created_at 无索引,同样锁全表;
  • 复合查询中用了函数:WHERE DATE(create_time) = '2025-01-01' → 索引失效 → 锁范围扩大;
  • 即使有索引,若统计信息过期(ANALYZE TABLE 未执行),优化器也可能误判为全

    表扫描。

全局锁 FLUSH TABLES WITH READ LOCK 的真实代价

它确实能保证备份一致性,但代价是整个实例只读——所有 DML、DDL、甚至 COMMIT 都会被阻塞,业务写入直接挂起。

所以生产环境慎用,尤其高流量系统:

  • mysqldump --single-transaction 是更优解(依赖 MVCC,仅对 InnoDB 有效),它不加全局锁,靠事务快照保证一致性;
  • FLUSH TABLES WITH READ LOCK 主要用于 MyISAM 表或混合引擎库的备份;
  • 执行后必须配对 UNLOCK TABLES,否则锁一直挂着——曾有案例因忘记解锁,导致线上订单积压数小时;
  • 注意:它不阻塞 SELECT,但会阻塞任何修改元数据的操作(比如 ALTER TABLE),而这类操作常被运维后台静默触发。

锁机制不是黑盒,它的行为直接受索引设计、SQL 写法、隔离级别共同决定。最危险的不是锁本身,而是你以为加了行锁,实际锁了一片索引范围,甚至整张表。


# mysql  # go  # ai  # 为什么  # 2025  # sql  # select  # date  # 并发  # table  # 数据库  # 的是  # 读到  # 整张  # 上加  # 加锁  # 主键  # 闭环  # 也会  # 尤其是  # 什么时候 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何在万网自助建站中设置域名及备案?  Linux系统命令中screen命令详解  潮流网站制作头像软件下载,适合母子的网名有哪些?  HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】  laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法  iOS中将个别页面强制横屏其他页面竖屏  Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册  JS碰撞运动实现方法详解  如何在 React 中条件性地遍历数组并渲染元素  Laravel如何处理表单验证?(Requests代码示例)  Laravel Fortify是什么,和Jetstream有什么关系  Laravel Debugbar怎么安装_Laravel调试工具栏配置指南  php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】  Laravel怎么为数据库表字段添加索引以优化查询  英语简历制作免费网站推荐,如何将简历翻译成英文?  php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】  EditPlus中的正则表达式 实战(2)  高端网站建设与定制开发一站式解决方案 中企动力  javascript基于原型链的继承及call和apply函数用法分析  如何用VPS主机快速搭建个人网站?  惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?  Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理  如何在IIS中新建站点并配置端口与物理路径?  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  专业商城网站制作公司有哪些,pi商城官网是哪个?  html5的keygen标签为什么废弃_替代方案说明【解答】  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  Android滚轮选择时间控件使用详解  Python面向对象测试方法_mock解析【教程】  Laravel怎么判断请求类型_Laravel Request isMethod用法  消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工  QQ浏览器网页版登录入口 个人中心在线进入  零服务器AI建站解决方案:快速部署与云端平台低成本实践  如何在IIS管理器中快速创建并配置网站?  Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】  Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程  如何安全更换建站之星模板并保留数据?  如何在七牛云存储上搭建网站并设置自定义域名?  极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?  Laravel如何实现多对多模型关联?(Eloquent教程)  Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程  重庆市网站制作公司,重庆招聘网站哪个好?  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  如何快速查询域名建站关键信息?  Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】  Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】  Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  Laravel中间件如何使用_Laravel自定义中间件实现权限控制  Python自动化办公教程_ExcelWordPDF批量处理案例