«Сервер MySQL ушел» с Ruby on Rails - PullRequest
38 голосов
/ 19 сентября 2008

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

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

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

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

Ответы [ 11 ]

61 голосов
/ 24 июля 2009

В Ruby on Rails 2.3 есть опция переподключения для подключения к вашей базе данных:

production:
  # Your settings
  reconnect: true

См:

Удачи!

22 голосов
/ 19 сентября 2008

Это, вероятно, вызвано прекращением постоянных подключений к 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! был изменен и т. Д.

5 голосов
/ 12 января 2014

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

4 голосов
/ 19 сентября 2008

Как говорили другие участники этого потока, наиболее вероятно, что сервер 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, и это также разрывает соединение, потому что это может оставить клиента в неопределенном состоянии.

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

2 голосов
/ 27 мая 2014

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

set global max_allowed_packet = 1048576; # 2^20 bytes (1 MB) was enough in my case
2 голосов
/ 26 июля 2013

Сначала определите 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 Reaper ):

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
1 голос
/ 28 сентября 2011

Использование 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
1 голос
/ 19 сентября 2008

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

mysql> show status;

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

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

Примечание: я только кратко использовал Ruby on Rails ...

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

1 голос
/ 19 сентября 2008

Время соединения с сервером MySQL, вероятно, истекло.

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

0 голосов
/ 07 марта 2014

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

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