Подтвердить что ты не робот

"Сервер MySQL ушел" с Ruby on Rails

После того, как наше приложение Ruby on Rails запустилось некоторое время, он начинает бросать 500 с "сервер MySQL ушел". Часто это происходит за одну ночь. Он начал делать это недавно, без каких-либо очевидных изменений в конфигурации сервера.

 Mysql::Error: MySQL server has gone away: SELECT * FROM `widgets`

Перезапуск mongrels (а не сервер MySQL) исправляет его.

Как мы можем это исправить?

4b9b3361

Ответ 1

Вероятно, это связано с постоянным подключением к MySQL (время ожидания, скорее всего, происходит в течение ночи), а Ruby on Rails не восстанавливает соединение, которое должно выполняться по умолчанию:

В файле vendor/rails/actionpack/lib/action_controller/dispatcher.rb указан код:

if defined?(ActiveRecord)
  before_dispatch { ActiveRecord::Base.verify_active_connections! }
  to_prepare(:activerecord_instantiate_observers) {ActiveRecord::Base.instantiate_observers }
end

Метод verify_active_connections! выполняет несколько действий, одним из которых является воссоздание любых истекших соединений.

Наиболее вероятной причиной этой ошибки является то, что это связано с тем, что патч обезьяны переопределил диспетчера, чтобы он не вызывал verify_active_connections!, или verify_active_connections!, и т.д.

Ответ 3

Как говорили другие участники этой темы, скорее всего, сервер MySQL закрыл соединение с вашим приложением Ruby on Rails из-за неактивности. Таймаут по умолчанию - 28800 секунд или 8 часов.

set-variable = wait_timeout=86400

Добавление этой строки в ваш /etc/my.cnf приведет к увеличению тайм-аута до 24 часов http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#option_mysqld_wait_timeout.

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

Есть, однако, три других ситуации, о которых я знаю, которые могут генерировать эту ошибку. Во-первых, перезагружается сервер MySQL. Это, очевидно, приведет к удалению всех подключений, но поскольку клиент MySQL является пассивным, и это не будет замечено, пока вы не выполните следующий запрос.

Вторым условием является то, что кто-то убивает ваш запрос из командной строки MySQL, и это также отключает соединение, поскольку оно может оставить клиента в состоянии undefined.

Последнее, если ваш сервер MySQL перезапустится из-за фатальной внутренней ошибки. То есть, если вы делаете простой запрос к таблице и сразу видите, что "MySQL ушел", я бы внимательно рассмотрел журналы вашего сервера, чтобы проверить аппаратную ошибку или повреждение базы данных.

Ответ 4

Сначала определите max_connections в MySQL:

show variables like "max_connections";

Вам нужно убедиться, что количество подключений, которые вы делаете в приложении Ruby on Rails, меньше максимально допустимого количества подключений. Обратите внимание, что дополнительные подключения могут возникать из ваших cron заданий, процессов delayed_job (каждый из них имеет одинаковый размер пула в вашем database.yml), и др.

Отслеживать соединения SQL при прохождении через приложение, запускать процессы и т.д., выполняя следующие действия в MySQL:

show status where variable_name = 'Threads_connected';

Возможно, вы захотите рассмотреть вопрос о закрытии соединений после завершения выполнения Thread, поскольку соединения с базой данных не закрываются автоматически (я думаю, что это не проблема с приложениями Ruby on Rails 4 Жнец):

Thread.new do
  begin
     # Thread work here
  ensure
     begin
        if (ActiveRecord::Base.connection && ActiveRecord::Base.connection.active?)
           ActiveRecord::Base.connection.close
        end
      rescue
      end
  end
end

Ответ 5

У меня возникла эта проблема при отправке действительно больших операторов в MySQL. MySQL ограничивает размер операторов и закрывает соединение, если вы переходите через предел.

set global max_allowed_packet = 1048576; # 2^20 bytes (1 MB) was enough in my case

Ответ 6

Соединение с сервером MySQL, вероятно, отключается.

Вы должны иметь возможность увеличить время ожидания в MySQL, но для правильного исправления попросите свой код проверить, что соединение с базой данных все еще жив, и повторно подключиться, если это не так.

Ответ 7

Вы отслеживаете количество открытых подключений или потоков MySQL? Каковы ваши настройки mysql.ini для max_connections?

mysql> show status;

Посмотрите на соединения, Max_used_connections, Threads_connected и Threads_created.

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

Примечание. Я использовал Ruby on Rails ненадолго...

Документация MySQL для статуса сервера находится в http://dev.mysql.com/doc/refman/5.0/en/server-status-variables.html.

Ответ 8

Использование reconnect: true в database.yml приведет к восстановлению соединения с базой данных ПОСЛЕ ВЫПОЛНЕНИЯ ошибки ActiveRecord:: StatementInvalid (как упоминал Дэйв Чейни).

К сожалению, добавление повторной попытки в операции с базой данных было необходимо для защиты от таймаута соединения:

begin
  do_some_active_record_operation
rescue ActiveRecord::StatementInvalid => e
  Rails.logger.debug("Got statement invalid #{e.message} ... trying again")
  # Second attempt, now that db connection is re-established
  do_some_active_record_operation
end

Ответ 9

Попробуйте ActiveRecord::Base.connection.verify! в Ruby on Rails 4. Проверьте, проверяет ли сервер и повторно подключается, если он не подключен.

Ответ 10

У меня была эта проблема в приложении Ruby on Rails 3, используя камень mysql2. Я скопировал нарушающий запрос и попытался запустить его непосредственно в MySQL, и я получил ту же ошибку: "Сервер MySQL ушел".

Вопрос был очень-очень большой. Очень большая вставка (+ 1 MB). В поле, которое я пытался вставить, был столбец TEXT, а их максимальный размер - 64 КБ. Вместо того, чтобы бросать ошибку, соединение ушло.

Я увеличил размер поля и получил то же самое, поэтому я все еще не уверен, что такое точная проблема. Дело в том, что это было в базе данных из-за какого-то странного запроса. В любом случае!

Ответ 11

Что-то еще, чтобы проверить конфигурацию Unicorn правильно. Ниже приведена ссылка before_fork и after_fork на соединение ActiveRecord: https://gist.github.com/nebiros/2776085#file-unicorn-rb