mysql行锁等待异常

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql行锁等待异常相关的知识,希望对你有一定的参考价值。

生产环境的Innodb_row_lock_current_waits参数一直是6,查看processlist和innodb_trx中均未发现有锁等待的情况,这是怎么回事

根据我之前接触到的此类问题,大致可以分为以下几种原因:
1. 程序中非数据库交互操作导致事务挂起
将接口调用或者文件操作等这一类非数据库交互操作嵌入在 SQL 事务代码之中,那么整个事务很有可能因此挂起(接口不通等待超时或是上传下载大附件)。
2. 事务中包含性能较差的查询 SQL
事务中存在慢查询,导致同一个事务中的其他 DML 无法及时释放占用的行锁,引起行锁等待。
3. 单个事务中包含大量 SQL
通常是由于在事务代码中加入 for 循环导致,虽然单个 SQL 运行很快,但是 SQL 数量一大,事务就会很慢。
4. 级联更新 SQL 执行时间较久
这类 SQL 容易让人产生错觉,例如:update A set ... where ...in (select B) 这类级联更新,不仅会占用 A 表上的行锁,也会占用 B 表上的行锁,当 SQL 执行较久时,很容易引起 B 表上的行锁等待。
5. 磁盘问题导致的事务挂起
极少出现的情形,比如存储突然离线,SQL 执行会卡在内核调用磁盘的步骤上,一直等待,事务无法提交。
综上可以看出,如果事务长时间未提交,且事务中包含了 DML 操作,那么就有可能产生行锁等待,引起报错。
参考技术A 锁等待..不一定就是锁表了..你这个是行级锁...追问

请问如何获取这6个行级锁的信息?

追答

show engine innodb status\G 里面内容很多..仔细找下...一般for update就是在等锁中

追问

看过了,没有for update状态

追答

看一下TRANSACTION 或者SSION里面的内容....不一定非得是for updare

追问

都看了,都是cleaning up。information下的innodb_lock_waits和innodb_locks都为空。数据库版本是5.6.10.

追答

5.6的啊? 5.6的没研究过不知道是不是有改善...
其实一般情况下锁等待很正常..mysql的行级锁其实很烦躁...那就看下慢查询..会不会有 for update?
曾经遇到过..因为开发的sql语句问题..导致一直锁着..

追问

慢日志我每周都看的,没有。关键是这个6个行锁,至少Innodb_row_lock_current_waits参数反映的,存在了个把月了,感觉不把这个坑填了,以后还会掉进去

追答

吧你的show engine innodb status\G贴出来看下...

mysql存储过程出现锁表锁行的情况怎么解决

行锁的等待

在介绍如何解决行锁等待问题前,先简单介绍下这类问题产生的原因。产生原因简述:当多个事务同时去操作(增删改)某一行数据的时候,MySQL 为了维护 ACID 特性,就会用锁的形式来防止多个事务同时操作某一行数据,避免数据不一致。只有分配到行锁的事务才有权力操作该数据行,直到该事务结束,才释放行锁,而其他没有分配到行锁的事务就会产生行锁等待。如果等待时间超过了配置值(也就是 innodb_lock_wait_timeout 参数的值,个人习惯配置成 5s,MySQL 官方默认为 50s),则会抛出行锁等待超时错误。


如上图所示,事务 A 与事务 B 同时会去 Insert 一条主键值为 1 的数据,由于事务 A 首先获取了主键值为 1 的行锁,导致事务 B 因无法获取行锁而产生等待,等到事务 A 提交后,事务 B 才获取该行锁,完成提交。这里强调的是行锁的概念,虽然事务 B 重复插入了主键,但是在获取行锁之前,事务一直是处于行锁等待的状态,只有获取行锁后,才会报主键冲突的错误。当然这种 Insert 行锁冲突的问题比较少见,只有在大量并发插入场景下才会出现,项目上真正常见的是 update&delete 之间行锁等待,这里只是用于示例,原理都是相同的。


三、产生的原因根据我之前接触到的此类问题,大致可以分为以下几种原因

参考技术A 首先synchronized不可能做到对某条数据库的数据加锁。它能做到的只是对象锁。
比如数据表table_a中coloum_b的数据是临界数据,也就是你说的要保持一致的数据。你可以定义一个类,该类中定义两个方法read()和write()(注意,所有有关该临界资源的操作都定义在这个类中),再定义一个静态变量作为锁就可以了。本回答被提问者采纳

以上是关于mysql行锁等待异常的主要内容,如果未能解决你的问题,请参考以下文章

mysql存储过程出现锁表锁行的情况怎么解决

mysql 开发进阶篇系列 13 锁问题(关于表锁,死锁示例,锁等待设置)

MySQL巡检查看参数

MySQL 行锁表锁

MySQL锁机制 -- 行锁

mysql innodb 行锁解锁后出现死锁