Bem, existem 2 métodos:
Método 1: Um método conhecido para renomear o esquema do banco de dados é despejar o esquema usando o Mysqldump, restaurá-lo em outro esquema e, em seguida, descartar o esquema antigo (se necessário).
De Shell
mysqldump emp > emp.out
mysql -e "CREATE DATABASE employees;"
mysql employees < emp.out
mysql -e "DROP DATABASE emp;"
Embora o método acima seja fácil, consome tempo e espaço. E se o esquema tiver mais de 100 GB? Existem métodos em que você pode canalizar os comandos acima juntos para economizar espaço, mas isso não economizará tempo.
Para remediar essas situações, existe outro método rápido para renomear esquemas, no entanto, é preciso tomar alguns cuidados ao fazê-lo.
Método 2: O MySQL possui um recurso muito bom para renomear tabelas que até funciona em diferentes esquemas. Essa operação de renomeação é atômica e ninguém mais pode acessar a tabela enquanto ela está sendo renomeada. Isso demora um pouco para ser concluído, pois alterar o nome de uma tabela ou seu esquema é apenas uma alteração de metadados. Aqui está uma abordagem processual ao renomear:
Crie o novo esquema do banco de dados com o nome desejado. Renomeie as tabelas do esquema antigo para o novo esquema, usando o comando “RENAME TABLE” do MySQL. Solte o esquema antigo do banco de dados.
If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too
. “RENAME TABLE” do MySQL falhará se houver gatilhos nas tabelas. Para remediar isso, podemos fazer o seguinte:
1) Dump the triggers, events and stored routines in a separate file.
Isso foi feito usando os sinalizadores -E, -R (além de -t -d, que despeja os gatilhos) no comando mysqldump. Depois que os gatilhos forem despejados, precisaremos removê-los do esquema, para que o comando RENAME TABLE funcione.
$ mysqldump <old_schema_name> -d -t -R -E > stored_routines_triggers_events.out
2) Gere uma lista apenas das tabelas "BASE". Estes podem ser encontrados usando uma consulta na information_schema.TABLES
tabela.
mysql> select TABLE_NAME from information_schema.tables where
table_schema='<old_schema_name>' and TABLE_TYPE='BASE TABLE';
3) Despejar as visualizações em um arquivo de saída. As visualizações podem ser encontradas usando uma consulta na mesma information_schema.TABLES
tabela.
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) Solte os gatilhos nas tabelas atuais no old_schema.
mysql> DROP TRIGGER <trigger_name>;
...
5) Restaure os arquivos de despejo acima depois que todas as tabelas "Base" encontradas na etapa 2 forem renomeadas.
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
Complexidades com os métodos acima: Talvez seja necessário atualizar os GRANTS para os usuários para que eles correspondam ao schema_name correto. Isso poderia ser corrigido com uma simples atualização de tabelas mysql.columns_priv, mysql.procs_priv, mysql.tables_priv, mysql.db, atualizando o nome old_schema para new_schema e chamando “Flush privilégios;”. Embora o "método 2" pareça um pouco mais complicado que o "método 1", isso é totalmente programável. Um script simples do bash para executar as etapas acima na sequência correta pode ajudar a economizar espaço e tempo e renomear os esquemas do banco de dados da próxima vez.
A equipe do DBA remoto da Percona escreveu um script chamado "rename_db" que funciona da seguinte maneira:
[root@dba~]# /tmp/rename_db
rename_db <server> <database> <new_database>
Para demonstrar o uso desse script, usou um esquema de exemplo "emp", criou gatilhos de teste, rotinas armazenadas nesse esquema. Tentará renomear o esquema do banco de dados usando o script, que leva alguns segundos para ser concluído, em vez do método de despejo / restauração demorado.
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 você pode ver na saída acima, o esquema do banco de dados "emp" foi renomeado para "emp_test" em menos de um segundo. Por fim, este é o script da Percona usado acima para o "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