就在昨天下午,也就是2021/03/26这天,我清楚的记得是下午16:25:11开始,程序出现莫名其妙的异常。
异常是这样的,很明显,执行这个存储过程的时候,入参为空
### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Incorrect number of arguments for PROCEDURE XXXX.get_bid_info; expected 1, got 0
### The error may exist in class path resource [mapper/XXXMapper.xml]
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: {call get_bid_info ( )}
报错代码是这样的
List<MessageDataDTO> dataDTOList = JSONArray.parseArray(messageDTO.getData(), MessageDataDTO.class);
Map<String, Object> parmtersMap = JSONObject.parseObject(messageDTO.getParameters(), Map.class);
//遍历,并构造消息所需要的参数
for (MessageDataDTO messageDataDTO : dataDTOList) {
//替换存储过程入参
Map<String, Object> replaceProcParams = getReplaceProcParams(messageDataDTO.getParams(), parmtersMap);
//执行存储过程
Map<String, Object> msgFormatInfo = iProcMapper.getMsgFormatInfo(replaceProcParams, messageDataDTO.getDataSql());
//获取返回参数
String dataField = messageDataDTO.getDataField();
}
在替换存储过程参数这一行,messageDataDTO.getParams()是用来根据parmtersMap里面的键值对,取出对应参数的值,作为存储过程的参数传入,并且执行。
问题就出在这,这个parmtersMap和getParmas()都是数据库里面的东西,
getParams()结构是这样的
"Params":"{ProjectName}"
而parmtersMap是这样
"Paramters":{"ProjectId":"b2ec97d2492d443285bfb3cfeaa3a6ec","Money":"423432","BidList":"[{ "FileName": "fsjfk","FileSrc": "dsajdkals","FileExtension": "fsd" }]","UserId":"a3ca84674afd48c6a0b504f93ddc49d0"
根据Params的ProjectName去Paramters里面找,并不存在里面,按道理来说替换后应该会返回null值,然后执行存储过程就会报参数为空,这是正常执行逻辑。
但是从这个段代码部署到服务器后,一直到昨天走到替换存储过程参数这里都是没有报错的,也顺利的走到了程序末尾做了一个发信息的操作。就从昨天下午四点左右开始,这里开始报错了,Params的字段在Parmaters里面找不到了。
- 我先是查看前两天还能正常走到发信息操作的git版本代码,回滚了一下,跑起来还是错误的,百思不得其解,甚至开始怀疑人生。
- 我想到我们项目里面有一个日志收集系统,然而上去看,只有昨天报错后的日志了,也很诡异,于是放弃。
- 我想到代码没有问题,和前几次版本对比也都没有变化,于是我想到了会不会数据有问题。我啪的一下,很快啊,我在数据库马上就看了general_log有没有开启,不出所料果然没开,于是放弃
- 就在准备提桶跑路的那刹那,我想起了数据库的binlog文件,马上怀着激动的心情查看一下最新的binlog文件,随后一个命令
mysqlbinlog --no-defaults -v --base64-output=decode-rows -v binlog.000007 > re.sql
等待sql下载好后,我全局查找了Params所在的表最早在哪个时间点被修改了,查找一通发现,特喵的果不其然,原来这个Params 就是ProjectId,不知道是谁手滑应该是在navicat里面修改成了ProjectName,
时间戳转成北京时间后
正是2021/03/25 16:25:11,然后为了让这个解释更加具有说服力,我结合了日志收集系统上,第一次出现错误的参数,我定睛一看,其中参数里的时间正是2021/03/25 16:25:11 的后面十多秒,
,恰恰说明了这十多秒前有人改了这个Params的值。
5. 其实装数据库的时候就该建个只能查询权限的用户来操作这些,还是自己不太专业,没什么经验,差点害的自己提桶跑路。