【发布时间】:2011-03-11 06:51:29
【问题描述】:
我正在使用带有 Rails3 的 Parallel gem 并遇到 mysql 线程的问题,即使是这样的简单行:
Parallel.each(User.all, :in_processes => 1) { |r| puts r.username }
它交替工作,然后第二次失败。这是我得到的错误:
ruby-1.8.7-p330 :035 > Parallel.each(User.all, :in_processes => 1) { |r| puts r.username }
ActiveRecord::StatementInvalid: Mysql::Error: MySQL server has gone away: SELECT `users`.* FROM `users`
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/connection_adapters/abstract_adapter.rb:202:in `log'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/connection_adapters/mysql_adapter.rb:289:in `execute'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/connection_adapters/mysql_adapter.rb:619:in `select'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:7:in `select_all'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/connection_adapters/abstract/query_cache.rb:56:in `select_all'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/base.rb:467:in `find_by_sql'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/relation.rb:64:in `to_a'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/relation/finder_methods.rb:143:in `all'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/base.rb:439:in `__send__'
from /Users/kimptoc/.rvm/gems/ruby-1.8.7-p330@p-ecom1-rails3/gems/activerecord-3.0.3/lib/active_record/base.rb:439:in `all'
from (irb):35
from (null):0
如果我做非并行版本,它工作正常:
User.all.each { |r| puts r.username }
我正在使用 mysql gem,但尝试过 mysql2 和 mysqlplus。
在 OSX 上运行。
我认为这是 ActiveRecord 和 mysql gem 如何与线程一起工作的问题。
根据我的阅读,我可能需要调整 mysql 设置以使其对并发更友好。尽管备用 gem 似乎可以更好地处理并发问题。
我已经通过 gem 提出了这个查询 - https://github.com/grosser/parallel/issues/9#comment_844380 - 但这似乎更像是一个基本问题,即如何使用 ruby 设置 mysql 以进行并发访问......
所以,我的问题是 - Rails3 和 mysql 是否有明确的配置以用于并发 DB 访问?
谢谢,克里斯
编辑
似乎可行的是分成 2 个查询,一个用于获取 id,然后在循环内并行遍历 id,通过 id 重新访问实体。
ids = User.all.map { |u| u.id }
Parallel.each(ids, :in_processes => 1) do |uid|
ActiveRecord::Base.connection.reconnect!
r = User.find(uid)
puts r.username
end
【问题讨论】:
标签: mysql ruby ruby-on-rails-3 activerecord