¿Cómo matar adecuadamente MySQL?


28

Tengo CentOS de 64 bits con CPanel instalado y uso:

service mysql stop

Simplemente sigue marcando períodos y nunca parece que se detenga. En los registros solo publica una gran cantidad de:

130303 17:42:38 [Warning] /usr/sbin/mysqld: Forcing close of thread

En el err.logarchivo, veo muchos de estos:

[Warning] /usr/sbin/mysqld: Forcing close of thread

Solía ​​ser instantáneo. ¿Alguna idea de por qué hace eso y cómo solucionarlo?

En este momento tengo que hacerlo, killall -9 mysqlpero ¿hay una mejor manera?

El servidor también es muy muy activo.

¿Es esto un problema de configuración? ¿Tengo la configuración de memoria demasiado alta?

[mysqld]
default-storage-engine=MyISAM
local-infile=0
symbolic-links=0
skip-networking
max_connections = 500
max_user_connections = 20
key_buffer = 512M
myisam_sort_buffer_size = 64M
join_buffer_size = 64M
read_buffer_size = 12M
sort_buffer_size = 12M
read_rnd_buffer_size = 12M
table_cache = 2048
thread_cache_size = 16K
wait_timeout = 30
connect_timeout = 15
tmp_table_size = 64M
max_heap_table_size = 64M
max_allowed_packet = 64M
max_connect_errors = 10
query_cache_limit = 1M
query_cache_size = 64M
query_cache_type = 1
low_priority_updates=1
concurrent_insert=ALWAYS
log-error=/var/log/mysql/error.log
tmpdir=/home/mysqltmp
myisam_repair_threads=4
[mysqld_safe]
open_files_limit = 8192
log-error=/var/log/mysql/error.log

[mysqldump]
quick
max_allowed_packet = 512M

[myisamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M

Respuestas:


37

La forma más ingeniosa de cerrar mysql cuando lo hace es simplemente ejecutar

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

Aquí es por qué:

El archivo de servicio mysql ( /etc/init.d/mysql) se basa en la presencia del archivo socket. Hablando históricamente, volviendo a MySQL 4.0, el archivo de socket a veces desaparece inexplicablemente. Esto dificulta un estándar service mysql stopde trabajo.

No es suficiente decir

mysqladmin -uroot -p -h127.0.0.1 shutdown

porque ruta mysqld un usuario entrando como root@127.0.0.1a root@localhostsi TCP / IP no está habilitado de forma explícita. De forma predeterminada, mysqld elegirá la menor ruta de resistencia y se conectará root@127.0.0.1a root@localhosttravés del archivo socket. Sin embargo, si no hay un archivo de socket, root@localhostnunca se conectará.

Incluso la documentación de MySQL en mysqladmin dice esto:

Si ejecuta el apagado de mysqladmin cuando se conecta a un servidor local utilizando un archivo de socket Unix, mysqladmin espera hasta que se haya eliminado el archivo de ID de proceso del servidor, para asegurarse de que el servidor se haya detenido correctamente.

Por eso es imprescindible habilitar TCP / IP:

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

El 30 de septiembre de 2011, escribí mi propia versión de mysqld_multillamada mysqlservice(consulte mi publicación: Ejecución de varias instancias en el mismo host ). Sirve como un motor virtual para conectarse a mysqld desde diferentes puertos. Solo tiene que traer los suyos my.cnfcon parámetros personalizados. En ese guión, publico paradas como esta:

stop() {
  ${ECHO} -n $"Stopping ${PROGNAME}"
  ${MYSQLD_STOP}
  ATTEMPTS=0
  STOPPING_MYSQLD=1
  MINUTES_TO_TRY=10
  (( TICKS_TO_TRY = MINUTES_TO_TRY*240 ))
  while [ ${STOPPING_MYSQLD} -eq 1 ]
  do
    ${ECHO} -n "."
    ${SLEEP} 0.25
    MYSQLD_HAS_BEEN_SHUTDOWN=`${TAIL} ${MYSQL_ERROR_LOG} | ${GREP} -c "Shutdown complete$"`
    (( ATTEMPTS++ ))
    if [ ${ATTEMPTS} -eq ${TICKS_TO_TRY}   ] ; then STOPPING_MYSQLD=0 ; fi
    if [ ${MYSQLD_HAS_BEEN_SHUTDOWN} -eq 1 ] ; then STOPPING_MYSQLD=2 ; fi
  done
  ${ECHO}
  if [ ${STOPPING_MYSQLD} -eq 2 ]
  then
    ${ECHO} "Stopped ${PROGNAME}"
  else
    ${TAIL} -30 ${MYSQL_ERROR_LOG}
  fi
}

Pero que es ${MYSQLD_STOP}?

MYSQL_CONN="-uroot -p<rootpassword> -P${MYSQLD_PORT} -h127.0.0.1 --protocol=tcp"
MYSQLD_STOP="${MYSQLADMIN} ${MYSQL_CONN} shutdown"

Tenga en cuenta que uso 127.0.0.1y un puerto explícito. De esa manera, no estoy confiando en un archivo de socket.

Siempre he usado mysqladmin --protocol=tcp shtudowncomo la alternativa adecuada a los cierres de mysql si se service mysql stopbloquea. Si lo hace kill -9en mysqldy mysqld_safesi el último de los últimos de los últimos recursos. (Sí, dije las últimas tres veces).

Muchas veces, mysqld ha eliminado mysql.sock sin previo aviso. Otras personas también han tenido este problema a lo largo de los años:

EPÍLOGO

El secreto es tal como dije: conéctese a mysql usando mysqladmin a través de TCP / IP ( --protocol=tcp) y emita shutdown. Esto tiene que funcionar porque el privilegio de apagado se realiza mysql.usercon el exclusivo propósito de los cierres autenticados. Esto me salvó el día de trabajo varias veces cuando pude emitir un apagado remoto desde mi máquina Windows al apagar mysqld en un servidor Linux.

ACTUALIZACIÓN 2013-03-06 22:48 EST

Si le preocupa lo que está sucediendo durante el apagado, hay una forma de manipular el tiempo de apagado y la forma en que los datos se vuelcan al disco, especialmente si tiene muchos datos InnoDB en el Buffer Pool

SUGERENCIA # 1

Si tiene muchas páginas sucias, puede reducir innodb_max_dirty_pages_pct a 0:

SET GLOBAL innodb_max_dirty_pages_pct = 0;

Establezca esto unos 15-30 minutos antes del apagado. Esto le dará a mysqld la menor cantidad posible de páginas sucias para escribir en el disco.

SUGERENCIA # 2

Por defecto, innodb_fast_shutdown es 1. Hay tres valores para esta opción

  • 0: InnoDB realiza un apagado lento, una purga completa y una fusión de búfer de inserción antes de apagarse.
  • 1: InnoDB omite estas operaciones en el apagado, un proceso conocido como apagado rápido.
  • 2: InnoDB vacía sus registros y se apaga, como si MySQL se hubiera bloqueado; no se pierden transacciones comprometidas, pero la operación de recuperación de fallos hace que el próximo inicio tarde más.

La documentación además dice esto:

El apagado lento puede llevar minutos o incluso horas en casos extremos donde aún se almacenan cantidades sustanciales de datos. Utilice la técnica de apagado lento antes de actualizar o degradar entre versiones principales de MySQL, de modo que todos los archivos de datos estén completamente preparados en caso de que el proceso de actualización actualice el formato del archivo.

Use innodb_fast_shutdown = 2 en situaciones de emergencia o solución de problemas, para obtener el apagado más rápido si los datos corren el riesgo de corrupción.

Los valores predeterminados para innodb_max_dirty_pages_pct e innodb_fast_shutdown deberían estar bien en la mayoría de los casos.


2
El archivo de socket desaparece en los derivados de Red Hat porque lo tmpwatchelimina, junto con todo lo demás /tmpque tiene un tiempo más antiguo que su umbral configurado.
Michael - sqlbot

Gracias, @ Michael-sqlbot Necesitaba escuchar eso de alguien, finalmente. Supongo que es por eso que alguien en MySQL AB (pre-Oracle, pre-Sun) decidió agregar el privilegio SHUTDOWN mysql.userpara evitar dolores de cabeza como este.
RolandoMySQLDBA

En el uso de Debian o Ubuntu mysqladmin --defaults-file=/etc/mysql/debian.cnf shutdown... ese archivo contiene credenciales para una cuenta MySQL tipo root.
0xC0000022L

Como de costumbre, @RolandoMySQLDBA es uno de los mejores recursos de DBA en los sitios de Stack Exchange. Gran trabajo aquí que me ayudó más de 6 años después.
JakeGould

5

Parece que su pregunta es menos sobre "cómo" cerrar MySQL y más sobre por qué la suya se está cerrando tan lentamente.

En mi respuesta a una pregunta similar , ofrecí algunas sugerencias para un reinicio sin problemas, que ayudan a reducir la cantidad de actividad que tiene que ocurrir después de que solicite que MySQL comience el proceso de apagado .

Si no es un usuario frecuente de SHOW FULL PROCESSLIST;ese elemento n. ° 1, porque necesita tener una idea de lo que está sucediendo en su servidor que está haciendo que el apagado sea tan lento. Si hay consultas de larga duración que son seguras para interrumpir, puede eliminarlas con KILL <thread-id>.

Recapitulando las otras sugerencias:

Establecer la variable global innodb_fast_shutdown = 1(el valor predeterminado) acelerará la parte del cierre de InnoDB. Sin embargo, esto solo es seguro si está cerrando el servidor por razones ajenas a la realización de una actualización. Si está cerrando para una actualización, esto debe establecerse en 0.

El uso FLUSH TABLES;cierra con gracia todas las mesas abiertas. Se volverán a abrir si se hace referencia en consultas posteriores, pero esta acción aún debería reducir el tiempo que transcurre entre el momento en que solicita el cierre y el momento en que se completa el cierre, ya que realiza algunas tareas de limpieza temprana y, lo que es más importante, prepara el escenario para el paso final ...

FLUSH TABLES WITH READ LOCK;cierra todas las tablas abiertas y obtiene un bloqueo exclusivo de su conexión de cliente actual que impide que cualquier otra conexión se escriba en cualquier tabla en todo el servidor. No volverá a recibir su mysql>solicitud hasta que posea este bloqueo, momento en el que puede emitir la solicitud de apagado, pero no se desconecte de esta sesión.

En un servidor ocupado, estos pasos deberían reducir el nivel de actividad en el servidor, deberían hacer las cosas mucho más silenciosas y deberían ayudar a hacer que el apagado o el reinicio sean más fluidos.


2

Es probable que MySQL no esté puramente bloqueado, sino que esté realizando actividades de limpieza (retrocesos, etc.) al cerrar. Si no deja que haga todo eso cuando se apaga, a menudo tendrá que esperar al iniciar.

Aquí hay algo para mirar: Apague mysql en una ventana de terminal mientras mira el registro de errores (tail -f [yourerror.log]) en otra ventana de terminal. El registro de errores le mostrará lo que está haciendo MySQL.


1

Lamento escuchar su experiencia y espero que mi experiencia con escenarios tontos de MySQL, similar a esto, pueda ayudarlo.

En lugar de tratar de descubrir cómo eliminar el servicio MySQL del servidor, en algunos casos, deberá verificar el estado de su sistema a través de lo siguiente para determinar si hay un abuso del servicio (la suposición se basa en la noción de un Entorno CentOS / RHEL ):

 /usr/bin/iostat
 /usr/bin/uptime
 top -c

Use lo siguiente para identificar la carga promedio del sistema y los recursos de mayor consumo dentro del sistema.

También deberá instalar mytoppara obtener una vista general de las instrucciones SQL que el sistema está procesando.

Para instalar mytop, simplemente realice lo siguiente:

 cd /root
 wget http://jeremy.zawodny.com/mysql/mytop/mytop-1.6.tar.gz
 tar -zxvf /root/mytop-1.6.tar.gz
 cd /root/mytop-1.6
 perl Makefile.pl
 make
 make install
 chmod 644 /usr/local/bin/mytop
 vi /usr/local/bin/mytop 

(use cualquier editor de texto que prefiera)

Buscar "long|!" => \$config{long_nums},

Comenta como #"long|!" => \$config{long_nums}:

chmod 555 /usr/local/bin/mytop

Y eres bueno para ir con mytop . Úselo para verificar las declaraciones de MySQL que están acaparando su servicio MySQL y detenerlas.

La ejecución de las instrucciones anteriores le proporcionará la siguiente capacidad:

  • Diagnóstico del estado / estado de su servidor
  • Diagnóstico de su causa del cuello de botella

Una vez que haya eliminado la causa del cuello de botella, debería tener un día más fácil cuando intente reiniciar el servicio MySQL. Espero que encuentre útil la información anterior.

Nota: mytop es antiguo y sin mantenimiento. Probablemente debería usarlo innotopen un sistema moderno.


0

La implementación estándar del guión de inicio de MySQL señala a MySQL con SIGTERM y espera una cierta cantidad de tiempo para que MySQL se cierre.

MySQL, después de recibir un SIGTERM, primero dejará de recibir nuevas conexiones, luego completará la ejecución de las consultas que aún estén pendientes (esto puede llevar un tiempo, dependiendo de su carga de trabajo y la cantidad de clientes concurrentes), luego comenzará a vaciar datos al disco (esto puede tomar mucho tiempo, nuevamente dependiendo de su carga de trabajo, configuraciones, memoria disponible y opciones de motor de almacenamiento). Después de que se realiza todo el enjuague de datos, MySQL luego desasignará cualquier memoria que haya asignado durante la etapa de inicialización (esto también puede tomar un tiempo, dependiendo de la cantidad de memoria asignada por MySQL), cerrará todos los identificadores de archivos que aún estén abiertos y luego llamará "salida (0)".

Si después de su solicitud de apagado, MySQL tarda mucho en apagarse, es muy posible que una o más de estas etapas tarde mucho en completarse. Si tiene tiempo, le recomiendo que espere a que se complete el proceso (esto evitará la pérdida de datos o los procesos de recuperación largos cuando inicie nuevamente su instancia de base de datos).

Lamentablemente, no hay suficiente información en su pregunta que me permita sugerir una solución adecuada para su problema. Espero que esto ayude a entender el problema.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.