ruby-on-rails - Rails 应用程序在迁移后抛出错误不应影响它

标签 ruby-on-rails ruby ruby-on-rails-3 rails-migrations unicorn

我正在尝试调试最近在我的 Rails (3.0.9) 应用程序中出现的一个问题,其中在对数据库。这种情况以前不会发生,我也找不到最近才应该发生的原因。

我的生产环境有几台服务器,每台服务器都使用 fork 的 Unicorn 实例,它们都共享一个 MySQL 实例。每个实例都使用 1 的连接池。在针对登台数据库进行测试后,我还有一台服务器用作最终登台环境以针对实时数据进行测试。

在过去,我们已经能够在生产数据库上运行迁移,而无需重新部署甚至重新启动生产 Unicorn 服务器,只要它们是旧代码永远不需要看到的迁移。例如,向现有表添加一个新的可选字段——部署到登台服务器的代码会向其写入数据,但现有服务器可以幸福地忽略它并继续以与我们之前相同的方式使用数据库准备好将新代码投入生产。

不过,最近我们看到生产服务器在运行迁移后抛出异常,但仅当它尝试将新行插入修改后的表时才会抛出异常。应用程序的所有其他部分和所有其他表格均不受影响,但只要有插入,我们就会得到:

NoMethodError: undefined method `name' for nil:NilClass

[GEM_ROOT]/gems/arel-2.0.10/lib/arel/visitors/to_sql.rb:56:in `visit_Arel_Nodes_InsertStatement'
[GEM_ROOT]/gems/arel-2.0.10/lib/arel/visitors/to_sql.rb:55:in `map'
[GEM_ROOT]/gems/arel-2.0.10/lib/arel/visitors/to_sql.rb:55:in `visit_Arel_Nodes_InsertStatement'
[GEM_ROOT]/gems/arel-2.0.10/lib/arel/visitors/visitor.rb:15:in `send'
[GEM_ROOT]/gems/arel-2.0.10/lib/arel/visitors/visitor.rb:15:in `visit'
[GEM_ROOT]/gems/arel-2.0.10/lib/arel/visitors/visitor.rb:5:in `accept'
[GEM_ROOT]/gems/arel-2.0.10/lib/arel/visitors/to_sql.rb:18:in `accept'
[GEM_ROOT]/bundler/gems/rails-83fb5552b6ab/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb:111:in `with_connection'
[GEM_ROOT]/gems/arel-2.0.10/lib/arel/visitors/to_sql.rb:16:in `accept'
[GEM_ROOT]/gems/arel-2.0.10/lib/arel/tree_manager.rb:20:in `to_sql'
[GEM_ROOT]/gems/arel-2.0.10/lib/arel/select_manager.rb:217:in `insert'

如果我们随后重新启动生产服务器,问题就会消失,即使它们仍在运行旧代码。因此,当表被修改时,似乎连接中的某些内容已损坏,即使应用程序(如果它没有遇到此错误)也可以继续执行迁移之前正在执行的操作。

我对 ActiveRecord/ARel 做了一些深入研究,但我能做的最多就是推论,在某个时刻,这个表的缓存模型会丢失关于它有哪些列的任何知识,但我不明白为什么它会那样做或者为什么这会突然发生。

最佳答案

我是 Jon 的同事,将为后代回答这个问题。

问题是 https://github.com/rails/rails/blob/v3.0.9/activerecord/lib/active_record/base.rb 中缓存的结果;本质上,某些模型类的 @columns 和 @arel_table 不同步,因为后者在应用程序初始化期间被缓存,因此任何新工作人员都从主 Unicorn 继承。

我们通过阻止在初始化期间调用任何模型的::scoped 或::unscoped 并在我们不能调用::reset_column_information 之后调用::reset_column_information 来修复它。

关于ruby-on-rails - Rails 应用程序在迁移后抛出错误不应影响它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8934105/

相关文章:

ruby - instance_eval 和 class << self 之间的区别?

ruby-on-rails - Heroku 安装 sqlite3 即使它不是依赖项

ruby-on-rails - 使用bundle exec rake 还是只使用rake?

ruby-on-rails - OS X 10.8 上 Rails 应用程序中的段错误

ruby-on-rails - 使用 Rails 查询语言进行复杂查询

ruby-on-rails - Rails i18n中的混合语言环境

Ruby,通过 SSH 和 LOG 一条一条地运行 linux 命令

ruby-on-rails - rspec test GET #index - 包含预期集合

ruby-on-rails-3 - Rails 3 - 使用acts_as_audited 设计可能吗?

ruby - 在 Rails 3 中使用 Nokogiri 读取 XML 文件