두 가지 방법이 있습니다.
방법 1 : 데이터베이스 스키마 이름을 바꾸는 잘 알려진 방법은 Mysqldump를 사용하여 스키마를 덤프하고 다른 스키마에서 복원 한 다음 이전 스키마를 삭제하는 것입니다 (필요한 경우).
쉘에서
mysqldump emp > emp.out
mysql -e "CREATE DATABASE employees;"
mysql employees < emp.out
mysql -e "DROP DATABASE emp;"
위의 방법은 쉽지만 시간과 공간이 많이 소모됩니다. 스키마가 100GB를 초과하면 어떻게됩니까?공간을 절약하기 위해 위의 명령을 함께 파이프하는 방법이 있지만 시간을 절약 할 수는 없습니다.
이러한 상황을 해결하려면 스키마의 이름을 바꾸는 또 다른 빠른 방법이 있지만 수행하는 동안 일부주의를 기울여야합니다.
방법 2 : MySQL은 다른 스키마에서도 작동하는 테이블 이름을 바꾸는 데 매우 유용한 기능을 가지고 있습니다. 이 이름 바꾸기 작업은 원 자성이므로 이름을 바꾸는 동안 다른 사람은 테이블에 액세스 할 수 없습니다. 테이블 이름을 변경하거나 스키마는 메타 데이터 만 변경되므로 완료하는 데 시간이 약간 걸립니다. 다음은 이름 바꾸기를 수행하는 절차 적 접근 방식입니다.
원하는 이름으로 새 데이터베이스 스키마를 작성하십시오. MySQL의“RENAME TABLE”명령을 사용하여 이전 스키마에서 새 스키마로 테이블 이름을 바꿉니다. 이전 데이터베이스 스키마를 삭제하십시오.
If there are views, triggers, functions, stored procedures in the schema, those will need to be recreated too. 테이블에 트리거가 있으면 MySQL의“RENAME TABLE”이 실패합니다. 이를 해결하기 위해 다음과 같은 작업을 수행 할 수 있습니다.
1) Dump the triggers, events and stored routines in a separate file. 이것은 mysqldump 명령에 -E, -R 플래그 (트리거를 덤프하는 -t -d 외에)를 사용하여 수행되었습니다. 트리거가 덤프되면 RENAME TABLE 명령이 작동하기 위해 스키마에서 트리거를 삭제해야합니다.
$ mysqldump <old_schema_name> -d -t -R -E > stored_routines_triggers_events.out
2) “BASE”테이블의 목록 만 생성하십시오. 이들은 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
위의 방법으로 복잡한 사항 : 사용자가 올바른 schema_name과 일치하도록 GRANTS를 업데이트해야 할 수도 있습니다. 이것들은 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"의 이름이 1 초 이내에 "emp_test"로 바뀌 었습니다. 마지막으로, 이것은 "방법 2"에 사용되는 Percona의 스크립트입니다.
#!/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