Detener el servidor MySQL parece una tarea sencilla, pero hacerlo incorrectamente puede resultar en pérdida de datos, corrupción de tablas o transacciones incompletas. MySQL necesita tiempo para cerrar ordenadamente: debe completar las transacciones en curso, vaciar los buffers de InnoDB a disco, cerrar archivos abiertos y liberar los bloqueos. En este artículo aprenderás las diferentes formas de detener MySQL y las precauciones que debes tomar antes de hacerlo.
Detener MySQL con systemd
En sistemas Linux con systemd, el comando estándar para detener MySQL es:
sudo systemctl stop mysqlEn distribuciones basadas en Red Hat, el nombre del servicio suele ser mysqld:
sudo systemctl stop mysqldSystemd envía la señal SIGTERM al proceso mysqld, que inicia un cierre ordenado. Puedes verificar que el servicio se detuvo correctamente:
sudo systemctl status mysql● mysql.service - MySQL Community Server
Loaded: loaded (/lib/systemd/system/mysql.service; enabled)
Active: inactive (dead) since Tue 2025-03-18 14:30:22 UTC; 3s ago
Process: 3467 ExecStart=/usr/sbin/mysqld
(code=exited, status=0/SUCCESS)
Main PID: 3467 (code=exited, status=0/SUCCESS)
Mar 18 14:30:22 db-server systemd[1]: Stopping MySQL Community Server...
Mar 18 14:30:22 db-server systemd[1]: mysql.service: Succeeded.
Mar 18 14:30:22 db-server systemd[1]: Stopped MySQL Community Server.
La línea Active: inactive (dead) y el status=0/SUCCESS confirman que el servidor se detuvo limpiamente.
Detener MySQL con mysqladmin
La herramienta mysqladmin ofrece el comando shutdown para detener el servidor desde la línea de comandos. A diferencia de systemd, que opera a nivel del sistema operativo, mysqladmin se conecta al servidor MySQL como un cliente y envía el comando de apagado internamente:
mysqladmin -u root -p shutdownEnter password: ********
Esta opción es especialmente útil cuando no tienes acceso a systemd (por ejemplo, en un contenedor Docker minimalista) o cuando necesitas detener una instancia específica entre varias que corren en la misma máquina:
mysqladmin -u root -p --socket=/tmp/mysql-test.sock shutdownEl usuario que ejecuta el shutdown necesita el privilegio SHUTDOWN:
GRANT SHUTDOWN ON *.* TO 'admin'@'localhost';Detener MySQL en Windows
En Windows, puedes detener el servicio desde la línea de comandos con permisos de administrador:
net stop MySQL80The MySQL80 service is stopping.
The MySQL80 service was stopped successfully.
O desde PowerShell:
Stop-Service -Name MySQL80También puedes detenerlo desde el panel de Servicios (services.msc), haciendo clic derecho en el servicio de MySQL y seleccionando "Detener".
Cierre ordenado vs cierre forzado
Cuando MySQL recibe una solicitud de apagado ordenado, sigue una secuencia de pasos que garantizan la integridad de los datos.
Primero, deja de aceptar nuevas conexiones. Las conexiones existentes que tienen transacciones activas reciben tiempo para completarlas. Luego, InnoDB vacía todas las páginas modificadas del buffer pool a los archivos de datos (un proceso llamado "flush"), escribe un checkpoint en el redo log y cierra los archivos de tablespace. Finalmente, el proceso mysqld termina.
Este proceso puede tardar desde unos pocos segundos hasta varios minutos, dependiendo del tamaño del buffer pool y la cantidad de datos pendientes de escribir a disco. La variable innodb_fast_shutdown controla qué tan exhaustivo es este proceso:
SHOW VARIABLES LIKE 'innodb_fast_shutdown';| Variable_name | Value |
|---|---|
| innodb_fast_shutdown | 1 |
Los valores posibles son:
-- Valor 0: Cierre completo (slow shutdown)
-- InnoDB hace un purge completo y merge del change buffer
-- Puede tardar minutos u horas en servidores grandes
SET GLOBAL innodb_fast_shutdown = 0;
-- Valor 1: Cierre rápido (por defecto)
-- No hace purge ni merge completo, pero sí vacía buffers
-- Adecuado para reinicios normales
SET GLOBAL innodb_fast_shutdown = 1;
-- Valor 2: Cierre inmediato
-- Solo vacía el log, no los buffers de datos
-- Al reiniciar, InnoDB necesita hacer crash recovery
SET GLOBAL innodb_fast_shutdown = 2;Para actualizaciones de versión de MySQL, se recomienda usar el valor 0 para asegurar que todos los datos estén perfectamente escritos antes de cambiar binarios.
Verificar conexiones activas antes de detener
En un servidor de producción, nunca debes detener MySQL sin antes verificar si hay conexiones activas realizando trabajo importante. Un cierre durante una operación ALTER TABLE en una tabla grande o una importación masiva podría dejar la tabla en un estado inconsistente.
SHOW PROCESSLIST;| Id | User | Host | db | Command | Time | State | Info |
|---|---|---|---|---|---|---|---|
| 45 | app_web | 10.0.1.5:49832 | tienda | Query | 0 | executing | SELECT * FROM productos... |
| 78 | etl_usr | 10.0.1.8:51203 | analytics | Query | 347 | Sending data | INSERT INTO fact_ventas SE... |
| 92 | admin | localhost | NULL | Query | 0 | starting | SHOW PROCESSLIST |
En este ejemplo, el proceso 78 lleva casi 6 minutos ejecutando una inserción masiva. Detener el servidor ahora causaría un rollback de esa transacción. Lo más responsable es esperar a que termine o, si es urgente, avisar al equipo que la operación se interrumpirá.
Para ver solo las consultas que llevan más de 60 segundos en ejecución:
SELECT id, user, host, db, command, time, info
FROM information_schema.PROCESSLIST
WHERE command != 'Sleep'
AND time > 60
ORDER BY time DESC;Caso práctico: apagado planificado para mantenimiento
Imagina que necesitas detener MySQL para una actualización del sistema operativo. El procedimiento seguro sería:
-- 1. Verificar conexiones activas con consultas largas
SELECT id, user, time, SUBSTRING(info, 1, 80) AS consulta
FROM information_schema.PROCESSLIST
WHERE command NOT IN ('Sleep', 'Daemon')
AND time > 30;
-- 2. Activar el modo read_only para evitar nuevas escrituras
SET GLOBAL read_only = ON;
SET GLOBAL super_read_only = ON;
-- 3. Esperar a que las consultas activas terminen
-- (repetir la consulta anterior hasta que no haya resultados)
-- 4. Asegurar un cierre limpio completo
SET GLOBAL innodb_fast_shutdown = 0;Luego, desde la terminal:
sudo systemctl stop mysqlCon innodb_fast_shutdown = 0, el cierre será más lento pero dejará los datos en el estado más limpio posible. Esto es particularmente importante si la máquina va a estar apagada por un tiempo prolongado o si se va a mover el directorio de datos.
Caso práctico: detener MySQL que no responde
En situaciones extremas, mysqld puede dejar de responder a las solicitudes de apagado. Esto puede ocurrir por un bloqueo interno (deadlock del sistema), falta de espacio en disco o un bug del servidor.
Si systemctl stop queda colgado por más de unos minutos, puedes verificar el estado del proceso:
# Ver si el proceso está consumiendo CPU
top -p $(pgrep mysqld)
# Revisar el log de errores
sudo tail -f /var/log/mysql/error.logSi el proceso está completamente bloqueado y no hay otra opción, puedes forzar su terminación como último recurso:
sudo kill -9 $(pgrep mysqld)Ten en cuenta que después de un kill forzado, InnoDB realizará una recuperación automática (crash recovery) al siguiente inicio. Este proceso revisa el redo log y deshace las transacciones incompletas. Aunque InnoDB es muy robusto en este escenario, siempre existe un riesgo mínimo, por lo que es la opción de último recurso.
Detener MySQL de forma correcta protege la integridad de tus datos y asegura que el siguiente arranque sea rápido y limpio. En el siguiente artículo veremos cómo reiniciar el servidor y en qué situaciones es necesario hacerlo.
Escrito por Eduardo Lázaro
