pgsql 的预编译缓存一致性检查问题

这周主要是在修xxx项目历史遗留bug。某一天,系统关键接口突然开始大量报错。具体错误如下:

"操作失败,\n### Error querying database.  Cause: org.postgresql.util.PSQLException: ERROR: cached plan must not change result type\n### The error may exist in URL [jar:file:/xxx/xxx/sys/xxx-1.0-SNAPSHOT.jar!/BOOT-INF/lib/jeecg-system-biz-3.4.0-SNAPSHOT.jar!/org/jeecg/modules/system/mapper/xml/SysDictMapper.xml]\n### The error may involve org.jeecg.modules.system.mapper.SysDictMapper.queryTableDictByKeysAndFilterSql-Inline\n### The error occurred while setting parameters\n### SQL: SELECT name AS \"text\", id AS \"value\" FROM xxx_project WHERE id IN (?)\n### Cause: org.postgresql.util.PSQLException: ERROR: cached plan must not change result type\n; uncategorized SQLException; SQL state [0A000]; error code [0]; ERROR: cached plan must not change result type; nested exception is org.postgresql.util.PSQLException: ERROR: cached plan must not change result type"

经过调查:发现是xxx_project表新增了一个字段,但是只重新部署了web服务(整个系统分sys和web两个服务);导致sys的旧缓存依旧生效,新的和xxx_project表相关的sql与旧的预编译缓存结果不一致导致报错。

具体复现可以通过如下方式:
1、开启两个会话:A和B
2、A会话创建一个关于xxx表的预编译查询sql,并执行
3、B会话修改xxx表结构,比如新增字段
4、A会话再次执行预编译查询sql
5、得到报错:[0A000] ERROR: cached plan must not change result type

当时情况紧急,没有仔细排查,直接使用pgsql连接参数:prepareThreshold=0 临时关闭了预编译缓存救急。

BH6AOL

我们正在前进!