私の会社は、Rails 2.x アプリから Rails 4 への大規模な移行/アップグレードの終わりに近づいています。はい、この記事を書いている時点では、Rails 4 は RC であり最終版ではないことは認識していますが、私たちの目標は4.0 の最終版がリリースされるとすぐに準備が整います。必要に応じて宝石を置き換えたりアップグレードしたりして、アップグレードプロセス全体を実行しましたが、最終的に非常に大きな壁にぶつかりました.
簡単な背景:
ユニコーンを使用してアプリを提供します
2 つの PostgreSQL データベースがあり、それぞれが異なるサーバー上にあります。1 つはマスター、もう 1 つはホット レプリケート読み取り専用スタンバイです。アプリ内の 2 つのコントローラーは、データからレポートを提供します。これらのレポートは一般的に非常に SQL 集約的であるため、シームレスなデータベース プール gem を使用して、それらのコントローラー アクション内のすべてのクエリが PostgreSQL スタンバイ読み取り専用ボックスを通過するようにしています。
残念ながら、Rails 4 で動作するようにシームレスなデータベース プールはまだ更新されていません。私は最近、宝石を使用することを忘れて、それらの特定のコントローラーの要求で接続を切り替えるだけで、要求が実行された後に接続が他のデータベースに切り替えられるようにすることで、この問題を処理する方法についてこのアイデアを考えました。そのため、そのユニコーン ワーカーへの今後のリクエストはデフォルトでプライマリ データベースになります。
これが本当に悪い考えなのか、他の誰かがより良い提案を持っているのか知りたい.
データベース.yml:
production:
host: primary_db_host_ip
adapter: postgresql
encoding: unicode
database: my_app_production
pool: 5
username: ****
password: ****
standby_by:
host: standby_db_host_ip
adapter: postgresql
encoding: unicode
database: my_app_production
pool: 5
username: ****
password: ****
アプリ/コントローラー/application_controller.rb:
class ApplicationController < ActionController::Base
...
...
private
def switch_db
ActiveRecord::Base.establish_connection("standby_db")
yield
ensure
ActiveRecord::Base.establish_connection("production")
end
end
app/controllers/special_controller.rb:
class SpecialController < ApplicationController
around_action :switch_db
...
...
end
更新:具体的には、これは、Rails 4 の準備ができていないかどうかをどのように知るかを尋ねた人のために、seamless_database_pool で発生しているエラーです...
undefined method `reset_transaction' for nil:NilClass (NoMethodError)
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/seamless_database_pool-1.0.12/lib/active_record/connection_adapters/seamless_database_pool_adapter.rb:336:in `proxy_connection_method'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/seamless_database_pool-1.0.12/lib/active_record/connection_adapters/seamless_database_pool_adapter.rb:122:in `block in reset_transaction'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/seamless_database_pool-1.0.12/lib/active_record/connection_adapters/seamless_database_pool_adapter.rb:243:in `use_master_connection'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/seamless_database_pool-1.0.12/lib/active_record/connection_adapters/seamless_database_pool_adapter.rb:121:in `reset_transaction'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_adapters/abstract/database_statements.rb:6:in `initialize'
/home/.rvm/rubies/ruby-2.0.0-p195/lib/ruby/2.0.0/monitor.rb:232:in `initialize'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_adapters/abstract_adapter.rb:90:in `initialize'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/seamless_database_pool-1.0.12/lib/active_record/connection_adapters/seamless_database_pool_adapter.rb:152:in `initialize'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/seamless_database_pool-1.0.12/lib/active_record/connection_adapters/seamless_database_pool_adapter.rb:48:in `new'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/seamless_database_pool-1.0.12/lib/active_record/connection_adapters/seamless_database_pool_adapter.rb:48:in `seamless_database_pool_connection'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_adapters/abstract/connection_pool.rb:440:in `new_connection'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_adapters/abstract/connection_pool.rb:450:in `checkout_new_connection'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_adapters/abstract/connection_pool.rb:421:in `acquire_connection'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_adapters/abstract/connection_pool.rb:356:in `block in checkout'
/home/.rvm/rubies/ruby-2.0.0-p195/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_adapters/abstract/connection_pool.rb:355:in `checkout'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_adapters/abstract/connection_pool.rb:265:in `block in connection'
/home/.rvm/rubies/ruby-2.0.0-p195/lib/ruby/2.0.0/monitor.rb:211:in `mon_synchronize'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_adapters/abstract/connection_pool.rb:264:in `connection'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_adapters/abstract/connection_pool.rb:546:in `retrieve_connection'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_handling.rb:79:in `retrieve_connection'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/activerecord-4.0.0.rc1/lib/active_record/connection_handling.rb:53:in `connection'
config/unicorn.rb:16:in `block in reload'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:495:in `call'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:495:in `spawn_missing_workers'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/unicorn-4.6.2/lib/unicorn/http_server.rb:142:in `start'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/gems/unicorn-4.6.2/bin/unicorn_rails:209:in `<top (required)>'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/bin/unicorn_rails:23:in `load'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/bin/unicorn_rails:23:in `<main>'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/bin/ruby_noexec_wrapper:14:in `eval'
/home/.rvm/gems/ruby-2.0.0-p195@theapp/bin/ruby_noexec_wrapper:14:in `<main>'