Copiar base de datos
Copiar una base de datos es una tarea frecuente: crear un entorno de pruebas a partir de producción, clonar datos para un desarrollador, o migrar una base de datos entre servidores. MySQL no tiene un comando COPY DATABASE ni RENAME DATABASE integrado, pero combinando mysqldump con mysql puedes lograr exactamente lo mismo de forma fiable.
Copiar en el mismo servidor
Para crear una copia de una base de datos dentro del mismo servidor, el proceso consiste en crear la base de datos destino y luego volcar los datos directamente usando un pipe:
# Crear la base de datos destino
mysql -u root -p -e "CREATE DATABASE tienda_staging CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
# Copiar estructura y datos
mysqldump --single-transaction --routines --triggers --events \
-u root -p tienda_mysql | mysql -u root -p tienda_stagingEste comando usa mysqldump para leer la base de datos original y envía la salida directamente al cliente mysql que la escribe en la base de datos destino. No se crea ningún archivo intermedio en disco, lo que ahorra espacio y tiempo.
Si prefieres usar un archivo intermedio para verificar antes de restaurar:
# Exportar
mysqldump --single-transaction --routines --triggers --events \
-u root -p tienda_mysql > /tmp/tienda_mysql_copia.sql
# Importar en la nueva base de datos
mysql -u root -p tienda_staging < /tmp/tienda_mysql_copia.sql
# Limpiar el archivo temporal
rm /tmp/tienda_mysql_copia.sqlCopiar entre servidores
Para copiar una base de datos de un servidor a otro, combina mysqldump en el servidor origen con mysql apuntando al servidor destino:
# Directo con pipe a través de la red
mysqldump --single-transaction --routines --triggers --events \
-h servidor_origen -u admin -p tienda_mysql \
| mysql -h servidor_destino -u admin -p tienda_mysqlSi los servidores no tienen conectividad directa entre sí, usa SSH como intermediario:
# A través de SSH
mysqldump --single-transaction --routines --triggers --events \
-u root -p tienda_mysql \
| ssh usuario@servidor_destino "mysql -u admin -p tienda_mysql"Para bases de datos grandes, comprimir en tránsito reduce significativamente el tiempo de transferencia:
# Comprimido en tránsito
mysqldump --single-transaction --routines --triggers --events \
-u root -p tienda_mysql \
| gzip | ssh usuario@servidor_destino "gunzip | mysql -u admin -p tienda_mysql"Renombrar una base de datos
MySQL eliminó el comando RENAME DATABASE en la versión 5.1 porque podía causar pérdida de datos en ciertos escenarios. La forma segura de "renombrar" es copiar y luego eliminar la original:
# Paso 1: Crear la nueva base de datos
mysql -u root -p -e "CREATE DATABASE tienda_nueva CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
# Paso 2: Copiar todo
mysqldump --single-transaction --routines --triggers --events \
-u root -p tienda_antigua | mysql -u root -p tienda_nueva
# Paso 3: Verificar que la copia es correcta
mysql -u root -p -e "
SELECT 'tienda_antigua' AS origen, COUNT(*) AS tablas FROM information_schema.tables WHERE table_schema = 'tienda_antigua'
UNION ALL
SELECT 'tienda_nueva', COUNT(*) FROM information_schema.tables WHERE table_schema = 'tienda_nueva';
"
# Paso 4: Solo si la verificación es correcta, eliminar la original
mysql -u root -p -e "DROP DATABASE tienda_antigua"Copiar solo la estructura
Si necesitas una copia vacía de la base de datos, usa --no-data:
mysql -u root -p -e "CREATE DATABASE tienda_test"
mysqldump --no-data --routines --triggers --events \
-u root -p tienda_mysql | mysql -u root -p tienda_testLa base de datos tienda_test tendrá todas las tablas, índices, foreign keys, procedimientos almacenados y triggers, pero sin datos.
Copiar estructura y datos parciales
Puedes copiar la estructura completa y luego agregar datos solo de algunas tablas o con filtros:
# Primero la estructura completa
mysqldump --no-data --routines --triggers --events \
-u root -p tienda_mysql | mysql -u root -p tienda_staging
# Luego datos de tablas de catálogo (pequeñas)
mysqldump --no-create-info -u root -p tienda_mysql \
categorias marcas proveedores | mysql -u root -p tienda_staging
# Datos parciales de tablas grandes
mysqldump --no-create-info -u root -p tienda_mysql \
pedidos --where="fecha_pedido >= '2026-01-01'" | mysql -u root -p tienda_stagingVerificar la copia
Después de copiar, verifica que ambas bases de datos son consistentes:
-- Comparar número de tablas
SELECT
table_schema AS base_datos,
COUNT(*) AS total_tablas,
SUM(table_rows) AS total_filas_aprox
FROM information_schema.tables
WHERE table_schema IN ('tienda_mysql', 'tienda_staging')
GROUP BY table_schema;| base_datos | total_tablas | total_filas_aprox |
|---|---|---|
| tienda_mysql | 15 | 102450 |
| tienda_staging | 15 | 102450 |
-- Comparar tabla por tabla
SELECT
t1.table_name,
t1.table_rows AS filas_origen,
t2.table_rows AS filas_destino
FROM information_schema.tables t1
JOIN information_schema.tables t2
ON t1.table_name = t2.table_name
WHERE t1.table_schema = 'tienda_mysql'
AND t2.table_schema = 'tienda_staging'
ORDER BY t1.table_name;| table_name | filas_origen | filas_destino |
|---|---|---|
| categorias | 15 | 15 |
| clientes | 5230 | 5230 |
| detalle_pedidos | 67320 | 67320 |
| pedidos | 28450 | 28450 |
| productos | 150 | 150 |
Los valores de table_rows en information_schema son aproximados para InnoDB, pero para una verificación rápida son suficientes. Si necesitas conteos exactos, ejecuta SELECT COUNT(*) en cada tabla.
Script automatizado de copia
Un script completo que copia una base de datos con verificación:
#!/bin/bash
# /scripts/copiar-base-datos.sh
ORIGEN=$1
DESTINO=$2
CONF="/root/.my.cnf"
if [ -z "$ORIGEN" ] || [ -z "$DESTINO" ]; then
echo "Uso: $0 <base_origen> <base_destino>"
exit 1
fi
echo "Copiando ${ORIGEN} -> ${DESTINO}..."
# Crear base de datos destino
mysql --defaults-file=$CONF -e "CREATE DATABASE IF NOT EXISTS \`${DESTINO}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
# Copiar
mysqldump --single-transaction --routines --triggers --events \
--defaults-file=$CONF "${ORIGEN}" | mysql --defaults-file=$CONF "${DESTINO}"
if [ $? -eq 0 ]; then
echo "Copia completada exitosamente."
# Verificar
TABLAS_ORIGEN=$(mysql --defaults-file=$CONF -sN -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${ORIGEN}'")
TABLAS_DESTINO=$(mysql --defaults-file=$CONF -sN -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${DESTINO}'")
echo "Tablas en ${ORIGEN}: ${TABLAS_ORIGEN}"
echo "Tablas en ${DESTINO}: ${TABLAS_DESTINO}"
else
echo "ERROR: La copia falló" >&2
exit 1
fichmod +x /scripts/copiar-base-datos.sh
/scripts/copiar-base-datos.sh tienda_mysql tienda_stagingCopiar bases de datos es una operación rutinaria en la administración de MySQL. Aunque no existe un comando nativo, la combinación de mysqldump y mysql es fiable, flexible y funciona tanto dentro del mismo servidor como entre servidores diferentes.
Escrito por Eduardo Lázaro
