mysql死锁和分库分表问题详解
来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习数据库相关编程知识。下面本篇文章就来带大家聊聊《mysql死锁和分库分表问题详解》,介绍一下MySQL死锁、分库分表,希望对大家的知识积累有所帮助,助力实战开发!
记录生产mysql的问题点。
业务场景与问题描述
请求一个外部接口时,每天的请求量在900万左右。
分为请求项目和回执这两个项目。请求是用来调用外部接口,回执是接收发送的接口。
在发送请求前会先插入数据库。
在请求后,如果接口返回调用失败,会更新数据库状态为失败。
如果发送成功,则会等待上游给出回执消息后,然后更新数据库状态。
而在生产运行过程中,半年出现过两次mysql导致的mq消费者堆积的问题。
问题分析
记录两次不同的原因导致的生产问题及原因分析。
mysql死锁问题
查看mq聚合平台TPS
上生产发现mq数据一直堆积,且不断上升。而TPS仅为30左右,一直上不去。
这就会使mq消费变慢了,导致不断堆积。具体什么原因导致mq一直堆积,需要继续排查。
查看生产服务器日志
查看生产服务器日志,发现有报错dead Lock的错误。
error response from MySQLConnection [node=24, id=277499, threadId=2735941, state=borrowed, closed=false, autocommit=true, host=10.1.10.74, port=3306, database=sep_4, localPort=27744, isClose:false, toBeClose:false, MySQLVersion:5.7.25], err: Deadlock found when trying to get lock; try restarting transaction, code: 1213
具体的sql如下:
update stage set status = 'success',reply_time = '2021-03-07 10:40:11' where code = '000123' and create_time > '2021-03-03 00:00:00';
也就是说在执行服务时出现了死锁的情况。
具体有多少条以及耗时,在生产服务器看着不直观,于是就让dba将慢sql的语句和耗时查出来。
查出后发现最长的慢sql的耗时长达7780ms。
仔细查看会发现,sql会发现相同的id一个在执行中,一个在Lock Wait状态。
而这慢sql中有大量的Lock Wait状态。
什么原因导致的死锁
mysql使用的数据库引擎时InnoDB。先了解下什么是死锁:
所谓死锁: 是指两个或两个以上的进程在执行过程中,
因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.
此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等竺的进程称为死锁进程.
通过上面的排查可以看出,出现死锁的问题就是:
在执行sql更新一条数据时,会将这一行数据锁定,执行完成后会释放行锁,而没有执行的sql处于Lock Wait状态。
而程序中导致此原因在于,在发送前后和回执时,频繁操作数据库,可能会出现同时操作同一条数据的情况。
所以在执行中就出现了锁等待的情况。
分库分表未带分片键
首先告警的是stage_prod库的CPU飙到了85%。
数据库线程数是否被打满
经过查看数据库连接情况可知,数据库连接数并没有被占满。
查出慢sql和耗时
查出的问题sql:
update stage set status = 'success',reply_time = '2021-03-07 10:40:11' where create_time > '2021-03-03 00:00:00';
查看sql会发现,这条sql竟然没有带分片键code字段。而这条sql是回执时执行的。
排查生产服务器日志
代码中有做判断,如果code值不为空,sql会带上code的值。那么没带上,就需要查看为何没有带上。
查看代码会发现,code是从redis中获取的,是在发送时set到redis中的。但是没有set进去就很奇怪了。
初步怀疑是redis问题,然后就与redis维护的平台沟通,发现果真是因为redis故障导致的问题。
为什么不带分片键CPU就会飙升
首先公司用的是hotdb分库分表,因为每天的入库量是在900万左右,一个表是上亿条数据。
如果只是单纯用索引,是无法满足要求的。
分库分表hotdb,根据code值做hash分片,做了64个分片。也就是说64个数据库,分布在8台服务器上的16个实例里面。
这样可以避免各分片数据不均,理论上避免了过度集中在某个分片上。
而如果不带分片键code的sql,所有的dml操作全部下发到所有的底层库上进行执行,相当于遍历了一遍库。
这样就可能会导致CPU直接飙到99%,甚至直接导致服务器直接崩掉,这样操作是很可怕的。
解决办法
应急处理:先停掉几台服务减少数据库操作
数据持续堆积,会影响数据处理速度。那么,就要先降低操作的速度,最快速的办法就是停服务,减少数据库的操作频率。
减少数据库操作避免数据库死锁
死锁一般时由于程序上没有控制好dml操作的提交,没有及时提交.
减少重复操作同一条数据。在批量操作时减少每批dml数,保证快速提交,避免长事务,避免重复提交dml。
那么怎样减少操作呢?
合并sql
将发送前插入和发送失败时更新,直接合并到一条sql,这样就可以避免多次操作同一条数据的情况。
批量执行时减少长事务和条数
执行时发现,每次批量执行20条sql,比一次性执行200条的效率更快。
所以尽可能避免这种问题。
每条sql必须带分库分表分片键
原则就是不能因为一条数据就拖累整个数据库的操作速度。
分片键必须带上,如果不带分片键,就抛错。
增加时间区间开闭区间
用code来做分片键,用createTime做分区。那么在保证code存在的情况下,可以写上开闭区间,可以提高执行效率。
更优解:sql顺序执行
这种方案可以通过把将要执行的sql统一发到一个mq来消费执行,这样可以保证sql顺序执行,从而避免死锁的产生。
但是这个需要根据业务场景来区分。
复盘
mysql死锁问题,要尽可能避免频繁操作同一条数据,也要避免长事务;
针对分库分表问题,一定要带上分片键;
监控机制不可少;
总结
以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于数据库的相关知识,也可关注golang学习网公众号。

- 上一篇
- MySQL性能压力基准测试工具sysbench的使用简介

- 下一篇
- MySQL Innodb关键特性之插入缓冲(insert buffer)
-
- 酷酷的热狗
- 很棒,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢作者分享技术贴!
- 2023-01-14 02:28:56
-
- 傻傻的玫瑰
- 这篇技术文章出现的刚刚好,好细啊,真优秀,收藏了,关注作者了!希望作者能多写数据库相关的文章。
- 2023-01-09 20:14:15
-
- 数据库 · MySQL | 1小时前 |
- MySQL排序优化与性能提升技巧
- 368浏览 收藏
-
- 数据库 · MySQL | 16小时前 |
- MySQL连接池配置与优化方法
- 297浏览 收藏
-
- 数据库 · MySQL | 17小时前 |
- MySQLGROUPBY使用技巧与常见问题
- 306浏览 收藏
-
- 数据库 · MySQL | 19小时前 |
- MySQL缓存优化技巧分享
- 392浏览 收藏
-
- 数据库 · MySQL | 20小时前 |
- MySQL安装到D盘教程及路径设置详解
- 279浏览 收藏
-
- 数据库 · MySQL | 22小时前 |
- MySQL缓存设置及查询作用解析
- 470浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQLcount优化技巧及性能提升方法
- 371浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQLUPDATE替换字段值方法详解
- 292浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL基础:增删改查全教程
- 356浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL建表语法详解与实例教程
- 498浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL中文界面设置方法详解
- 356浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL安装后如何启动和连接
- 233浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 千音漫语
- 千音漫语,北京熠声科技倾力打造的智能声音创作助手,提供AI配音、音视频翻译、语音识别、声音克隆等强大功能,助力有声书制作、视频创作、教育培训等领域,官网:https://qianyin123.com
- 94次使用
-
- MiniWork
- MiniWork是一款智能高效的AI工具平台,专为提升工作与学习效率而设计。整合文本处理、图像生成、营销策划及运营管理等多元AI工具,提供精准智能解决方案,让复杂工作简单高效。
- 89次使用
-
- NoCode
- NoCode (nocode.cn)是领先的无代码开发平台,通过拖放、AI对话等简单操作,助您快速创建各类应用、网站与管理系统。无需编程知识,轻松实现个人生活、商业经营、企业管理多场景需求,大幅降低开发门槛,高效低成本。
- 104次使用
-
- 达医智影
- 达医智影,阿里巴巴达摩院医疗AI创新力作。全球率先利用平扫CT实现“一扫多筛”,仅一次CT扫描即可高效识别多种癌症、急症及慢病,为疾病早期发现提供智能、精准的AI影像早筛解决方案。
- 98次使用
-
- 智慧芽Eureka
- 智慧芽Eureka,专为技术创新打造的AI Agent平台。深度理解专利、研发、生物医药、材料、科创等复杂场景,通过专家级AI Agent精准执行任务,智能化工作流解放70%生产力,让您专注核心创新。
- 95次使用
-
- MySQL死锁使用详解及检测和避免方法
- 2022-12-31 151浏览
-
- Mysql数据库分库分表全面瓦解
- 2023-01-01 219浏览
-
- 由不同的索引更新解决MySQL死锁套路
- 2022-12-31 476浏览
-
- 一文聊聊JDBC多数据库间怎么进行联表查询
- 2023-02-16 393浏览
-
- 聊聊百亿级数据分表后怎么分页查询?三种方案分享
- 2023-01-09 160浏览