日常Bug排查-偶发性读数据不一致
日常Bug排查-偶发性读数据不一致
前言
日常Bug排查系列都是一些简单Bug的排查。笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材。
Bug现场
业务场景
先描述这个问题出现的业务场景。这是一个支付的场景,如果支付成功了,我们就把支付状态置为success(主单据更新)同时写入支付成功时间戳为t1(子单据更新)。支付成功之后,我们还需要做其它的动作,做这个动作的时候我们需要刚才的支付成功时间戳t1。那么,我们正常的请求顺序即为:

Bug现场
奇怪的是,线上运行时候,会有极小的概率(大概是几亿分之一)获取的这个时间戳为0!也即在读到主单为success的时候,看到的子单时间戳是0!由于时间戳为0,所以调用下游RPC传参错误导致了调用失败。
如下图所示:

思路
因为在请求1中,我们是在事务内更新的,数据应该始终保持一致才对。那很直观的第一个思考点就是:
思路1: 是不是事务没生效?笔者看了下源代码,使用没有问题,也不存在类内方法互相调用的情况。再者说,如果事务没生效,概率不至于这么低。
思路2:稍加思索一下,好像这个是事务隔离级别的原因。在这个Case里面,看上去数据库采用的RC隔离级别,也就是读已提交。如下图所示:

t1时刻,请求2查询到的子单据时间戳为0
t2时刻,请求1提交,这时候将子单据时间戳更新为t1,主单据状态为success
t3时刻,请求2由于RC隔离级别,能看到请求1的提交,主单状态为success,所以判定可以进行下游RPC的调用,但是由于在t1时刻获取到的时间戳为0,导致调用失败
矛盾点
数据库隔离级别是RC应该能非常好的解释出现Bug时的行为。于是笔者查了一下隔离级别,发现是RR,这就陷入了矛盾!但由于RC这个隔离级别解释这个Bug非常的靠谱,所以笔者看了下业务的数据库配置,发现它有100个库。那么就自然有了下一步猜想:这100个库中有的是RR的,有的是RC的。出问题的那个库正好就是RC的。
指定库查询隔离级别
于是笔者就根据业务的shardKey到了指定的库查询隔离级别,发现它果然是RC级别的,真相大白!这100个库中大概有1/3的库是RC隔离级别。

后续修复
这个问题是由于DBA在换库的过程中采用了默认的配置,导致原来设置为RR级别的库在换了大容量机器后被默认改成了RC隔离级别。DBA找了个时间将隔离级别切换回RR后问题就消失了,并编写了相应的巡检脚本防止此类问题再次发生。
总结
隔离级别是比较微妙的,相关问题大多只在高并发大流量下才会有偶发性的显现,分库分表集群中不同DB的隔离级别由于种种原因导致的不一致会加大问题的排查难度。有时候遇到无法解释问题时可以考虑下底层组件的设置问题。

日常Bug排查-偶发性读数据不一致的更多相关文章
- 日常Bug排查-系统失去响应-Redis使用不当
日常Bug排查-系统失去响应-Redis使用不当 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_. Bug现场 开发反应线上系统出现失去响 ...
- 日常Bug排查-消息不消费
日常Bug排查-消息不消费 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_. Bug现场 某天下午,在笔者研究某个问题正high的时候.开 ...
- 日常Bug排查-抛异常不回滚
日常Bug排查-抛异常不回滚 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,同时顺便积累素材_. Bug现场 最近有人反映java应用操作数据库的时候,抛异 ...
- 日常Bug排查-Nginx重复请求?
日常Bug排查-Nginx重复请求? 前言 日常Bug排查系列都是一些简单Bug排查,笔者将在这里介绍一些排查Bug的简单技巧,其中不乏一些看起来很低级但很容易犯的问题. 问题现场 有一天运维突然找到 ...
- 记一次线上bug排查-quartz线程调度相关
记一次线上bug排查,与各位共同探讨. 概述:使用quartz做的定时任务,正式生产环境有个任务延迟了1小时之久才触发.在这一小时里各种排查找不出问题,直到延迟时间结束了,该任务才珊珊触发.原因主要就 ...
- wordpress插件bug排查后记(记一次由于开启memecached引起的插件bug)
这篇文章是写给自己的. 周三的时候我在维护公司的一个wordpress项目页面时发现了一个非常奇怪的情况:当我尝试更新网站上的一个页面后,在wordpress后台的编辑器中发现其内容并没有按我预期的将 ...
- 年年出妖事,一例由JSON解析导致的"薛定谔BUG"排查过程记录
前言 做开发这么多年,也碰到无数的bug了.不过再复杂的bug,只要仔细去研读代码,加上debug,总能找到原因. 但是最近公司内碰到的这一个bug,这个bug初看很简单,但是非常妖孽,在一段时间内我 ...
- 团队项目-BUG排查-ADT工程 To Android Studio 一整天的排查日记
4-22 10:44至4-23 0:45 ①打开Eclipse从Github上Clone MathsApp到本机,报错'Unable to resolve target'android-19' ②尝试 ...
- 记一次偶发的bug排查——redis-py-cluster库的bug
排查流水账: 通过平台监控,发现很多偶发的查看推荐列表的接口时延大于0.5s 写单元测试,不能重现.在测试环境不能重现.只有在正式环境可以偶发重现. 通过日志埋点,等待重现 不断地加日志埋点后发现耗 ...
- 一次压力测试Bug排查-epoll使用避坑指南
Bug复现 使用Webbench对服务器进行压力测试,创建1000个客户端,并发访问服务器10s,正常情况下有接近8万个HTTP请求访问服务器. 结果显示仅有7个请求被成功处理,0个请求处理失败,服务 ...
随机推荐
- OpenHarmony littlefs文件系统存储结构与IO性能优化分析
引言 随着科技的发展和网络技术的进步,计算机存储空间愈加紧张,存储空间对文件系统的功能需求越来越大,大规模的数据增长为文件存储.非结构化数据存储提出了新的挑战. 对于许多物联网设备而言,拥有一个小型且 ...
- Java 运算符详解与字符串处理技巧
Java 运算符 算术运算符 算术运算符用于执行常见的数学运算. 运算符 名称 描述 示例 + 加法 将两个值相加 x + y - 减法 从一个值中减去另一个值 x - y * 乘法 将两个值相乘 x ...
- C# 方法详解:定义、调用、参数、默认值、返回值、命名参数、方法重载全解析
C# Methods 方法是一段代码,只有在调用时才会运行. 您可以将数据(称为参数)传递给方法. 方法用于执行某些操作,也被称为函数. 为什么使用方法?为了重用代码:定义一次代码,然后多次使用. 创 ...
- C# Replace方法
例子: string tStw = "Run Status"; string tStw1 = tStw.Replace("Run Status", " ...
- Viu联合华为HMS生态,共创影音娱乐新体验
华为HMS生态携手流媒体平台Viu,为海外消费者打造精品移动娱乐应用体验,并助力提升流量变现能力.Viu在中东非.东南亚等16个国家及地区提供广告合作和付费会员服务,支持优质视频内容高清点播和直播.自 ...
- R语言学习3:数据框处理(1)
本系列是一个新的系列,在此系列中,我将和大家共同学习R语言.由于我对R语言的了解也甚少,所以本系列更多以一个学习者的视角来完成. 参考教材:<R语言实战>第二版(Robert I.Kaba ...
- openGauss社区入门(openGauss-定时任务)
为什么要使用定时任务 在一个固定的时间点活间隔一段时间需要频繁触发某一动作,为了使用便捷,有了定时任务,极大的减少了工作的重复性,提高了效率. 定时任务的内容 基于定时任务产生的背景,定时任务内容包括 ...
- CSS:注册页面的编写练习
最终效果图: html文件: <!-- * @Qusetion: * @Author: 一届书生 * @Date: 2020-04-07 08:17:36 * @LastEditTime: 20 ...
- .Net core 3.0 SignalR+Vue 实现简单的IM(无jq依赖)
.Net core 中的SignalR JavaScript客户端已经不需要依赖Jquery了 一.服务端 1.nuget安装 Microsoft.AspNetCore.SignalR2.在start ...
- vue 弹出框挂载富文本,富文本()无法实例化问题
因为elementUI的dialog组件,他是v-if渲染,再页面刚加载时,这个弹出框还未进行挂载,我们就让他v-show显示. ,富文本实例再mounted里面挂载即可