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数据库经常死锁的问题解决记录的更多相关文章

  1. 【原创】互联网项目中mysql应该选什么事务隔离级别

    摘要 企业千万家,靠谱没几家. 社招选错家,亲人两行泪. 祝大家金三银四跳槽顺利! 引言 开始我们的内容,相信大家一定遇到过下面的一个面试场景 面试官:"讲讲mysql有几个事务隔离级别?& ...

  2. 互联网项目中mysql推荐(读已提交RC)的事务隔离级别

    [原创]互联网项目中mysql应该选什么事务隔离级别 Mysql为什么不和Oracle一样使用RC,而用RR 使用RC的原因 这个是有历史原因的,当然要从我们的主从复制开始讲起了!主从复制,是基于什么 ...

  3. 互联网项目中mysql应该选什么事务隔离级别

    引言 开始我们的内容,相信大家一定遇到过下面的一个面试场景 面试官:“讲讲mysql有几个事务隔离级别?” 你:“读未提交,读已提交,可重复读,串行化四个!默认是可重复读” 面试官:“为什么mysql ...

  4. 【转】互联网项目中mysql应该选什么事务隔离级别

    作者:孤独烟 转自:https://www.cnblogs.com/rjzheng/p/10510174.html 摘要 企业千万家,靠谱没几家.社招选错家,亲人两行泪. 祝大家金三银四跳槽顺利! 引 ...

  5. 【转载】一个小时学会MySQL数据库

    一个小时学会MySQL数据库   目录 一.数据库概要 1.1.发展历史 1.1.1.人工处理阶段 1.1.2.文件系统 1.1.3.数据库管理系统 1.2.常见数据库技术品牌.服务与架构 1.3.数 ...

  6. 连接云服务器中MySql数据库遇到的问题

    使用的免费的云服务器,上面只能下载MySql数据库,不过当云数据库使用绰绰有余了,也就放一些测试数据而已 而且上面只可以部署php项目,.netcore项目部署实现比较麻烦 问题如下: 下载了navi ...

  7. XamarinSQLite教程在Xamarin.Android项目中使用数据库

    XamarinSQLite教程在Xamarin.Android项目中使用数据库 在Xamarin.Android项目中使用预设数据库的具体操作步骤如下: (1)创建一个Xamarin.Android项 ...

  8. 更改XAMPP中MySQL数据库的端口号

    更改XAMPP中MySQL数据库的端口号 如果电脑上已安装MySql数据库,还想用XAMPP中自带的数据库就需要更改XAMPP中数据库的端口号,避免和已安装的数据库冲突.本例以更改为3307端口号为例 ...

  9. XamarinSQLite教程在Xamarin.Android项目中提取数据库文件

    XamarinSQLite教程在Xamarin.Android项目中提取数据库文件 由于不能直接打开该文件,开发者需要先将数据库文件从Android系统中提取出来.操作步骤如下. (5)选择MyDoc ...

随机推荐

  1. Oracle中判断字段是否为数字

    在我们平常的开发中可能会遇到这样的问题,就是判断某一列是否全部由数字组成,我们都知道oracle并没有给我们提供这样一个现成的函数,那么根据我的经验我总结了两个行之有效的方法(列名:column,表名 ...

  2. [加密]openssl之数字证书签名,CA认证原理及详细操作

    转自:http://blog.sina.com.cn/s/blog_cfee55a70102wn3h.html 1 公钥密码体系(Public-key Cryptography) 公钥密码体系,又称非 ...

  3. Oracle分析函数-统计(sum、avg、max、min)

    很多需求中都涉及到统计:均值.累计.范围均值.相邻记录比较等.这些操作会统计多次,或有明确的统计范围,或返回的记录统计的数据集不同... 根据场景不同可分为如下几类: 1. 全统计 2. 滚动统计 3 ...

  4. awd入门教程

    (转自:awk入门教程 - 阮一峰) 以下为正文 ———————————————————— awk是处理文本文件的一个应用程序,几乎所有 Linux 系统都自带这个程序. 它依次处理文件的每一行,并读 ...

  5. 分析“HTTP500内部服务器错误”解决方法

    系统中出现的一些故障是用户最不想看到的,有时候遇到一些故障都到折腾个大半天才能够搞定.打开网站出现了HTTP500内部服务器错误的提示,无法法查看错误的详细信息,用户也没办法根据具体的问题来解决,这对 ...

  6. python 字符编码判断 chardet评测

    之前一直想找到一个模块,针对字符判断是什么字符集编码的库 网上有chardet的blog,发现自己的环境有这个库,于是就做了测试 >>> import chardet >> ...

  7. 当我们直接打印定义的对象的时候,隐含的是打印toString()的返回值。

      以下介绍的三种方法属于Object: (1)  finalize方法:当一个对象被垃圾回收的时候调用的方法. (2)  toString():是利用字符串来表示对象. 当我们直接打印定义的对象的时 ...

  8. mysql 存储过程、循环

    CREATE PROCEDURE questionProc() BEGIN declare pgId ); declare pGuid varchar(); -- 定义游标卡尺 declare don ...

  9. C#实现复杂XML的序列化与反序列化

    已知.xml(再此命名default.xml)文件,请将其反序列化到一个实例对象. Default.XML文件如下: <?xml version="1.0" encoding ...

  10. shell脚本学习笔记(符号)

    shell脚本的学习: 1.Shell的作用是解释运行用户的命令,用户输入一条命令,Shell就解释运行一条,这样的方式称为交互式(Interactive),Shell还有 一种运行命令的方式称为批处 ...