두 가지 방법이 있습니다.
방법 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