¿Hay un reinicio elegante o seguro para mysql como para apache httpd?

29

Me gustaría reiniciar mysql con gracia al igual que httpd donde se sirven los hilos antes de reiniciar. No me gustaría que las consultas se rompan.

giorgio79
fuente

Respuestas:

37

Cualquier secuencia de cierre "solicitada" en MySQL (corta kill -9) es algo elegante , ya que las transacciones en curso (en las tablas transaccionales) se revierten, pero aquí hay un par de formas de hacer que un reinicio sea lo más limpio posible.

Nota: si está cerrando el servidor para una actualización, no use este proceso; en su lugar, siga el proceso detallado en esta respuesta .

De lo contrario, si solo está reiniciando un servidor de otro modo saludable para que pueda cambiar una variable global de solo lectura o algo similar, aquí hay una ruta elegante:

Primero, habilítelo innodb_fast_shutdownsi aún no lo está. Esto no está directamente relacionado con la gracia del apagado, pero debería hacer que su servidor vuelva más rápido.

mysql> SHOW VARIABLES LIKE 'innodb_fast_shutdown';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| innodb_fast_shutdown | 0     |
+----------------------+-------+
1 row in set (0.00 sec)

mysql> SET GLOBAL innodb_fast_shutdown = 1;
Query OK, 0 rows affected (0.01 sec)

A continuación, indique al servidor que cierre todas las tablas abiertas tan pronto como ninguna consulta que se esté ejecutando actualmente haga referencia a ellas. Este paso tampoco tiene nada que ver con el apagado elegante, pero hará que el siguiente paso sea más rápido:

mysql> FLUSH LOCAL TABLES;
Query OK, 0 rows affected (41.12 sec)

La FLUSH TABLESdeclaración (con la LOCALpalabra clave opcional , que evita una descarga innecesaria pero inofensiva de cualquier esclavo) se bloqueará y su mensaje no volverá hasta que se puedan cerrar todas las tablas. Una vez que cada tabla ha sido "vaciada" (cerrada), si una consulta posteriormente hace referencia a la tabla, se volverá a abrir automáticamente, pero está bien. Lo que estamos logrando con este paso es hacer menos trabajo para el paso final:

mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (13.74 sec)

mysql>

Esta declaración vacía todas las tablas (de ahí la ventaja de sacar parte de eso de manera menos disruptiva con el paso anterior) y adquiere un bloqueo global de solo lectura (en todo el servidor) en ellas.

No puede tener un bloqueo de lectura global hasta que todas las consultas de "escritura" que se estén ejecutando actualmente (es decir, casi todo, pero SELECT) estén terminadas. La emisión de la solicitud de bloqueo permitirá que finalicen las consultas existentes, pero no permitirá que comiencen otras nuevas.

Su solicitud no regresa hasta que mantenga este bloqueo global, por lo que cada consulta que está en curso cuando solicita el bloqueo puede finalizar, y sabe que están finalizadas, porque recupera la solicitud. Cualquier consulta posterior que intente escribir algo en cualquier tabla simplemente se detendrá, no cambiará ningún dato, esperará indefinidamente el bloqueo, hasta ...

  • cambia de opinión sobre el reinicio y libera el bloqueo manualmente ( UNLOCK TABLES;)
  • reinicia el servidor o
  • desconecta accidental o intencionalmente el cliente de línea de comandos de este hilo (así que no lo haga). Mantenga esta ventana conectada y sentada en el indicador de mysql:

Resista la tentación de cerrar esto.

mysql>

Este indicador de consola inactiva es lo que mantiene el bloqueo global para usted. Pierde esto, pierde la cerradura.

Desde otra ventana de consola, reinicie MySQL como lo haría normalmente, ya sea con initscripts (por ejemplo, su variante local de service mysql.server restart) o mysqladmin shutdownseguido de un reinicio manual.

Michael - sqlbot
fuente
¿El uso innodb_fast_shutdown = 1realmente garantiza que MySQL se inicie más rápido? Mirando los documentos, parece que esto mejora la velocidad de apagado (¿a costa de la velocidad de inicio?).
Chris
@Chris, la idea es que ayuda a asegurar que todo el apagado + inicio sea tan rápido como sea práctico, pero es algo anecdótico ya que la cantidad de trabajo que se realiza es teóricamente la misma, solo se trasladó al otro lado de la secuencia, aún Por alguna razón, siempre ha parecido en general más rápido en general, como tal vez haya una ineficiencia en la forma en que ocurre en el apagado que no está allí en el inicio. Difícil de decir.
Michael - sqlbot
2

En resumen, algunas de las mejores prácticas que deben considerarse antes de cerrar MySQL son:

  1. Confirme la instancia que va a cerrar para evitar detener otra instancia por error.
  2. Detenga la replicación si va a apagar un esclavo mysql> STOP SLAVE;.
  3. Enjuague las páginas sucias de antemano para reducir el tiempo de apagado mysql> SET GLOBAL innodb_max_dirty_pages_pct = 0;.
  4. Verifique las consultas de larga duración mysql> SHOW PROCESSLIST;, elimínelas mysql> kill thread_id;o espere hasta que terminen.
  5. Volcar el grupo de búferes al apagar mysql> SET GLOBAL innodb_buffer_pool_dump_at_shutdown = ON;y volver a cargarlo al inicio # vi /etc/my.cnf innodb_buffer_pool_load_at_startup = ON para calentar el grupo de búferes.

Luego, después de confirmar los puntos anteriores, puede reiniciar MySQL de forma segura shell$ service mysql restart

Para obtener más detalles, consulte mi publicación. ¡ Compruebe esto antes de cerrar MySQL!

Prostituta
fuente
¿Por qué se rechazó esto? No sé lo suficiente como para reconocer qué comando (s) son malos, pero quiero saberlo para poder evitarlos.
Jon
No sé nada de lo anterior es un mal comando. Estoy siguiendo los pasos anteriores y mucha gente lo hace. Solo el paso 4 debe ser con precaución, no debe eliminar ninguna consulta hasta que esté seguro de lo que está haciendo, de lo contrario, espere hasta que finalicen las consultas de larga duración. Pruébalo y, si te ayudó, vota a favor, si no, ¡vota a favor!
Moll