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 = 1或LIKE '%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批量处理案例


