当前位置: 首页
数据库
MySQL意向锁为何能提高加锁效率

MySQL意向锁为何能提高加锁效率

热心网友 时间:2026-06-24
转载

意向锁使表级加锁无需逐行检查行锁状态,仅需读取表级IX IS标记即可判断兼容性,避免千万行表的随机I O开销。IS和IX彼此兼容,但IX会阻塞所有表级锁。意向锁本身不阻塞操作,长期存在需排查事务未提交问题。

意向锁的核心价值可以概括为一句话:它让表级加锁不再需要逐行检查行锁状态。如果没有意向锁,当你执行LOCK TABLES t WRITE时,InnoDB必须遍历每一行,确认是否已被其他事务锁定——这并非逻辑上的多此一举,而是兼容性判断的必要步骤。面对千万行级别的表,这将引发大量随机I/O,导致锁请求本身就能阻塞数秒。有了意向锁,事情变得简单:只需读取一次表级元数据。看到IX标记,就表明有行正在被修改,立即拒绝加表锁;看到IS标记,说明至少存在读操作,WRITE同样被拒绝,但READ可以放行。

为什么MySQL的意向锁(Intention Lock)能提高加锁效率?

### 意向锁解决的是“表级加锁时要不要扫全表行锁”这个问题 在没有意向锁的情况下,像LOCK TABLES t WRITE这类语句会真正尝试检查每一行是否被其他事务加了X锁——这并非逻辑上必然,而是兼容性兜底逻辑要求判断“整张表是否空闲”。对于千万行级别的表,这等于触发大量随机I/O,锁请求本身就会卡住数秒。意向锁将这个问题压缩为一次表级元数据读取:看到IX标记,即可确认有行正被修改,直接拒绝;看到IS标记,说明至少有行被读取,WRITE仍被拒绝,但READ可以放行。 ### IS 和 IX 锁的触发条件与常见误判点 你无法直接写出 LOCK TABLES ... IN INTENTION MODE 这类语句——意向锁完全由 InnoDB 自动添加,但其出现与否取决于语句类型: - SELECT ... LOCK IN SHARE MODE → 触发 IS 锁(同时在命中的行上加 S 锁) - INSERTUPDATEDELETESELECT ... FOR UPDATE → 触发 IX 锁(同时在命中的行上加 X 锁) - 未走索引的 UPDATEDELETE → 仍会加 IX,但会对全表每行添加 X 行锁,效果接近“伪表锁”,此时 IX 是真实瓶颈,而非假象 容易产生误判的地方:以为不加锁的SELECT就不会有意向锁——实际上,在REPEATABLE READ隔离级别下,只有SELECT ... LOCK IN SHARE MODE才会添加IS锁;而普通SELECTREAD COMMITTED下完全不会触发任何意向锁。 ### 意向锁兼容性真正影响的是表锁,不是行锁 许多人在查询performance_schema.data_locks时看到大量ISIX记录感到紧张,但实际上两者完全兼容:ISIX可以共存,多个只读事务或多个更新事务不会因此相互阻塞。真正影响表锁的兼容规则如下: - IS 允许 LOCK TABLES t READ,但拒绝 LOCK TABLES t WRITE - IX 拒绝所有表级锁:READWRITE 都会被阻塞 - IX 与行级 S 锁兼容,IS 与行级 X 锁兼容——这正是高并发能够成立的基础 DDL(如ALTER TABLE)被卡住,90%的情况是因为某个未提交事务持有IX锁,而不是SQL语句本身的错误。 ### 监控时只看 data_locks 会漏掉关键信息 SELECT object_schema,object_name,lock_type,lock_mode FROM performance_schema.data_locks WHERE lock_type = 'TABLE' 只能看到ISIX标记,但这仅仅是表面症状。真正需要排查的是背后的事务状态: - 使用SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX查看TRX_STATE是否为RUNNINGLOCK WAIT,并检查TRX_QUERY对应的具体语句 - 如果TRX_STATE = RUNNINGTRX_STARTED时间很长,通常是因为应用层未执行COMMIT或网络超时导致事务挂起 - INNODB_LOCK_WAITS能揭示锁等待关系,但仅在等待发生时有效;若IX长期存在却无等待,说明问题不在锁本身,而在事务生命周期管理上 意向锁本身从不阻塞任何操作,它只是一个标记。当看到它长期存在时,不要急于优化SQL,而应首先检查事务是否已经提交。
来源:https://www.php.cn/faq/2676367.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
不停服务修改主键字段的SQL实现方法

不停服务修改主键字段的SQL实现方法

直接修改MySQL主键会锁表并阻塞写入。不停服的关键是将锁时间压缩到秒级,可用pt-online-schema-change工具创建影子表同步数据后原子交换表名,或手动分步操作。PostgreSQL支持并发索引构建,主键变更更灵活。需同步更新外键、ORM和缓存。

时间:2026-07-19 08:39
phpMyAdmin左侧导航栏滚动条美化方法

phpMyAdmin左侧导航栏滚动条美化方法

phpMyAdmin左侧导航栏滚动条美化需通过修改navigation css文件或config inc php注入自定义样式。在文件中添加针对 serveritems容器的::-webkit-scrollbar规则可实现窄化、圆角与柔和配色。此方法仅对Chromium内核浏览器有效,Firefox不支持。修改后需清除浏览器缓存。

时间:2026-07-19 08:37
MySQL高并发写入索引过多导致性能抖动解决方案

MySQL高并发写入索引过多导致性能抖动解决方案

高并发写入时索引过多引发写放大,导致锁等待、刷脏压力及I O失衡。需通过Index_length与Data_length比值、Innodb_rows_inserted与Innodb_pages_written比值等确认问题。安全删除低频、重复及未命中索引,精简宽索引,优化字段类型及查询写法。若抖动未消,需检查innodb_flush_neighbors、主键

时间:2026-07-19 08:37
订单查询丢数据?原是WHERE条件惹的祸

订单查询丢数据?原是WHERE条件惹的祸

一条LEFTJOIN查询因将右表过滤条件写在了WHERE子句中,被优化器转换为内连接,导致左表数据被意外丢失。修复方法是将条件移至ON子句,即可保留外连接语义,保证左表数据完整返回。

时间:2026-07-19 08:37
Oracle存储过程并发更新行锁超时修复方法

Oracle存储过程并发更新行锁超时修复方法

解决Oracle并发更新锁超时需使用SELECTFORUPDATEWAIT显式控制等待超时,确保WHERE条件走索引避免锁升级。捕获ORA-30006或ORA-00054后采用指数退避重试最多三轮,否则降级为异步。列存表需注意CU级锁,建议改用行存表或批量合并更新。

时间:2026-07-19 08:05
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜