Postgres: “ ERROR: cached plan must not change result type”

这个异常由 PostgreSQL 8.3.7服务器抛出到我的应用程序。 有人知道这个错误意味着什么吗? 我能做些什么?

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

我找到了导致这个错误的原因。

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

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

在修改数据库表之后,我通过重新启动应用程序来解决这个问题。这将重置数据库连接,允许准备好的语句在没有错误的情况下执行。

对于在这里登录的任何人,我将在尝试在 Java/JDBC 应用程序的上下文中解决这个问题时通过谷歌 ERROR: cached plan must not change result type添加这个答案。

当使用 DB 的后端应用程序运行时,我能够通过运行模式升级(即 DDL 语句)可靠地重现错误。如果应用程序正在查询一个被模式升级改变的表(例如,应用程序在升级之前和之后在一个改变的表上运行查询)-postgres 驱动程序会返回这个错误,因为显然它缓存了一些模式细节。

您可以通过使用 autosave=conservative配置 pgjdbc驱动程序来避免这个问题。有了这个选项,驱动程序将能够刷新缓存的任何细节,您不应该反弹您的服务器或刷新您的连接池或任何工作方法,您可能已经想出。

转载在 Postgres 9.6(AWS RDS)和我的初步测试似乎表明,这个问题是完全解决了这个选项。

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

您可以查看 pgjdbc Github 第451期了解更多细节和问题的历史。


JRubyActiveRecords 用户可以看到: https://github.com/jruby/activerecord-jdbc-adapter/blob/master/lib/arjdbc/postgresql/connection_methods.rb#L60


关于表现的说明:

根据上面链接中报告的性能问题,在盲目打开应用程序之前,应该对应用程序进行一些性能/加载/浸入测试。

在运行于 AWS RDS Postgres 10实例上的我自己的应用程序上进行性能测试时,启用 conservative设置确实会导致数据库服务器上额外的 CPU 使用。但是这并不多,我甚至只能看到 autosave的功能在我调优了负载测试使用的每一个查询并开始大力推动负载测试之后,显示为使用了可测量的 CPU 数量。

对我们来说,我们面临着类似的问题。我们的应用程序处理多个模式。每当我们进行模式更改时,就会出现这个问题。

在 JDBC 参数中设置 PrepareThreshold = 0参数将禁用数据库级语句缓存,这为我们解决了这个问题。

我得到了这个错误,我手动运行失败的选择查询,它修复了错误。