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
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).
Haz el dump simple de una base específica:
mysqldump -u root -p mibase > mibase-2026-05-29.sqlEl -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.
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.
Comprime al vuelo para ahorrar espacio:
mysqldump -u root -p \
--single-transaction --routines --triggers --events --quick \
mibase | gzip > mibase-2026-05-29.sql.gzEl 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.
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.
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.
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.
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 -lhead 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.
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.
Restaura el dump comprimido directo por pipe:
zcat mibase-2026-05-29.sql.gz | mysql -u root -p mibasezcat 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.sqlLa 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.
Sigue el progreso en dumps grandes:
pv mibase-2026-05-29.sql.gz | zcat | mysql -u root -p mibasepv (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%.
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.
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.
--single-transaction --routines --triggers --quick --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.