Backup MySQL con mysqldump y Restaurar Base de Datos en Linux

Aprende a hacer backup MySQL con mysqldump y restaurar bases de datos en Linux con comandos listos, consistencia transaccional y validación.

Perder una base MySQL por dropear la tabla equivocada, corromper el archivo de datos o subir una migration mala le ocurre a cualquier equipo. La diferencia entre un incidente corto y un día entero de pánico es tener un backup reciente, validado y restaurable. Este tutorial cubre el flujo completo de backup con mysqldump y el restore subsiguiente, incluyendo los flags que realmente importan en producción.

El foco aquí es práctico: comandos listos para copiar, parámetros explicados en contexto y validación del archivo generado antes de que lo necesites de verdad. La persona es un developer que conoce MySQL básico (SELECT/INSERT) pero nunca configuró una rutina de backup propia — probablemente migrando de un hosting compartido a una VPS propia donde la responsabilidad ahora es suya.

Tiempo estimado: 15-20 minutos para ejecutar el tutorial completo sobre una base de ejemplo. En producción real, el dump en sí tarda proporcional al tamaño de la base (~1 GB/min en SSD NVMe típico).

Prerrequisitos

Lo que necesitas tener

Ubuntu 22.04 LTS o 24.04 LTS (Debian también sirve) con MySQL 8.0 o MariaDB 10.6+ instalado y corriendo. Acceso sudo en el servidor y credenciales del usuario root de MySQL o de un usuario con privilegios SELECT, LOCK TABLES, SHOW VIEW y EVENT sobre la base que vas a dumpear. Espacio libre en disco como mínimo igual al tamaño de la base (verifica con df -h).

Para confirmar que mysqldump está disponible, ejecuta:

mysqldump --version

La salida debe mostrar algo como mysqldump Ver 8.0.x for Linux on x86_64. Si el comando no se encuentra, instala el paquete client:

sudo apt update
sudo apt install -y mysql-client

Para MariaDB, el binario equivalente es el propio mariadb-dump (alias de mysqldump en distribuciones recientes).

Backup de la base con mysqldump

mysqldump lee el estado actual de MySQL y genera un archivo SQL con todos los comandos necesarios para recrear la base desde cero — CREATE DATABASE, CREATE TABLE, INSERT de cada fila, triggers, views y procedures. Es un formato portátil y versionable (incluso puedes commitearlo en Git, aunque no sea su uso principal).

01

Haz el dump simple de una base específica:

mysqldump -u root -p mibase > mibase-2026-05-29.sql

El -u root define el usuario, -p pide la contraseña interactivamente (más seguro que pasar -pcontrasena en la línea de comandos, que se filtra en el historial del shell y en ps aux). La redirección > guarda la salida en el archivo indicado.

Incluye la fecha en el nombre del archivo desde el inicio — ayuda en la rotación y evita la sobreescritura accidental.

02

Agrega los flags de consistencia transaccional para producción:

mysqldump -u root -p \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  --quick \
  mibase > mibase-2026-05-29.sql

--single-transaction envuelve el dump en START TRANSACTION con isolation REPEATABLE READ, generando un snapshot consistente sin bloquear escrituras en tablas InnoDB. Ese es el flag crítico en producción: sin él, escrituras paralelas pueden dejar el dump inconsistente.

Los flags --routines, --triggers y --events incluyen stored procedures, triggers y eventos programados — cosas que son fáciles de olvidar y que solo notas que faltan cuando restauras y el sistema se rompe. --quick hace el dump fila por fila en lugar de cargar tablas enteras en RAM, importante para tablas grandes.

03

Comprime al vuelo para ahorrar espacio:

mysqldump -u root -p \
  --single-transaction --routines --triggers --events --quick \
  mibase | gzip > mibase-2026-05-29.sql.gz

El pipe a gzip reduce el archivo en 70-85% en dumps típicos (el texto SQL comprime muy bien). Para bases de 10 GB, eso es la diferencia entre 2 GB y 10 GB ocupando tu disco de backup.

Para una compresión mejor (más lenta), cambia gzip por zstd -19 o xz -9.

04

Haz backup de todas las bases a la vez (útil para snapshot diario del servidor completo):

mysqldump -u root -p \
  --all-databases \
  --single-transaction \
  --routines --triggers --events \
  --master-data=2 \
  | gzip > full-2026-05-29.sql.gz

--all-databases incluye también las bases del sistema (mysql, sys, performance_schema) — preserva usuarios y grants. --master-data=2 graba la posición del binlog en el dump como comentario, útil para point-in-time recovery si tienes binlogs habilitados.

Contraseña en archivo de configuración

Para evitar escribir la contraseña en scripts automatizados, crea ~/.my.cnf con [client] + user=root + password=contrasena y permiso 600 (chmod 600 ~/.my.cnf). mysqldump lo lee automáticamente — ejecutas mysqldump mibase > archivo.sql sin -u ni -p. Nunca pongas contraseña en un script versionado.

Validación del archivo de backup

Un backup que nunca probaste restaurar es un rumor, no un backup. Antes de confiar en el archivo, valida tres cosas: integridad del archivo, sintaxis SQL y que el dump cubra lo que esperas.

05

Verifica que el archivo no haya sido truncado:

ls -lh mibase-2026-05-29.sql.gz
gzip -t mibase-2026-05-29.sql.gz && echo "OK: archivo integro"

gzip -t prueba la integridad de la compresión sin descomprimir. Si falla, el archivo está corrupto (generalmente disco lleno durante el dump o crash a mitad de camino). Vuelve a ejecutar el dump.

06

Inspecciona el contenido del dump:

zcat mibase-2026-05-29.sql.gz | head -30
zcat mibase-2026-05-29.sql.gz | grep -c "^INSERT INTO"
zcat mibase-2026-05-29.sql.gz | grep "^CREATE TABLE" | wc -l

head muestra el encabezado con la versión de mysqldump y la configuración. grep -c INSERT cuenta las líneas de insert (sanity check de volumen de datos). grep CREATE TABLE | wc -l cuenta tablas — ¿coincide con lo que esperas tener en la base?

Para comparar con el servidor original:

mysql -u root -p -e "SELECT COUNT(*) AS tablas FROM information_schema.tables WHERE table_schema='mibase';"

Los números deben coincidir.

Restaurar base de datos desde el dump

El restore es el camino inverso: leer el archivo SQL y enviarlo al servidor MySQL que ejecuta cada comando en secuencia. Esto puede ser en un servidor nuevo, en el mismo servidor tras un drop accidental, o para clonar datos de producción a un entorno de staging.

07

Crea la base vacía de destino (solo si no existe aún):

mysql -u root -p -e "CREATE DATABASE mibase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

Usa utf8mb4 siempre — soporta emoji y caracteres asiáticos completos. Saltar este paso es OK si el dump se hizo con --databases (que incluye el CREATE DATABASE en el archivo) o --all-databases.

08

Restaura el dump comprimido directo por pipe:

zcat mibase-2026-05-29.sql.gz | mysql -u root -p mibase

zcat descomprime en memoria y envía al cliente mysql, que ejecuta cada comando contra la base mibase. Para un archivo .sql no comprimido, usa redirección:

mysql -u root -p mibase < mibase-2026-05-29.sql

La operación tarda proporcional al tamaño (cada INSERT corre individualmente por defecto). Para dumps grandes, déjalo corriendo en tmux o screen para no interrumpir si la sesión SSH se cae.

09

Sigue el progreso en dumps grandes:

pv mibase-2026-05-29.sql.gz | zcat | mysql -u root -p mibase

pv (pipe viewer) muestra una barra de progreso y la velocidad. Instálalo con sudo apt install -y pv. Sin él, el restore corre silencioso — no sabes si estás en el 10% o en el 90%.

Restore en una base existente sobrescribe datos

Si la base ya tiene tablas, el dump (que contiene DROP TABLE IF EXISTS) va a borrar las versiones actuales y recrearlas. En producción, haz el restore en una base con nombre distinto primero (mibase_restore) y valida antes de promover vía RENAME.

Verificación post-restore

Un restore que no fue verificado es medio restore. Comprueba tres cosas: las tablas regresaron, el conteo de filas coincide y la aplicación puede abrir conexión.

10

Confirma estructura y conteos:

mysql -u root -p mibase -e "SHOW TABLES;"
mysql -u root -p mibase -e "SELECT COUNT(*) FROM usuarios;"

El primero lista las tablas; el segundo cuenta filas en una tabla de la que sabes cuántas filas tenía antes. Las discrepancias indican un dump incompleto (faltó un flag) o un restore interrumpido.

Flag crítico InnoDB --single-transaction
Incluye procedures --routines
Incluye triggers --triggers
Dump streaming --quick
Posición binlog --master-data=2

Resolución de problemas

Error “Access denied” durante el dump

El usuario no tiene privilegio sobre alguna tabla. Verifica grants con SHOW GRANTS FOR 'usuario'@'localhost';. Para un dump completo, el usuario necesita SELECT, LOCK TABLES, SHOW VIEW, EVENT y TRIGGER. La solución más simple es ejecutar como root.

El restore falla con “Unknown collation utf8mb4_0900_ai_ci”

El dump se hizo en MySQL 8.0+ y estás restaurando en 5.7 o MariaDB antiguo. Edita el archivo (sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' archivo.sql) o regenera el dump con --compatible=mysql57.

”MySQL server has gone away” a mitad del restore

max_allowed_packet muy pequeño en el servidor de destino. Auméntalo en /etc/mysql/mysql.conf.d/mysqld.cnf con max_allowed_packet = 256M, reinicia MySQL e inténtalo otra vez.

Próximos pasos

El backup manual es el comienzo — automatízalo con cron y copia a un storage externo (rclone para B2/S3 funciona bien). Considera también la replicación master-slave para tener una copia caliente disponible en segundos, y habilita binary logs para point-in-time recovery dentro del día.

Si estás corriendo MySQL en producción, una VPS Hostini ya viene con SSD NVMe y snapshots de disco como capa adicional de protección sobre el backup lógico de mysqldump — recovery rápido para desastres de infraestructura, sin reemplazar el dump SQL que es portátil entre servidores.

Preguntas frecuentes

¿Cuál es la diferencia entre mysqldump y snapshot del disco?

mysqldump genera un archivo SQL portátil (texto con CREATE TABLE e INSERTs), restaurable en cualquier servidor MySQL compatible, incluso en una versión diferente. El snapshot de disco es una copia binaria — más rápida en bases grandes, pero solo se restaura en el mismo motor/versión y requiere cuidado con las transacciones en vuelo. Para bases por debajo de 50 GB, mysqldump es el estándar.

¿mysqldump bloquea las tablas durante el backup?

Por defecto sí, con FLUSH TABLES WITH READ LOCK en MyISAM. En InnoDB, usa --single-transaction para hacer el dump dentro de una transacción consistente sin bloquear escrituras. Ese es el flag más importante para bases en producción.

¿Puedo restaurar el dump en una versión diferente de MySQL?

Sí, siempre que vayas de la versión más antigua a la más nueva (5.7 → 8.0, por ejemplo). Lo inverso puede fallar por sintaxis nueva no soportada. Para downgrade entre versiones, genera el dump con --compatible=mysql57 en el servidor más nuevo.

¿Cómo hago backup solo de algunas tablas?

Pasa los nombres de las tablas tras el nombre de la base: mysqldump -u root -p mibase usuarios pedidos > parcial.sql. Esto dumpea solo usuarios y pedidos de la base mibase. Útil para migrar datos específicos sin mover la base completa.

El archivo .sql quedó enorme — ¿cómo reducirlo?

Comprime con gzip en el pipe: mysqldump ... | gzip > backup.sql.gz. La compresión típicamente reduce 70-85% del tamaño. Para restaurar, usa zcat backup.sql.gz | mysql -u root -p mibase. Evita ocupar espacio temporal en disco durante la operación.

¿Cómo programo el backup para que se ejecute todos los días automáticamente?

Usa cron: crea /etc/cron.daily/mysql-backup con el script de dump y rotación. Guarda la contraseña en ~/.my.cnf con permiso 600 para no pasarla por línea de comandos. Combina con rsync o rclone para copiar a un storage externo justo después del dump.

Temas:
Próximos pasos Cloud Ryzen con NVMe y protección DDoS siempre activa.Pon en producción en un VPS Hostini →
¿Te resultó útil este tutorial?
Hablar por WhatsApp