ActiveRecord :: StatementInvalid: Mysql :: Ошибка: сервер MySQL ушел: (используя параллельный гем) - PullRequest
2 голосов
/ 11 марта 2011

Я использую гем Parallel с Rails3 и получаю проблемы с потоками 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, но пробовал mysql2 и mysqlplus.

Работает на OSX.

Я думаю, проблема в том, как ActiveRecord и гем mysql работают с потоками.

Из того, что я прочитал, может быть, мне нужно настроить параметры mysql, чтобы сделать его более удобным для параллелизма. Хотя альтернативные гемы, кажется, лучше справляются с обработкой параллелизма.

Я поднял это как запрос к гему - https://github.com/grosser/parallel/issues/9#comment_844380 - но это больше похоже на фундаментальный вопрос о том, как настроить mysql с ruby ​​для одновременного доступа ...

Итак, мой вопрос - есть ли определенная конфигурация для Rails3 и mysql для одновременного доступа к БД?

Спасибо, Крис

EDIT

То, что, кажется, работает, разбивается на 2 запроса: один для получения идентификаторов, затем циклический просмотр идентификаторов параллельно и внутри цикла, повторный доступ к сущности по идентификатору.

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

Ответы [ 2 ]

3 голосов
/ 11 марта 2011

Вам необходимо установить соединения после разветвления.Это «особенность» разветвления - сетевые соединения находятся в несовместимом состоянии.

Parallel.each(User.all, :in_processes => 1) do |r|
  ::ActiveRecord::Base.establish_connection
  puts r.username
end
2 голосов
/ 12 декабря 2012

Я получил очень похожую ошибку со следующим:

pid = Process.fork
if pid
  Process.detach(pid)
else
  # Perform long task using ActiveRecord
  do_stuff
end

Если я попадаю на сервер с запросом во время работы do_stuff, он завершает задачу и выдает исключение:

ActiveRecord::StatementInvalid (Mysql2::Error: Lost connection to MySQL server during query: ...

Добавление предложения Франсуа исправило мою проблему:

pid = Process.fork
if pid
  Process.detach(pid)
else
  # Perform long task using ActiveRecord
  ActiveRecord::Base.establish_connection
  do_stuff
end

Спасибо, Франсуа!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...