查看原文
其他

我竟被这个 Bug 坑了一周!

鱼皮 程序员鱼皮 2022-08-14

记录下来,下次秒解

大家好,我是鱼皮,昨天解决了一个让我头疼了一周的 Bug,爽的不行!记录下来分享给大家,如果你们之后也遇到了这个 Bug,说不定就能轻松干掉它了。

孽起

事情是这样的,我在公司负责数据可视化相关项目,就是有个网站可以展示各种数据图表,便于分析数据。结果上周有一天,产品小姐姐说,她在系统上输入了两个不同的数据筛选条件,竟然查询出了一模一样的结果?

举个例子,她想分别查询一班和二班的学生成绩,结果无论指定查询条件是一班还是二班,查出的结果都是一班的!

查询数据

我还是第一次在我们的系统中遇到这样的 Bug,那就排查一下呗!

排查

让我们从前端开始查起,完整地追溯一个查询请求。

首先打开浏览器控制台,查看请求参数,发现班级的查询条件(1 或者 2)的确发送给后端了:

查看请求参数

好吧,那就是后端的问题,为什么不同的条件能查出相同的结果呢?

难道是后端没有用到这些条件?

由于数据都是从数据库中查询出来的,那不妨看一下两种请求对应的 SQL(数据库查询语言)语句是否一致。

查一班学生成绩的 SQL:

select 班级,姓名,成绩 
from student
where 班级 = '一班';

查二班学生成绩的 SQL:

select 班级,姓名,成绩 
from student
where 班级 = '二班';

显然,上述两个查询语句不一致,已经把班级拼接到了 SQL 的 where 子句中。

然后我直接用数据库客户端去执行这两个语句,结果是不同的,能查到二班的数据。也就是说,不是数据库和查询语句的问题。

那奇怪了,如果从数据库中查到的数据是二班的,为什么最后返回给前端却是一班的呢?

难道是系统对数据库中查出的数据又进行了后续处理,把二班变成了一班?

仔细看了下代码,也没有,我怎么会写出这么神奇的逻辑哈哈哈!

等等,难道说,数据根本不是从数据库取出来的,而是从数据库的上游 —— 缓存中读取的?

为了提高系统性能,我添加了缓存逻辑,将每个对数据库的查询语句、查询条件等放在一起进行计算,得到一个 key 字符串,并保证相同的查询语句 key 一定相同。

key = 计算(sql, 条件)

也就是说,只要用户执行 SQL 从数据库中取过一次数据,就可以把 key 和结果保存起来。第二次再执行同样的查询,就能直接从缓存中取到结果,不用再到数据库中查啦。

但是,按道理来说,查询一班和二班的 SQL 是不同的,生成的 key 也理应不同,肯定不会查到同一份缓存数据啊?难不成我计算 key 的函数写错,导致出现相同的 key 碰撞了?

于是,我在自己的电脑上运行了计算 key 的函数,发现 key 的确是不同的:

# 查询一班的 SQL 算出的 Key:
prefix:1234567

# 查询二班的 SQL 算出的 Key:
prefix:7654321

既然本地和线上是同一组 SQL、同一个计算函数,所以本地的 key 不同,线上的 key 肯定也不同,那怎么还会查出相同的数据呢?好气啊!这不科学啊!

好吧,脑补分析一波后,没有结果。正好当时需求又比较多,于是我决定后面再解决这个 Bug,但它始终让我耿耿于怀。

真相

后来某一天,系统又出了其他 Bug,我就去看线上日志,结果这一看,好家伙,这都是啥啊?!

线上程序日志

为啥会有这么多问号呢?

哦,中文乱码了,估计是部署这个项目的 Docker 容器缺少中文环境吧。

等等,我突然想到了什么!

在中文乱码下,我们很多有意义的中文内容都变成了枯燥的问号,导致无法分辨看到的信息有何不同。那么会不会是这个原因,导致之前我们根据 SQL 语句生成的 key 也相同了呢?

看了下日志,果然,查询一班和二班的 SQL 语句都变成了下面这副模样:

select ????,????,???? 
from student
where ???? = '????';

显然,查询条件无论指定为啥,都已经没有意义了,最终查询了同一个缓存,从而取到了同一份数据。

真相大白,之后我在容器的配置文件中补充上对中文环境的支持,再重新构建,就完美解决了~

参考博客:https://blog.csdn.net/weixin_39153210/article/details/83617792

解决 Bug 的那一刻,感觉世界又充满了色彩哈哈哈!



看来,想要解决 Bug,一定要立足于事实(比如日志等 “证据”),有序排查,灵活分析。有时,你以为的不一定是你以为的!

排查 Bug 虽然头疼,但却能锻炼一个人思考问题的方法,帮他积累到更多经验。对我来说,这波属实不亏~

以上就是本期分享,我是鱼皮,点赞 + 在看 还是要求一下的,祝大家都能心想事成、发大财、行大运。

往期推荐

摔到老三的 Java,未来在哪?

刚刚,腾讯开奖!有鹅选鹅?

不敢想,做个博客竟如此简单!

腾讯同事的内部分享,大赞!

帮大二创业的学弟优化简历

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存