Table ActiveRecord 中的名称损坏错误
Table name corruption errors in ActiveRecord
我们在使用 ActiveRecord 时偶尔会遇到 PG::UndefinedTable
错误。关联 table 名称有些损坏,我经常看到
Cancelled
附加到 table 名称的末尾。
例如:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "fooCancell" does not exist
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "Cancelled" does not exist
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "barC" does not exist
在上面的示例中,我使用 foo
和 bar
.
混淆了 table 名称
当 rails 项目在 Puma 中 运行 时,我们会看到此错误。队列工作人员似乎做得很好。
错误消息中的 table 与真实的 table 或模型不对应。看起来像是内存损坏的情况。有没有人见过这样的问题?如果是这样,您是如何解决的?
puma.rb
on_worker_boot do
ActiveRecord::Base.establish_connection
end
database.yml
production:
url: <%= ENV["DATABASE_URL"] %>
pool: <%= ENV['DB_CONNECTION_POOL_SIZE'] || 5%>
reaping_frequency: <%= ENV['DB_CONNECTION_REAPING_FREQUENCY'] || 10 %>
prepared_statements: false
看起来 reaping_frequency 可能是问题所在。我发现有几个声称他们可能有线程错误。我会尝试删除该选项或将其设置为 nil,看看是否可行。我唯一能想到的另一件事是,如果您手动调用 Thread.new 并在其中使用活动记录。
以下是一些反对收割的声明:
http://omegadelta.net/2014/03/15/the-rails-grim-reaper/
https://github.com/mperham/sidekiq/issues/1936
在此处搜索 "DO fear the Reaper":
https://www.google.com/amp/s/bibwild.wordpress.com/2014/07/17/activerecord-concurrency-in-rails4-avoid-leaked-connections/amp/
我在这里冒险猜测,基于 ...
但您可能是:
- 在您的应用程序中调用
fork
;或者
- 在服务器 (puma) 派生它的工作进程之前(在应用程序初始化期间)调用 ActiveRecord 例程(使用数据库调用)。
其中任何一个都会破坏 ActiveRecord 的同步并导致多个进程共享数据库连接池而不同步它的使用(导致交错和损坏的数据库命令)。
如果您正在使用 fork
,请确保关闭所有 ActiveRecord 数据库连接并重新初始化连接池(有一个函数调用可以执行此操作,但我不记得它在我的顶部头,可能 ActiveRecord.disconnect!
或 ActiveRecord.connection_pool.disconnect!
).
否则,在运行 Puma之前(在初始化过程中或使用Puma的after_fork
),关闭所有ActiveRecord数据库连接并重新初始化连接池。
我们在使用 ActiveRecord 时偶尔会遇到 PG::UndefinedTable
错误。关联 table 名称有些损坏,我经常看到
Cancelled
附加到 table 名称的末尾。
例如:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "fooCancell" does not exist
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "Cancelled" does not exist
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "barC" does not exist
在上面的示例中,我使用 foo
和 bar
.
当 rails 项目在 Puma 中 运行 时,我们会看到此错误。队列工作人员似乎做得很好。
错误消息中的 table 与真实的 table 或模型不对应。看起来像是内存损坏的情况。有没有人见过这样的问题?如果是这样,您是如何解决的?
puma.rb
on_worker_boot do
ActiveRecord::Base.establish_connection
end
database.yml
production:
url: <%= ENV["DATABASE_URL"] %>
pool: <%= ENV['DB_CONNECTION_POOL_SIZE'] || 5%>
reaping_frequency: <%= ENV['DB_CONNECTION_REAPING_FREQUENCY'] || 10 %>
prepared_statements: false
看起来 reaping_frequency 可能是问题所在。我发现有几个声称他们可能有线程错误。我会尝试删除该选项或将其设置为 nil,看看是否可行。我唯一能想到的另一件事是,如果您手动调用 Thread.new 并在其中使用活动记录。 以下是一些反对收割的声明:
http://omegadelta.net/2014/03/15/the-rails-grim-reaper/
https://github.com/mperham/sidekiq/issues/1936
在此处搜索 "DO fear the Reaper": https://www.google.com/amp/s/bibwild.wordpress.com/2014/07/17/activerecord-concurrency-in-rails4-avoid-leaked-connections/amp/
我在这里冒险猜测,基于
但您可能是:
- 在您的应用程序中调用
fork
;或者 - 在服务器 (puma) 派生它的工作进程之前(在应用程序初始化期间)调用 ActiveRecord 例程(使用数据库调用)。
其中任何一个都会破坏 ActiveRecord 的同步并导致多个进程共享数据库连接池而不同步它的使用(导致交错和损坏的数据库命令)。
如果您正在使用 fork
,请确保关闭所有 ActiveRecord 数据库连接并重新初始化连接池(有一个函数调用可以执行此操作,但我不记得它在我的顶部头,可能 ActiveRecord.disconnect!
或 ActiveRecord.connection_pool.disconnect!
).
否则,在运行 Puma之前(在初始化过程中或使用Puma的after_fork
),关闭所有ActiveRecord数据库连接并重新初始化连接池。