Ну есть 2 метода:
Метод 1: Хорошо известный метод для переименования схемы базы данных - выгрузка схемы с использованием Mysqldump и восстановление ее в другой схеме, а затем удаление старой схемы (если необходимо).
Из оболочки
mysqldump emp > emp.out
mysql -e "CREATE DATABASE employees;"
mysql employees < emp.out
mysql -e "DROP DATABASE emp;"
Хотя описанный выше метод прост, он требует много времени и пространства. Что делать, если схема больше 100 ГБ? Существуют методы, где вы можете объединить вышеперечисленные команды вместе, чтобы сэкономить место, однако это не сэкономит время.
Чтобы исправить такие ситуации, существует другой быстрый способ переименования схем, однако, при этом необходимо соблюдать осторожность.
Метод 2: MySQL имеет очень хорошую функцию для переименования таблиц, которая работает даже в разных схемах. Эта операция переименования является атомарной, и никто другой не может получить доступ к таблице во время ее переименования. Это займет короткое время, поскольку изменение имени таблицы или ее схемы - это только изменение метаданных. Вот процедурный подход к переименованию:
Создайте новую схему базы данных с нужным именем. Переименуйте таблицы из старой схемы в новую, используя команду MySQL «RENAME TABLE». Удалите старую схему базы данных.
If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too
, «RENAME TABLE» MySQL завершается ошибкой, если в таблицах существуют триггеры. Чтобы исправить это, мы можем сделать следующие вещи:
1) Dump the triggers, events and stored routines in a separate file.
Это делается с помощью флагов -E, -R (в дополнение к -t -d, который выводит триггеры) в команду mysqldump. После сброса триггеров нам нужно будет удалить их из схемы, чтобы команда RENAME TABLE работала.
$ mysqldump <old_schema_name> -d -t -R -E > stored_routines_triggers_events.out
2) Сформировать список только «БАЗОВЫХ» таблиц. Их можно найти с помощью запроса к information_schema.TABLES
таблице.
mysql> select TABLE_NAME from information_schema.tables where
table_schema='<old_schema_name>' and TABLE_TYPE='BASE TABLE';
3) Дамп представления в выходной файл. Представления могут быть найдены с помощью запроса к той же information_schema.TABLES
таблице.
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) Отбросьте триггеры на текущих таблицах в old_schema.
mysql> DROP TRIGGER <trigger_name>;
...
5) Восстановите вышеуказанные файлы дампа, как только все «базовые» таблицы, найденные на шаге №2, будут переименованы.
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
Сложности с вышеуказанными методами: нам может потребоваться обновить GRANTS для пользователей, чтобы они соответствовали правильному имени схемы. Они могут быть исправлены с помощью простого UPDATE для таблиц mysql.columns_priv, mysql.procs_priv, mysql.tables_priv, mysql.db, обновляющих имя old_schema до new_schema и вызывающих «Flush privileges;». Хотя «метод 2» кажется немного более сложным, чем «метод 1», он полностью подходит для сценариев. Простой скрипт bash для выполнения вышеуказанных шагов в правильной последовательности поможет сэкономить место и время при следующем переименовании схем базы данных.
Команда Percona Remote DBA написала сценарий «rename_db», который работает следующим образом:
[root@dba~]# /tmp/rename_db
rename_db <server> <database> <new_database>
Чтобы продемонстрировать использование этого скрипта, использовали образец схемы «emp», создали триггеры тестирования, сохранили подпрограммы в этой схеме. Попытается переименовать схему базы данных с помощью сценария, который занимает несколько секунд, в отличие от трудоемкого метода дампа / восстановления.
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 |
+--------------------+
Как видно из вышеприведенного вывода, схема базы данных «emp» была переименована в «emp_test» менее чем за секунду. Наконец, это скрипт из Percona, который используется выше для «метода 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