Есть 2 метода:
Метод 1. Хорошо известным методом переименования схемы базы данных является сброс схемы с помощью Mysqldump и ее восстановление в другой схеме, а затем удаление старой схемы (при необходимости).
Из Shell
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
. 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
Сложности с вышеуказанными методами: нам может потребоваться обновить ГРАНТЫ для пользователей, чтобы они соответствовали правильному имени схемы. Их можно было исправить простым ОБНОВЛЕНИЕМ таблиц mysql.columns_priv, mysql.procs_priv, mysql.tables_priv, mysql.db, обновив имя old_schema до new_schema и вызвав «Сбросить привилегии;». Хотя «метод 2» кажется немного более сложным, чем «метод 1», он полностью поддерживает сценарии. Простой сценарий bash для выполнения вышеуказанных шагов в правильной последовательности может помочь вам сэкономить место и время при переименовании схем базы данных в следующий раз.
Команда администраторов баз данных Percona Remote написала сценарий под названием «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
person
Community
schedule
29.01.2014
RENAME DATABASE
оператор, который не несет в себе никаких опасностей, поскольку в настоящее время нет простого способа выполнить эту задачу. Нет очевидной причины, почему это было опасно в документацию, чтобы у них была возможность сделать замену. По крайней мере, люди размещали на своих веб-сайтах ошибки, связанные с запросами функций. Например, bugs.mysql.com/bug.php?id=58593. и bugs.mysql.com/bug.php?id=1698. - person Edward   schedule 15.04.2016