При каких обстоятельствах вы бы хотели, чтобы Rails не устанавливал соединение с MYSQL - PullRequest
13 голосов
/ 08 октября 2009

Я испытываю несколько ошибок в приложении rails, например:

ActiveRecord::StatementInvalid: Mysql::Error: Lost connection to MySQL server during query: SELECT * FROM `actions` WHERE (`foo`.`id` = 16)

Похоже, что происходит то, что mysql-соединение закрывается по истечении времени ожидания, а rails не замечает, пока не станет слишком поздно.

Я нашел средств правовой защиты , которые выглядят как , чтобы установить для флага переподключения значение true в database.yaml или для любого действия базы данных, добавив некоторый код, подобный так:

def some_database_operation
  begin
    Account.find(1)
    # or some other database operations here...
  rescue ActiveRecord::StatementInvalid
    ActiveRecord::Base.connection.reconnect!
    unless @already_retried
      @already_retried = true
      retry 
    end
    raise
  else
    @already_retried = false
  end
end
end

Я перечисляю эту опцию поверх этой, видимой здесь , поскольку эта опция, по-видимому, небезопасна для транзакций:

ActiveRecord::ConnectionAdapters::MysqlAdapter.module_eval do
  def execute_with_retry_once(sql, name = nil)
    retried = false
    begin
      execute_without_retry_once(sql, name)
    rescue ActiveRecord::StatementInvalid => exception
      ActiveRecord::Base.logger.info "#{exception}, retried? #{retried}"

      # Our database connection has gone away, reconnect and retry this method
      reconnect!
      unless retried
        retried = true
        retry
      end
    end
  end

  alias_method_chain :execute, :retry_once
end

Из опций, позволяющих избежать этой надоедливой ошибки, опция переподключения в файле yaml кажется самой опрятной, но мне любопытно; почему в вашей базе данных по умолчанию не установлено значение true?

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

Спасибо

Ответы [ 2 ]

13 голосов
/ 10 октября 2009

Как вы указали в этом вопросе, одним из возможных побочных эффектов автоматического повторного подключения (если оно выполняется на уровне выписки) является то, что он не безопасен для транзакций.

Документация MySQL фактически прямо заявляет, что функция автоматического переподключения влияет на транзакции:

Любые активные транзакции откатываются, и режим автоматического принятия сброс.

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

Кроме того, если соединение с базой данных внезапно потеряно, сервер может неправильно освободить блокировки, удерживаемые соединением, поэтому в некоторых случаях может показаться, что приложение может заблокироваться:

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

6 голосов
/ 10 октября 2009

Из примечаний к выпуску Rails 2.3 1002 * (выделено мной):

4.8 Переподключение MySQL Connections

MySQL поддерживает флаг переподключения в своих соединениях - если установлено значение true, тогда клиент попытается переподключиться к серверу, прежде чем отказаться в случае потери соединения. Теперь вы можете установить reconnect = true для ваших подключений MySQL в database.yml, чтобы получить это поведение из приложения Rails. По умолчанию установлено значение false, , поэтому поведение существующих приложений не меняется.

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