【Mysql主从延迟过高导致的case】昨天同事遇到了一个线上case,主要现象是部分用户下单成功,但是却查不到订单详情信息,追踪到订单表里,发现部分订单并没有更新状态。
排查:
用户下单的后台服务逻辑最近并未做改动,分析报警日志发现,在下午四点到五点之间有部分空指针异常,定位到代码如下:
文章图片
显然这里查询到的订单DTO为空,造成了空指针异常。正常的下单逻辑是,用户创建订单-在本地db生成订单-调用订单中心rpc接口-订单中心创建订单成功返回订单信息-拿到信息后先查本地订单表,然后更新。那么问题来了,从本地表生成订单到订单中心返回信息延迟不过几十ms,是什么原因导致在mysql表中插入成功一条数据,然后在几十ms后查不到该条数据呢?
这里我们很显然的会想到mysql的主从分离,然后我去查看了一下相应db的信息,采用了一主一从,insert或者update操作一般默认走主库,而查询操作一般默认走从库。也就是说,在大约50ms的时间内主库的信息并未同步到从库中。
我们知道,一般来说一级主从延迟大约在50~100us左右,然后我们查看了mysql集群的监控,发现在故障发生期间,集群tps较大,mysql的主从延迟峰值达到130s。
文章图片
文章图片
由于mysql的主从同步机制是异步单线程,当在主机器执行大量写操作时,主从同步的IO线程来不及处理,会导致从机器的同步产生延迟。而目前我们数据库集群的同步机制是以集群为粒度,这会导致同一个集群的一个数据库出现Delay,其他的数据库也受到对应的影响。也就是说故障期间有同事在针对同一个集群中另一个库进行大量的sql操作,tps高达5000以上,而该集群建议的tps在3000以内,导致了主库的访问量太大,而从库的数据同步跟不上,导致从库的数据存在不一致的情况。
存在的问题:
(1)最初采用比较少量的数据进行同步,后续逐渐加大数据量,在加大数据量的过程中只关注了对服务提供方的压力,忽略了对DB的压力
(2)对于入库后在短时间内需要再次查询该条数据的业务,建议查询sql强制走主库,这样就不会存在主从延迟的问题了。
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)