2011-12-22 7 views
6

que estoy experimentando problemas para actualizar mis rieles 2.3.14/Ruby 1.8.7 aplicación 3.1.1/1.9.2: Tengo un poco deRails 3.1/mysql2 de error: "El servidor MySQL se ha apagado"

(ActiveRecord::StatementInvalid) "Mysql2::Error: MySQL server has gone away" 

errores que ocurren esporádicamente. Es importante precisar que nunca tuve tales problemas con la gema 'mysql' en 2.3.14 y el mismo db exacto (entonces el error no debería provenir de mysql (v5.5.10)).

Ejemplo:

$ rails c production 
Loading production environment (Rails 3.1.1) 
ruby-1.9.2-p290 :001 > ActiveRecord::Base.connection.active? 
=> false 
ruby-1.9.2-p290 :002 > exit 
$ rails c production 
Loading production environment (Rails 3.1.1) 
ruby-1.9.2-p290 :001 > ActiveRecord::Base.connection.active? 
=> true 

Esto ocurre sólo con mi (remoto) de base de datos de producción, no hay problema con mi db desarrollo local. He tratado de establecer "reconexión: true" en mi database.yml pero condujo a una

Mysql2::Error: Host '****' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts':... 

He tratado de aislar el problema con un pequeño script rb única carga mysql2 y activerecord pero yo no' t logra reproducir el error de esa manera (por lo que puede estar vinculado a la pila de rieles).

No puedo volver de la gema 'mysql2' a la 'mysql' debido a problemas de codificación (http://www.rorra.com.ar/2010/07/30/rails-3-mysql-and-utf-8/). Como consecuencia, tuve que retrotraer mi producción a mi aplicación carriles 2.3.14, lo que me entristece mucho ...

¿Ve lo que puedo hacer para depurar esto? Ni siquiera puedo encontrar una manera segura de reproducir el error ... ¿Alguien ha encontrado el mismo error?

Acabo de encontrar algunas personas que mencionen este error (por ejemplo, https://github.com/brianmario/mysql2/issues/213) pero no una solución.

Gracias por su ayuda.

Respuesta

11

Ok, creo que he resuelto mi problema. No me di cuenta cuando publiqué mi pregunta, pero parecía que el error estaba relacionado con el tiempo de espera: después de unos 20 segundos, activerecord pierde su conexión.

$ rails runner "sleep 23; puts ActiveRecord::Base.connection.active?" 
=> true 
$ rails runner "sleep 25; puts ActiveRecord::Base.connection.active?" 
=> false 

cavé más y me di cuenta de que MySQL y mysql2 joyas no trataban con el MySQL 'wait_timeout Param la misma manera: joya MySQL no establece que por lo tanto utiliza el MySQL default value 28800, mientras que si no se mysql2 gem sets it at 2592000 definido en la base de datos.yml. Pero tengo la impresión de que el valor 2592000 está por encima del valor máximo para este parámetro: 2147483! Lo que podría conducir al comportamiento inesperado que describí ...

construyo una prueba de secuencia de comandos que muestra el error: https://gist.github.com/1514154

Y si tuviera cierta desconexión aparentemente aleatoria, mientras que los carriles de carga de la consola (cf mi pregunta), creo que es debido a mi aplicación tomando mucho tiempo para cargar y a veces esperando unos segundos antes de escribir mi comando.

No puedo explicar por qué somos tan pocos para encontrar este problema. Quizás es específico de mi conf (base de datos remota, ¿versión de MySQL?). Lo he intentado con otra base de datos de puesta en marcha remota: el error no se reprodujo ...

Como conclusión, estableceré wait_timeout: 2147483 en mi base de datos.yml. Y tal vez extraiga los rieles de solicitud ...

+0

Gracias, esto pareció arreglar mis errores aleatorios de 'desaparecidos'. – Delameko

+0

2147483 límite es para ventanas, ¿verdad? Está en el bloque "Tipo (ventanas)". Para otras plataformas, el límite es 31536000. http://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_wait_timeout – kenn

+0

Probado con 'mysql2 0.3.16' y' activerecord 4.0. 0/4.1.4' en Windows 7 - 'wait_timeout' está funcionando, pero en los rieles reales estoy experimentando conexiones perdidas e incluso falta de memoria. – Paul

2

había una gran cantidad de conexiones perdidas - pero no podría decir si se fueron debido a lo siguiente pellizco o elsewise:/

Tuvo que tirar el siguiente script en inicializadores y añadir una línea de configuración a cada una de mis bases de datos en mi database.yml así:

... 
flags: <%= 65536 | 131072 %> 
... 

El guión es el siguiente:

/config/initializers/mysql2.rb

module ActiveRecord 
    class Base 
    # Overriding ActiveRecord::Base.mysql2_connection 
    # method to allow passing options from database.yml 
    # 
    # Example of database.yml 
    # 
    # login: &login 
    #  socket: /tmp/mysql.sock 
    #  adapter: mysql2 
    #  host: localhost 
    #  encoding: utf8 
    #  flags: 131072 
    # 
    # @param [Hash] config hash that you define in your 
    # database.yml 
    # @return [Mysql2Adapter] new MySQL adapter object 
    # 
    def self.mysql2_connection(config) 
     config[:username] = 'root' if config[:username].nil? 

     if Mysql2::Client.const_defined? :FOUND_ROWS 
     config[:flags] = config[:flags] ? config[:flags] | Mysql2::Client::FOUND_ROWS : Mysql2::Client::FOUND_ROWS 
     end 

     client = Mysql2::Client.new(config.symbolize_keys) 
     options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0] 
     ConnectionAdapters::Mysql2Adapter.new(client, logger, options, config) 
    end 
    end 
end 
+1

Gracias por su respuesta, pero no creo que nuestros 2 problemas estén relacionados: ¿probablemente tiene varias afirmaciones/consultas de resultados múltiples en su aplicación? Porque las banderas que está agregando corresponden a CLIENT_MULTI_RESULTS y CLIENT_MULTI_STATEMENTS, ¿no es así? Por cierto, el uso de Mysql2 :: Client :: MULTI_STATEMENTS y ​​Mysql2 :: Client :: PS_MULTI_RESULTS (en lugar de enteros sin procesar) debería funcionar. – Flackou

Cuestiones relacionadas