簡體   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