繁体   English   中英

添加新列时如何避免PG :: InFailedSqlTransaction?

[英]How can I avoid PG::InFailedSqlTransaction when adding new columns?

我们针对同一个数据库运行两个rails应用程序。 部署时,我们通常部署到App A,然后部署到App B,在部署期间重新启动所有rails进程。 App A在7台服务器上运行,至少有20个进程连接到数据库。 App B在4台服务器上运行,至少有8个与数据库的连接。

今天,当我们部署App A时,我们在现有表中添加了一列:

change_table :organizations do |t|
  t.integer :users_count, default: 0
end

我们希望这很好:它在现有表上的新列,它有一个默认值。 迁移运行后不久,App A(重启之前)和App B(部署之前)出现了一些错误。

这些错误是:

FATAL ActiveRecord::StatementInvalid error: PG::InFailedSqlTransaction:
ERROR:  current transaction is aborted, commands ignored until end of 
transaction block

在postgres日志中,我有58个错误,如下所示:

postgres[12283]: ERROR:  cached plan must not change result type
postgres[12283]: STATEMENT:  SELECT  "organizations".* FROM 
  "organizations" WHERE "organizations"."id" = $1 LIMIT $2

这会重复多次,并在所有部署完成并重新启动所有进程后消失。

似乎Rails错误#12330Rails PR 22170在Rails 5.0中解决了这个问题,但我有这个提交,我仍然看到这个错误。

相关软件版本

  • Rails 5.0.2
  • PG 0.19.0
  • Postgres 9.5

关于Rails bug#12330的一条评论表明我必须添加具有null默认值的列。 另一个建议执行多个部署,一个用于禁用prepare语句,另一个用于执行迁移并重新启用预准备语句。

有没有避免这种情况? 当我们重新启动服务器时它会清除,但我觉得我错过了一些东西 - 比如只使用可空列可能会一起避免这些错误。 这不会在每次部署时发生,我不知道如何重现它 - 但这不是第一次发生。

您已经更改了表结构,因此更改了准备好的SELECT返回的内容,因为您使用"organizations".* ,并返回所有列。 PostgreSQL显然不支持更新预准备语句,因此您需要创建新会话(重新连接)或使用DEALLOCATE删除准备好的语句。

编辑:你也可以停止使用SELECT *

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM