Bueno, hay 2 métodos:
Método 1: Un método bien conocido para renombrar el esquema de la base de datos es volcar el esquema usando Mysqldump y restaurarlo en otro esquema, y luego descartar el esquema anterior (si es necesario).
De Shell
mysqldump emp > emp.out
mysql -e "CREATE DATABASE employees;"
mysql employees < emp.out
mysql -e "DROP DATABASE emp;"
Aunque el método anterior es fácil, requiere mucho tiempo y espacio. ¿Qué pasa si el esquema es más de 100 GB? Existen métodos en los que puede canalizar los comandos anteriores para ahorrar espacio, sin embargo, no ahorrará tiempo.
Para remediar tales situaciones, hay otro método rápido para cambiar el nombre de los esquemas, sin embargo, se debe tener cuidado al hacerlo.
Método 2: MySQL tiene una muy buena característica para renombrar tablas que incluso funciona en diferentes esquemas. Esta operación de cambio de nombre es atómica y nadie más puede acceder a la tabla mientras se renombra. Esto lleva poco tiempo en completarse ya que cambiar el nombre de una tabla o su esquema es solo un cambio de metadatos. Aquí hay un enfoque de procedimiento para cambiar el nombre:
Cree el nuevo esquema de base de datos con el nombre deseado. Cambie el nombre de las tablas del antiguo esquema al nuevo esquema, utilizando el comando "RENAME TABLE" de MySQL. Descarte el antiguo esquema de la base de datos.
If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too
. La "RENAME TABLE" de MySQL falla si existen desencadenantes en las tablas. Para remediar esto, podemos hacer lo siguiente:
1) Dump the triggers, events and stored routines in a separate file.
Esto se hace usando los indicadores -E, -R (además de -t -d que vuelca los disparadores) al comando mysqldump. Una vez que se descartan los desencadenantes, tendremos que eliminarlos del esquema para que funcione el comando RENAME TABLE.
$ mysqldump <old_schema_name> -d -t -R -E > stored_routines_triggers_events.out
2) Genere una lista de solo tablas "BASE". Estos se pueden encontrar utilizando una consulta en la information_schema.TABLES
tabla.
mysql> select TABLE_NAME from information_schema.tables where
table_schema='<old_schema_name>' and TABLE_TYPE='BASE TABLE';
3) Volcar las vistas en un archivo de salida. Las vistas se pueden encontrar usando una consulta en la misma information_schema.TABLES
tabla.
mysql> select TABLE_NAME from information_schema.tables where
table_schema='<old_schema_name>' and TABLE_TYPE='VIEW';
$ mysqldump <database> <view1> <view2> … > views.out
4) Suelta los disparadores en las tablas actuales en old_schema.
mysql> DROP TRIGGER <trigger_name>;
...
5) Restaure los archivos de volcado anteriores una vez que todas las tablas "Base" encontradas en el paso # 2 cambien de nombre.
mysql> RENAME TABLE <old_schema>.table_name TO <new_schema>.table_name;
...
$ mysql <new_schema> < views.out
$ mysql <new_schema> < stored_routines_triggers_events.out
Complejos con los métodos anteriores: es posible que debamos actualizar las SUBVENCIONES para los usuarios de modo que coincidan con el nombre_esquema correcto. Esto podría solucionarse con una simple ACTUALIZACIÓN en las tablas mysql.columns_priv, mysql.procs_priv, mysql.tables_priv, mysql.db actualizando el nombre old_schema a new_schema y llamando a "Flush privileges;". Aunque el "método 2" parece un poco más complicado que el "método 1", esto es totalmente programable. Una secuencia de comandos bash simple para llevar a cabo los pasos anteriores en la secuencia adecuada puede ayudarlo a ahorrar espacio y tiempo mientras renombra los esquemas de la base de datos la próxima vez.
El equipo de Percona Remote DBA ha escrito un script llamado "rename_db" que funciona de la siguiente manera:
[root@dba~]# /tmp/rename_db
rename_db <server> <database> <new_database>
Para demostrar el uso de este script, usé un esquema de muestra "emp", creó disparadores de prueba, almacenó rutinas en ese esquema. Intentará cambiar el nombre del esquema de la base de datos utilizando el script, que tarda unos segundos en completarse en lugar del método de volcado / restauración que consume mucho tiempo.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| emp |
| mysql |
| performance_schema |
| test |
+--------------------+
[root@dba ~]# time /tmp/rename_db localhost emp emp_test
create database emp_test DEFAULT CHARACTER SET latin1
drop trigger salary_trigger
rename table emp.__emp_new to emp_test.__emp_new
rename table emp._emp_new to emp_test._emp_new
rename table emp.departments to emp_test.departments
rename table emp.dept to emp_test.dept
rename table emp.dept_emp to emp_test.dept_emp
rename table emp.dept_manager to emp_test.dept_manager
rename table emp.emp to emp_test.emp
rename table emp.employees to emp_test.employees
rename table emp.salaries_temp to emp_test.salaries_temp
rename table emp.titles to emp_test.titles
loading views
loading triggers, routines and events
Dropping database emp
real 0m0.643s
user 0m0.053s
sys 0m0.131s
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| emp_test |
| mysql |
| performance_schema |
| test |
+--------------------+
Como puede ver en el resultado anterior, el esquema de la base de datos "emp" fue renombrado como "emp_test" en menos de un segundo. Por último, este es el script de Percona que se usa arriba para el "método 2".
#!/bin/bash
# Copyright 2013 Percona LLC and/or its affiliates
set -e
if [ -z "$3" ]; then
echo "rename_db <server> <database> <new_database>"
exit 1
fi
db_exists=`mysql -h $1 -e "show databases like '$3'" -sss`
if [ -n "$db_exists" ]; then
echo "ERROR: New database already exists $3"
exit 1
fi
TIMESTAMP=`date +%s`
character_set=`mysql -h $1 -e "show create database $2\G" -sss | grep ^Create | awk -F'CHARACTER SET ' '{print $2}' | awk '{print $1}'`
TABLES=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='BASE TABLE'" -sss`
STATUS=$?
if [ "$STATUS" != 0 ] || [ -z "$TABLES" ]; then
echo "Error retrieving tables from $2"
exit 1
fi
echo "create database $3 DEFAULT CHARACTER SET $character_set"
mysql -h $1 -e "create database $3 DEFAULT CHARACTER SET $character_set"
TRIGGERS=`mysql -h $1 $2 -e "show triggers\G" | grep Trigger: | awk '{print $2}'`
VIEWS=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='VIEW'" -sss`
if [ -n "$VIEWS" ]; then
mysqldump -h $1 $2 $VIEWS > /tmp/${2}_views${TIMESTAMP}.dump
fi
mysqldump -h $1 $2 -d -t -R -E > /tmp/${2}_triggers${TIMESTAMP}.dump
for TRIGGER in $TRIGGERS; do
echo "drop trigger $TRIGGER"
mysql -h $1 $2 -e "drop trigger $TRIGGER"
done
for TABLE in $TABLES; do
echo "rename table $2.$TABLE to $3.$TABLE"
mysql -h $1 $2 -e "SET FOREIGN_KEY_CHECKS=0; rename table $2.$TABLE to $3.$TABLE"
done
if [ -n "$VIEWS" ]; then
echo "loading views"
mysql -h $1 $3 < /tmp/${2}_views${TIMESTAMP}.dump
fi
echo "loading triggers, routines and events"
mysql -h $1 $3 < /tmp/${2}_triggers${TIMESTAMP}.dump
TABLES=`mysql -h $1 -e "select TABLE_NAME from information_schema.tables where table_schema='$2' and TABLE_TYPE='BASE TABLE'" -sss`
if [ -z "$TABLES" ]; then
echo "Dropping database $2"
mysql -h $1 $2 -e "drop database $2"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.columns_priv where db='$2'" -sss` -gt 0 ]; then
COLUMNS_PRIV=" UPDATE mysql.columns_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.procs_priv where db='$2'" -sss` -gt 0 ]; then
PROCS_PRIV=" UPDATE mysql.procs_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.tables_priv where db='$2'" -sss` -gt 0 ]; then
TABLES_PRIV=" UPDATE mysql.tables_priv set db='$3' WHERE db='$2';"
fi
if [ `mysql -h $1 -e "select count(*) from mysql.db where db='$2'" -sss` -gt 0 ]; then
DB_PRIV=" UPDATE mysql.db set db='$3' WHERE db='$2';"
fi
if [ -n "$COLUMNS_PRIV" ] || [ -n "$PROCS_PRIV" ] || [ -n "$TABLES_PRIV" ] || [ -n "$DB_PRIV" ]; then
echo "IF YOU WANT TO RENAME the GRANTS YOU NEED TO RUN ALL OUTPUT BELOW:"
if [ -n "$COLUMNS_PRIV" ]; then echo "$COLUMNS_PRIV"; fi
if [ -n "$PROCS_PRIV" ]; then echo "$PROCS_PRIV"; fi
if [ -n "$TABLES_PRIV" ]; then echo "$TABLES_PRIV"; fi
if [ -n "$DB_PRIV" ]; then echo "$DB_PRIV"; fi
echo " flush privileges;"
fi