with rails example conectar con mysql ruby-on-rails

example - "El servidor MySQL se ha ido" con Ruby on Rails



rails with mysql (11)

Después de que nuestra aplicación Ruby on Rails se haya ejecutado por un tiempo, comienza a arrojar 500s con "El servidor MySQL se ha ido". A menudo esto sucede durante la noche. Ha comenzado a hacer esto recientemente, sin cambios obvios en la configuración de nuestro servidor.

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

Reiniciar los mongrels (no el servidor MySQL) lo corrige.

como podemos arreglar esto?


La conexión al servidor MySQL probablemente se agote.

Debería poder aumentar el tiempo de espera en MySQL, pero para una solución correcta, haga que su código verifique que la conexión de la base de datos aún esté activa y vuelva a conectarse si no es así.


El uso de reconexión: verdadero en la base de datos.yml causará que la conexión de la base de datos se restablezca DESPUÉS de que se produzca el error ActiveRecord :: StatementInvalid (como mencionó Dave Cheney).

Lamentablemente, al agregar un reintento en la operación de la base de datos, pareció necesario evitar el tiempo de espera de la conexión:

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



¿Monitoreas la cantidad de conexiones o hilos MySQL abiertos? ¿Cuál es la configuración de mysql.ini para max_connections?

mysql> show status;

Observe Conexiones, Max_used_connections, Threads_connected y Threads_created.

Es posible que necesite aumentar los límites en su configuración de MySQL, o quizás los rieles no cierren la conexión correctamente *.

Nota: solo he usado Ruby on Rails brevemente ...

La documentación de MySQL para el estado del servidor está en http://dev.mysql.com/doc/refman/5.0/en/server-status-variables.html .


Como han dicho otros colaboradores de este hilo, lo más probable es que el servidor MySQL haya cerrado la conexión a su aplicación Ruby on Rails debido a la inactividad. El tiempo de espera predeterminado es 28800 segundos u 8 horas.

set-variable = wait_timeout=86400

Agregar esta línea a su /etc/my.cnf elevará el tiempo de espera a 24 horas http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html#option_mysqld_wait_timeout .

Aunque la documentación no lo indica, un valor de 0 puede inhabilitar por completo el tiempo de espera, pero tendría que experimentar ya que esto es solo una especulación.

Sin embargo, hay otras tres situaciones que conozco que pueden generar ese error. El primero es el servidor MySQL que se reinicia. Obviamente, esto soltará todas las conexiones, pero como el cliente MySQL es pasivo, no se notará hasta que realices la siguiente consulta.

La segunda condición es si alguien elimina su consulta de la línea de comando de MySQL, y esto también deja de estar conectada, ya que podría dejar al cliente en un estado indefinido.

El último es si su servidor MySQL se reinicia debido a un error interno fatal. Es decir, si está haciendo una simple consulta en una tabla y ve instantáneamente ''MySQL se ha ido'', examinaría de cerca los registros de su servidor para verificar si hay errores de hardware o corrupción de la base de datos.


Esto probablemente se deba a que las conexiones persistentes con MySQL se van (el tiempo de espera es probable si está sucediendo durante la noche) y Ruby on Rails no está restableciendo la conexión, lo que debería estar haciendo por defecto:

En el proveedor de archivos / rails / actionpack / lib / action_controller / dispatcher.rb está el código:

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

El método verify_active_connections! realiza varias acciones, una de las cuales es recrear cualquier conexión vencida.

La causa más probable de este error es que esto se debe a que un parche mono ha redefinido al despachador para que no llame a verify_active_connections! ¡o verify_active_connections! ha sido cambiado, etc.


Primero, determine max_connections en MySQL:

show variables like "max_connections";

Debe asegurarse de que la cantidad de conexiones que está realizando en su aplicación Ruby on Rails sea menor que la cantidad máxima permitida de conexiones. Tenga en cuenta que las conexiones adicionales pueden provenir de sus trabajos cron , procesos de retraso de trabajo (cada uno tendría el mismo tamaño de grupo en su database.yml datos.yml), etc.

Supervise las conexiones SQL a medida que avanza en su aplicación, ejecute procesos, etc. haciendo lo siguiente en MySQL:

show status where variable_name = ''Threads_connected'';

Es posible que desee considerar el cierre de las conexiones después de que un Thread finalice la ejecución, ya que las conexiones de la base de datos no se cierran automáticamente (creo que esto es un problema menor con Reaper, aplicaciones de Ruby on Rails):

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


Prueba ActiveRecord::Base.connection.verify! en Ruby on Rails 4. Verifique que el servidor se conecte y vuelva a conectar si no está conectado.



Tuve este problema al enviar declaraciones realmente grandes a MySQL. MySQL limita el tamaño de las declaraciones y cerrará la conexión si supera el límite.

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


Tuve este problema en una aplicación de Ruby on Rails 3, usando la gema mysql2 . Copié la consulta ofensiva e intenté ejecutarla en MySQL directamente, y obtuve el mismo error, "El servidor MySQL se ha ido".

La consulta en cuestión fue muy, muy grande. Un inserto muy grande (+1 MB). El campo en el que traté de insertar era una columna TEXTO y su tamaño máximo es 64 KB. En lugar de lanzar un error, la conexión desapareció.

Aumenté el tamaño del campo y obtuve lo mismo, así que todavía no estoy seguro de cuál fue el problema exacto. El punto es que estaba en la base de datos debido a alguna consulta extraña. ¡De todas formas!