Postgres:“错误:缓存计划不得更改结果类型”

时间:2010-05-06 19:23:21

标签: postgresql

PostgreSQL 8.3.7服务器将此异常抛给我的应用程序。 有谁知道这个错误意味着什么,我能做些什么呢?

ERROR:  cached plan must not change result type
STATEMENT:  select code,is_deprecated from country where code=$1

3 个答案:

答案 0 :(得分:152)

我弄清楚导致此错误的原因。

我的应用程序打开了一个数据库连接并准备了一个SELECT语句来执行。

与此同时,另一个脚本正在修改数据库表,更改上述SELECT语句中返回的其中一列的数据类型。

我通过在修改数据库表后重新启动应用程序来解决此问题。这会重置数据库连接,允许预准备语句无错误地执行。

答案 1 :(得分:10)

我试图在Java / JDBC应用程序的上下文中尝试解决问题时,通过google ERROR: cached plan must not change result type为任何登陆此处的人添加此答案。

我能够通过运行架构升级(即DDL语句)来可靠地重现错误,而我的后端应用程序正在运行。如果应用程序正在查询已通过架构升级更改的表(即应用程序在更改的表上升级之前和之后运行查询) - postgres驱动程序将返回此错误,因为它显然会缓存某些架构详细信息。 / p>

您可以使用pgjdbc配置autosave=conservative驱动程序,以避免此问题。使用此选项,驱动程序将能够刷新缓存的任何详细信息,您不必反弹服务器或刷新连接池或您可能提出的任何解决方法。

在Postgres 9.6(AWS RDS)上重现,我的初步测试似乎表明此选项已完全解决问题。

文档:https://jdbc.postgresql.org/documentation/head/connect.html#connection-parameters

您可以查看pgjdbc Github issue 451了解更多详情和问题的历史。

关于表现的说明:

根据上述链接中报告的性能问题 - 在盲目切换之前,您应该对应用程序进行一些性能/负载/浸泡测试。

在我自己在AWS RDS Postgres 10实例上运行的应用程序上执行性能测试时,启用conservative设置会导致额外的CPU使用率。虽然不是很多,但在我调整了负载测试使用的每个查询并开始推送负载之后,我甚至只能看到autosave功能显示为使用可测量的CPU量努力测试。

答案 2 :(得分:2)

对于我们来说,我们面临着类似的问题。我们的应用程序可以在多个架构上运行。每当我们进行架构更改时,此问题就开始出现。

在JDBC参数中设置 prepareThreshold = 0 参数可在数据库级别禁用语句缓存。这为我们解决了。