一个项目中mysql数据库经常死锁的问题解决记录
1、问题描述
此项目为一个物流系统,需要使用PDA对货物进行入库、备货、出货等操作,在系统开发测试过程中,经常发现死锁问题。
有这样一种业务场景:仓库对备货单上货进行扫码备货后,点击”完成”以确定完成了该备货单,才能进行下一步的发车动作,也即是说,如果不对单进行”完成”动作,就无法进行发车。仓库使用人员经常反馈已经点击了完成,但是不生效。此问题很诡异,有时很正常,有时频繁发生,联系开发人员检查代码,检查网络,很久都没有解决,很是头疼。仓库使用较大意见,项目推进遇到很大阻力。
最后经过摸索,问题得到解决。因为问题重现比较难,自己测试的时候都无问题(还怀疑过使用人员是否误报),此问题的解决刚开始要等出现的时候观察,慢慢有点头绪,再通过脚本方式进行巡检,再分析,最终才得到解决。解决方法记录如下
2、问题分析过程
2.1、编写事务监控与锁冲突监控脚本
普及下如下三个表的作用
innodb_trx ## 当前运行的所有事务
innodb_locks ## 当前出现的锁
innodb_lock_waits ## 锁等待的对应关系
在出现问题的时候,通过观察innodb_trx发现,经常有一些事务执行很久,一直在执行,也不会关闭,同时观察innodb_locks表,会出现死锁现象
于是写了两个脚本分别对innodb_trx、innodb_locks表进行监控,脚本1每5秒钟记录innodb_trx的情况,脚本2每1分钟监控innodb_locks的情况,如果innodb_locks有数据代表有出现死锁
脚本1监控使用如下命令:此命令查询正在执行的事务,需要说明的是有事务不一定是有死锁,只是代表有一个事务在执行还未commit,本脚本不发告警邮件,只做记录
1 SELECT * FROM information_schema.INNODB_TRX\G;

脚本2监控使用如下命令:如果有锁冲突,此表会有数据,如果未锁表,此表为空。此脚本发现有死锁就发邮件通知,以便问题的及时核查
1 SELECT * FROM information_schema.INNODB_locks;

2.2、开启mysql的general日志
开启general log会将所有到达MySQL Server的SQL语句记录下来。一般不会开启此功能,因为log的量会非常庞大。
但个别情况下可能会临时的开一会儿general log以供排障使用。
相关参数一共有3:general_log、log_output、general_log_file
- general_log:全局动态变量,默认关闭
- log_output :全局动态变量,可取FILE、TABLE、NONE。其中TABLE存储方式比较方便按条件检索。若指定为NONE,则即使general_log开启了也不会记录log。若log_output指定为TABLE,则会在mysql数据库下边创建一个general_log表。需要注意的是该参数不仅仅影响general的存储方式还影响slow的存储方式,这一点需要特别注意。
- general_log_file:全局动态变量,日志文件名,不指定的话默认为hostname.log,位于数据目录下。
开启命令:
1 set global general_log=on
注:此命令是临时开启,如果mysql重启后回默认关闭
关闭命令:
1 set global general_log=off
2.3、核查分析
在出现死锁的时候,分别对general日志与脚本记录的innodb_trx数据进行分析,如下:

查看监控innodb_trx的日志情况,两个时间对了下(如上下图时间),确定了就是beihuovr存储过程执行才出现的这个一直执行的事务

分析:
同一个会话分别执行beihu和beihuovr存储过程出现问题,单独执行beihuovr没有问题,进一步分析beihu和beihuovr存储过程的内容
- beihuovr存储过程没有设置autocommit=0,既会自动提交
- beihu存储过程设置了autocommit=0,关闭了自动提交
按道理beihuovr这个存储过程的事务不会一直执行才对,那么就有一种可能,因为是同一个线程执行两个存储过程,可能是beihuovr存储过程继承了beihu存储过程的autocommit属性,存储过程里面也没有commit操作,导致这个存储过程的事务一直在执行。
3、解决办法
在每个存储过程的开始设置autocommit=1,问题解决。
一个项目中mysql数据库经常死锁的问题解决记录的更多相关文章
- 【原创】互联网项目中mysql应该选什么事务隔离级别
摘要 企业千万家,靠谱没几家. 社招选错家,亲人两行泪. 祝大家金三银四跳槽顺利! 引言 开始我们的内容,相信大家一定遇到过下面的一个面试场景 面试官:"讲讲mysql有几个事务隔离级别?& ...
- 互联网项目中mysql推荐(读已提交RC)的事务隔离级别
[原创]互联网项目中mysql应该选什么事务隔离级别 Mysql为什么不和Oracle一样使用RC,而用RR 使用RC的原因 这个是有历史原因的,当然要从我们的主从复制开始讲起了!主从复制,是基于什么 ...
- 互联网项目中mysql应该选什么事务隔离级别
引言 开始我们的内容,相信大家一定遇到过下面的一个面试场景 面试官:“讲讲mysql有几个事务隔离级别?” 你:“读未提交,读已提交,可重复读,串行化四个!默认是可重复读” 面试官:“为什么mysql ...
- 【转】互联网项目中mysql应该选什么事务隔离级别
作者:孤独烟 转自:https://www.cnblogs.com/rjzheng/p/10510174.html 摘要 企业千万家,靠谱没几家.社招选错家,亲人两行泪. 祝大家金三银四跳槽顺利! 引 ...
- 【转载】一个小时学会MySQL数据库
一个小时学会MySQL数据库 目录 一.数据库概要 1.1.发展历史 1.1.1.人工处理阶段 1.1.2.文件系统 1.1.3.数据库管理系统 1.2.常见数据库技术品牌.服务与架构 1.3.数 ...
- 连接云服务器中MySql数据库遇到的问题
使用的免费的云服务器,上面只能下载MySql数据库,不过当云数据库使用绰绰有余了,也就放一些测试数据而已 而且上面只可以部署php项目,.netcore项目部署实现比较麻烦 问题如下: 下载了navi ...
- XamarinSQLite教程在Xamarin.Android项目中使用数据库
XamarinSQLite教程在Xamarin.Android项目中使用数据库 在Xamarin.Android项目中使用预设数据库的具体操作步骤如下: (1)创建一个Xamarin.Android项 ...
- 更改XAMPP中MySQL数据库的端口号
更改XAMPP中MySQL数据库的端口号 如果电脑上已安装MySql数据库,还想用XAMPP中自带的数据库就需要更改XAMPP中数据库的端口号,避免和已安装的数据库冲突.本例以更改为3307端口号为例 ...
- XamarinSQLite教程在Xamarin.Android项目中提取数据库文件
XamarinSQLite教程在Xamarin.Android项目中提取数据库文件 由于不能直接打开该文件,开发者需要先将数据库文件从Android系统中提取出来.操作步骤如下. (5)选择MyDoc ...
随机推荐
- ubuntu如何安装或更换内核
内核是一个系统的灵魂,系统在启动的时候,就是基于相关的内核启动该系统的.我们怎么样更改ubuntu系统的内核并运行它呢? ubuntu18.04LTS 互联网安装内核. 安装内核的步骤非常简单,我们可 ...
- linux通用技巧集合
1.将程序置为后台进程运行,关闭终端程序继续运行 nohup ./test.sh & 2.列出当前后台运行的进程列表包括进程id jobs -l 3.根据进程id杀掉该进程 kill - pi ...
- C#高阶与初心:(一)List.Add添加的到底是什么?
前几日与同事讨论一个相对复杂的场景,需要先将中间过程存储在List中,稍后再用.同时程序类的许多线程共用了一个全局变量. 具体来说就是如下代码 ... _order = order1; _list.A ...
- ubuntu下core file文件生成及调试
1.简介:corefile 是Linux下程序崩溃时生成的文件,可以用来分析程序崩溃的原因,因为它内部包含了程序崩溃时的堆栈信息. 2.corefile的设置 默认情况下,程序崩溃是不会生成coref ...
- clientHeight scrollHeight offsetHeight
<div style="height:200px;padding:10px;border:1px solid green;"></div> 对于上面的di ...
- redis在php中的基本使用
//使用autoload加载相关库,这边重点就是为了require $file; spl_autoload_register(function($class) { $file = __DIR__.’/ ...
- osg shader 相机观察矩阵逆矩阵 求顶点世界坐标
uniform mat4 osg_ViewMatrixInverse;//osg内置uniform void main() { vec4 posWorld = osg_ViewMatrixInvers ...
- C# WinForm窗体控件GroupBox修改边框颜色控件
C# WinForm窗体控件GroupBox修改边框颜色控件 1.新建组件这里可以自定义一个GroupBox控件起名为GroupBoxEx 2.增加一个BoderColor属性 private Col ...
- 将VSCode添加到右键
https://www.cnblogs.com/Rexcnblog/p/8046371.html https://www.jianshu.com/p/b49002fa10a7 @echo Off :S ...
- vim 多窗口操作
1.打开多个窗口打开多个窗口的命令以下几个:横向切割窗口:new+窗口名(保存后就是文件名) :split+窗口名,也可以简写为:sp+窗口名纵向切割窗口名:vsplit+窗口名,也可以简写为:vsp ...