当前位置: 首页 > news >正文

一个程序入库出现死锁问题的排查

某虚拟化部署的服务群,发现其中一个程序在写数据库时,经常有死锁现象,一旦出现,持续时间长达数分钟。当时没时间排查,一直到年底才解决。后面又忙,直到月底才有点时间总结。抛开起初没找到问题的时间外,花了几天解决了问题,虽然没有很难的技术问题,但过程还是值得记录的。本文从后来者角度总结一下解决问题的过程,不涉及代码。

由于本文没有技术含量,请谨慎按需阅读。

起因

从前2个月开始,就收到反馈,数据上传不及时。具体表现是我负责的一个用Golang语言写的数据入库程序断续出现死锁,提示信息如下:

Error 1205: Lock wait timeout exceeded; try restarting transaction

因为有很多个服务连接同一数据库,无法定位到具体原因,排查不到问题。

排查及解决

问题定位

本节根据时间顺序结合排查结果描述解决过程。

经查,在该服务群部署之初,数据库日志就显示有几个警告,如[Warning] [MY-010055] [Server] IP address '192.18.18.168' could not be resolved: Temporary failure in name resolution。至今也有,所以应该不是关键问题。

在出现死锁时,登录mysql,使用select * from processlist where command!='Sleep';查看进程列表,发现我写的程序里的几条插入sql语句明显卡在那里,除此外,还有外部IP进行的select操作,还有本服务器上几个进程进行的select和update操作。

拿其它地方的服务器配置和程序版本来做对比,内存、CPU方面相差不多,自己所了解到的连接数据库的程序版本是一样的,所用的docker镜像ID也是一样的。

此时,问题排查卡住了,接着忙于其它项目,一直到年底。

元旦收假第一天上班,业主上报到领导处,上峰过问,所以必须解决。

我写的程序是入库,还有另外程序是读库传输。于是打电话咨询相关开发人员,但由于刚接不久,问不到问题。

又回到数据库列锁问题上。以个从能力水平,看不到问题,于是联系DBA寻求帮忙,DBA提到一个概念:间隙锁。上网查了一下,的确有这个概念,大意是如果有select操作,数据库会将邻近的数据记录锁住,防止幻读情况出现。前面提到,出现死锁时,数据库有insert、update、select操作,而且极可能是相同的表——因为不同程序,是通过数据库做数据中转站的。此外,DBA还说,如果在select或update过程耗时,那么极可能出现死锁,解决办法是加索引,将耗时降低。

解决方法

于是联系相关开发人员,得到程序会在某个时候进行update操作,观察其语句,是使用一个大ID和和小ID进行update的,其中匹配大ID的数据记录有数十至数百条不等(小ID只匹配一条),而update操作只是更新其中一条数据记录。但是,对大ID没有做索引。

基本定位到问题了。本来想让相关程序的开发人员进行加索引的,但个人推不动,于是直接上手到生产环境上的数据库加索引。先停止我写的程序——因为这个程序是直接写库的,再登录数据库,找到对应的表,建索引。示例语句如下:

show index from foobar;
CREATE INDEX idx_foobar_my_id_dataid_state ON laneheartbeat (my_id, dataid, state);

其中一张表数据量大,建立索引大概耗时几分钟,当时就慌了,以为出事故了,还好一切正常。

接着重启程序,观察日志,入库正常。后面观察了3天日志,都没有出现exceeded。问题基本解决。

接着在其它服务集机器上对数据库的表都建立相同的索引。

反馈

后来了解到,在数据表建立索引的事,其实相关开发人员已经做了测试验证,性能的确提升了很多,可能担心影响,没继续进行。只是个人没想到问题的原因,没问别人,别人也没共享信息。经此事后,也加强了这方面问题的排查和知识的积累。

因为问题直接表现在我负责的程序,也因为数据库方面的确不行,所以花了几天时间。但对业主来说,从问题产生到解决,已经用了近3个月了。

小结

回顾发现,本文遇到的问题,就是数据库的索引正确建立,导致操作耗时,加上多个程序同时操作数据库,因间隙锁机制,出现死锁。建立索引即可解决。

http://www.lryc.cn/news/291081.html

相关文章:

  • 记录解决报错--These dependencies were not found jsencrypt lodash-es
  • 【极数系列】Flink集成DataSource读取集合数据(07)
  • React hooks子组件暴露方法示例
  • 数据结构:大顶堆、小顶堆
  • 电加热热水器上架亚马逊美国站需要的UL174报告
  • 使用visual studio写一个简单的c语言程序
  • 怎么创建facebook广告
  • pdf怎么转成高清图?pdf在线转换器推荐分享
  • postgresql 查询缓慢原因分析
  • N65总账凭证管理凭证查询(sql)
  • 投资1300万欧元!芬兰正式启动量子旗舰项目
  • 【3分钟开服】幻兽帕鲁服务器一键部署保姆教程
  • PandaWallet :Web3.0世界的入口
  • 微软Azure-openAI 测试调用及说明
  • java 图书管理系统 spring boot项目
  • Ubuntu系统安装 Redis
  • 简单记录一下如何安装python以及pycharm(图文教程)(可供福建专升本理工类同学使用)
  • 浏览器内存泄漏排查指南
  • ClickHouse(22)ClickHouse集成HDFS表引擎详细解析
  • idea报错 :(java: 找不到符号)
  • 设计软件最重要的目标是可理解性?
  • 酒店|酒店管理小程序|基于微信小程序的酒店管理系统设计与实现(源码+数据库+文档)
  • C++ 数论相关题目,博弈论,SG函数,集合-Nim游戏
  • ​学者观察 | 区块链技术理论研究与实践观察——中央财经大学朱建明
  • 使用Promethues+Grafana监控Elasticsearch
  • 研学活动报名平台源码开发方案
  • 一篇文章,彻底理解数据库操作语言:DDL、DML、DCL、TCL
  • Linux编辑器之vim的使用
  • 制作OpenSSH 9.6 for openEuler 22.03 LTS的rpm升级包
  • DNS配置文件讲解