Mysql for update导致大量行锁的问题

 更新时间:2023年08月29日 09:57:30   作者:tingmailang  
这篇文章主要介绍了Mysql for update 导致大量行锁的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、引言

最近同事的复盘会上提到自己for update一个不存在的where条件导致表锁,然后产生大量的事务失败和读写超时,这时博主非常奇怪,因为虽然网上许多博客写Innodb的表锁行锁与锁升级,但是事实上这都是错误的观点。

二、分析

首先博主的环境是Mysql5.7,隔离级别是RC

博主为什么说这些都是错误的观点呢?

因为在《高性能Mysql》和《Innodb存储引擎当中》,非常明确的提出:

1、Innodb不存在锁升级

所以不存在因为锁的数据量大或者多表,导致行锁升级成表锁。

2、当for update一个不存在的where条件时

Innodb加的是Record级别锁

这一点可以通过验证得到

  • 不存在的where:
set autocommit = 0 ;
begin;
select * from t_aac_battery_compensate  where gmt_create  in ('2020-05-21 07:02:37') for update ;
  • 存在的where:
begin;
select * from t_aac_***  where gmt_create  in ('2020-05-21 07:32:37') for update ;

然后执行

select * from information_schema.INNODB_LOCKS il 

可以看到锁

可以看到两个事务加的都是行级别锁。

可能有的同学会对锁住的行数量和数据有疑惑,这里博主发现这两个数值统计的方式是不准的,包括在《Innodb存储引擎》作者明确提出lock_data是不准确的。

也有的同学疑惑他加行锁为什么会阻塞其他读写,这里是innodb加了行锁之后最后一起释放,虽然不知道它这样的设计是出于什么考虑。

3、Innodb如果在索引中找不到记录

会在行数据进行搜索,锁住主键,而不是锁表

所以一些博客说根据索引加不到锁,innodb就会锁全表,这是错误的理解

只是可能在一些情况下他搜索行数据对主键加锁的数量过多,之前也说了innodb加行锁是最后一起释放的,所以阻塞了其他读写

4、Innodb加锁的方式是从上到下的

自动加锁只有表级别的意向锁和行级锁,表级别的意向锁只会阻塞全表扫描

5、RR级别加锁情况

上文都是基于博主线上环境配置,如果是RR隔离级别,还会有GapLock与行锁进行Next_keyLock算法加锁,其实简单说就是锁住当前B+树种当前索引到上一个索引之间(或当前行到上一行)的间隔,防止在这个过程中有插入数据,也就是防止幻读。

但是这个情况不是绝对的,对于唯一索引,innodb会降低级别行级锁,不会锁住范围

三、总结

通过以上分析得到结论:

1、RC级别下innodb都是行级锁,表级的意向锁只会阻塞全表扫描

2、innodb不存在锁升级

3、innodb加不到索引会搜索行,对主键加锁

4、当for update一个不存在的where条件时,Innodb加的是Record级别锁

以上分析除了实际操作验证和权威书籍理解之外,博主与DBA也经过深入探讨,如果有异议欢迎讨论。 另外希望各位同学,多实际操作、多看权威书籍和源码,对于网上的博客看一半信一半,要有自己的判断,书籍和源码的查看也要结合实际经验,因为每个人的脑回路是不一样的,一不小心理解方向就可能歪了。

好了,这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 与MSSQL对比学习MYSQL的心得(四)--BLOB数据类型

    与MSSQL对比学习MYSQL的心得(四)--BLOB数据类型

    在MYSQL中BLOB是一个二进制大对象,用来储存可变数量的数据,而MSSQL中并没有BLOB数据类型,只有大型对象数据类型(LOB)
    2014-06-06
  • mac安装mysql数据库及配置环境变量的图文教程

    mac安装mysql数据库及配置环境变量的图文教程

    本文主要介绍了mac安装mysql数据库及配置环境变量,文中通过图文代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • MySQL中查询、删除重复记录的方法大全

    MySQL中查询、删除重复记录的方法大全

    mysql中删除重复记录的方法有很多种,下面这篇文章主要给大家总结了在MySQL中查询、删除重复记录的方法大全,文中给出了详细的示例代码供大家参考学习,需要的朋友下面来一起看看吧。
    2017-06-06
  • mysql数据库查询优化 mysql效率

    mysql数据库查询优化 mysql效率

    MySQL由于它本身的小巧和操作的高效, 在数据库应用中越来越多的被采用.我在开发一个P2P应用的时候曾经使用MySQL来保存P2P节点,由于P2P的应用中,结点数动辄上万个,而且节点变化频繁,因此一定要保持查询和插入的高效.以下是我在使用过程中做的提高效率的三个有效的尝试. 1. 使用statement进行绑定查询 2. 随机的获取记录 3. 使用连接池管理连接.
    2008-01-01
  • SQL NULL值的定义测试处理空数据及SQL UPDATE语句使用详解

    SQL NULL值的定义测试处理空数据及SQL UPDATE语句使用详解

    这篇文章主要为大家介绍了SQL NULL值的定义测试处理空数据及SQL UPDATE语句使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 设置MySQLroot账户密码报错ERROR 1064 (42000): You have an error in your SQL syntax;的解决方案

    设置MySQLroot账户密码报错ERROR 1064 (42000): You 

    在安装mysql的时候,设置root账户密码出现了ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds..错误,本文小编给大家介绍了相关的解决方案,需要的朋友可以参考下
    2023-12-12
  • MySQL如何使用limit获取最后一条记录

    MySQL如何使用limit获取最后一条记录

    这篇文章主要介绍了MySQL如何使用limit获取最后一条记录问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • mysql limit分页优化方法分享

    mysql limit分页优化方法分享

    MySQL的优化是非常重要的。其他最常用也最需要优化的就是limit。MySQL的limit给分页带来了极大的方便,但数据量一大的时候,limit的性能就急剧下降。
    2011-04-04
  • windows下mysql 8.0.16 安装配置方法图文教程

    windows下mysql 8.0.16 安装配置方法图文教程

    这篇文章主要为大家详细介绍了windows下mysql 8.0.16 安装配置方法图文教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • 关于Mysql5.7及8.0版本索引失效情况汇总

    关于Mysql5.7及8.0版本索引失效情况汇总

    这篇文章主要介绍了关于Mysql5.7及8.0版本索引失效情况汇总,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08

最新评论