记一次达梦数据库的查询异常
项目使用的国产达梦数据库。不得不说达梦数据库网上的资料真的是少啊!遇到问题都不知道怎么搞。
表象:
1. 启动项目后,第一次使用17当做参数查询数据正常,总条数=10,使用16作为参数查询,结果正常,总条数=0。 再使用17当做参数查询,结果异常,总条数=0。
首先copy了他的数据库,本地进行复现,失败
视图创建语句,一模一样,
视图依赖的表的建表语句,基本一致,
STORAGE(ON "FAWKES", CLUSTERBTR)
STORAGE(ON "MAIN", CLUSTERBTR) ;
先放弃本地复现。
链接服务器进行问题复现
查询17,总条数=10,
查询16,总条数=0,
查询17,总条数=0,(异常)
copy出来语句,直接使用navicat执行,总条数=10.
通过python脚本等其他方式执行,总条数=10.
首先怀疑是视图的问题
dm项目中使用场景很多,如果正常的对象mapper出现问题服务早宕了。将视图中对应的这条数据copy到mapper中,直接使用mappper执行,没有问题。重复多次执行数据正常。
问题出现在视图上。
怀疑我们项目的问题
我们项目对接了10多种数据库,对mybatis的拦截器等进行过各种封装。怀疑参数拼接存在问题。
启动一个新的空的项目,只引入mybatisPlus, 进行验证。(排除我们项目自己拦截器的问题)
空项目的demo中,mybatis验证异常,查询17=10条,16=0条,17=0条。
怀疑mybatis和dm的问题
直接使用手撸jdbc进行验证。直接使用拼接完成的sql验证,数据正常,
使用?占位符验证, 数据正常???(这个地方搞错了)
手撸jdbcTemplate正常,mybatis不正常。
问题是否出现在参数拼接上?MybatisParameterHandler#setParameters,跟这个这个类看看参数拼接,数据拼接方式一致,执行语句一致,麻了我,mybatis底层也是PreparedStatement,手撸代码也是PreparedStatement,咋执行结果还是不一样呢?
不能太相信自己的眼睛,copy出来用对比工具比对一下各个参数。嗯?我错误的把英文占位符写成了中文的占位符。dm自己有优化,支持中文占位符。所以我的中文占位符数据正常。退回到上一步,验证英文占位符查询结果,结果异常,17=10条,16=0条,17=0条。
其它错误,调整参数顺序,因为条件有多个((()))嵌套,去掉一组括号后,数据正常,但是去掉括号后忘了用16进行查询,导致了分析方向被误导到嵌套括号上,又浪费了我大把的生命。
怀疑dm的jdbc有问题
使用python来进行sql的验证。
使用应为占位符?查询失败,17=0条,16=0条,17=0条。
尝试使用中文占位符,结果异常,17=10条,16=0条,17=0条。
python进行查询异常,jdbc进行查询也是异常,排除jdbc的问题。最终问题肯定出现在dm数据库的视图查询上。
疑问再次梳理。
使用navicat一直正常,
使用拼接好的sql一直正常,
使用普通的表是正常的,视图才会出现异常。
重建视图后第一次查询正常,第二次查询其他数据后,再次查询出现异常。
使用占位符jdbc和dmPython都是异常的,问题出现在视图和占位符和缓存上。
执行计划缓存
查询执行计划,并且清理所有执行计划(线上环境慎用全部清理)。
-- 查看执行计划:0:关闭,1:启用,2:不包含显式参数优化,3:有显式参数也优化
select PARA_NAME,PARA_VALUE from v$dm_ini where para_name like 'USE_PLN_POOL';-- 定位问题SQL的缓存项:执行以下SQL,替换'%你的SQL特征%'为能唯一标识你问题SQL的字符串片段。
select cache_item, sqlstr from v$cachepln where sqlstr like '%你的SQL特征%';-- 清除特定的执行计划缓存:使用上一步查询得到的cache_item值来清除缓存。
call SP_CLEAR_PLAN_CACHE(这里替换为具体的cache_item值);
使用jdbc占位符查询视图,17=10条,16=0条,17=0条,清理执行计划,17=10条。
不能每次都跟屁股后面手动清理执行计划吧!添加HINT `/*+ USE_PLN_POOL(0) */ `。
我的jdbc使用了USE_PLN_POOL(0) 不生效,dmpython也不生效,看网上有说能生效的。
待解决问题
USE_PLN_POOL(0) 不生效,问题待定位解决
如何在拦截器中识别当前为dm的视图,并且添加USE_PLN_POOL=0,或其他链接参数方式进行指定不使用执行计划。
本地环境执行结果正常,线上环境执行结果异常问题定位。
优化视图构建,解决执行计划异常问题。