场景问题: VisualVM工具Profiler JDBC不是真实执行的SQL

文章讲述了前端反馈前端分页接口的Total字段总是为0的问题,通过排查发现是Mybatisplus插件在处理IN操作时,因NULL值导致的SQL语句错误。VisualVM的Profiler显示的错误SQL揭示了问题根源,最终在代码和预编译SQL的构建环节找到并修复了低级错误。
摘要由CSDN通过智能技术生成

1. 问题

诡异的问题表象: 前端反馈分页接口的Total字段一直为0

使用Visualvm中的 Profiler 注入到应用后,查看JDBC监控得到了分页接口执行的SQL,复制出来执行是55. 此时还没有注意到 IN 的范围中有一个特别的值 'NULL' 🤨

在这里插入图片描述

2. 排查

开始查使用到的Mybatis plus分页插件是不是有bug,debug一轮发现SQL执行的结果就是0 然后才赋值给的IPage对象 😢 这下更奇怪了

重放请求,继续! 往JDBC执行SQL的入口去找,就不信是DataGrip的问题,然后在MySQL的驱动中发现 com.mysql.cj.NativeSession#execSQL 执行的SQL是 SELECT COUNT(*) ... id NOT IN (null, 128, 129) emmm 迷茫🤨

根据MySQL官方文档所描述 operator IN() 可以确认这个 id not in 子句永远会返回null 所以不会有符合条件的数据 count为0。

To comply with the SQL standard, IN() returns NULL not only if the expression on the left hand side is NULL, 
but also if no match is found in the list and one of the expressions in the list is NULL. 

好了,只要在应用代码中加个过滤空问题就解决了🤣

又是一个低级错误导致表象看起来不可思议问题的案例

问题又来了,为什么visualvm中监控到的SQL是 in ( 'NULL' ) 呢 😟

看了下这个项目大部分是Java代码,拉他代码瞅瞅,拉下来发现是古早的ant项目,emmm 在IDE中调试的想法直接放弃,转而从GUI入手, 找到这个界面对应的代码 ProfilerJDBCPanel

但是由于没构建,只能手动搜文件和字符串去找调用关系,总所周知项目中SQL的执行基本都是用PreparedStatement, 传入的只有模板和参数,真实SQL是驱动构建的,visualvm 同样要走这一步。

看了一会发现一个可疑的方法 org.graalvm.visualvm.lib.jfluid.results.jdbc.SQLStatement#getFullSql 。 通过 arthas watch 这个方法后,确认了是这里返回了错误的SQL。😓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值