大家好:

现在分享一下最近的一个测试。

大家都知道,在mysql里面,没有提供重命名一个数据库的语句(其实在MySQL 5.1.7 to 5.1.23也有使用过rename database,但是因为很多的危险性,之后的版本就摒弃了这个功能),那么如何在mysql数据库中高效的重命名一个数据库呢?

1、使用mysqldump备份出数据库,之后删除原来的数据库,再dump文件中修改旧数据库名称为新的名称,再导入数据库,修改数据库中的相关用户权限(mysqldump的参数必须包含视图、触发器、函数、存储过程等,这里不再说明了)

1
 2

3

4

[root@percona ~]#  mysqldump emp > emp.out

[root@percona ~]#  mysql -e "CREATE DATABASE employees;"

[root@percona ~]#  mysql  employees < emp.out

[root@percona ~]#  mysql -e "DROP DATABASE emp;"

优点:操作比较简单,不易出错

弊端:在遇到数据库较大的时候,时间和磁盘空间都会有很高的要求

2、利用renametable的方式实现数据库重命名

主要操作步骤:

A)新建数据库:create database

B)重命名旧数据库中的表到新的数据库中,包含视图、触发器等:rename table

C)删除旧数据库

D)重授权相关用户的权限

因为操作较为复杂,先附上两个脚本,rename_db.sh完成数据库表、触发器、事件、函数、存储过程,rename_grants.sh完成相关用户的授权转换

脚本执行方法:

A)bash rename_db.sh  localhost  old_database_name  new_database_name

B)bash  rename_grants old_database_name  new_database_name


注:如果要使用的话,可以自己先测试一下,看看是否有问题,欢迎修改脚本和指正


看不见附件,贴出来了

1、rename_db.sh

#!/bin/bash

# Copyright 2013  zhujzhuo

. ~/.bash_profile  > /dev/null 2>&1


if [ $# -lt 3  ]; then

   echo "rename_db <server> <database> <new_database>"

   exit 1

fi


old_db_exists=`mysql -h $1  -e "show databases like '$2'" -sss `


if [ -z "$old_db_exists" ]; then

   echo "ERROR: Old database not  exists $2"

   exit 1

fi


db_exists=`mysql -h $1 -s -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 $0 $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


if [  -n $TRIGGERS  ];then

  for TRIGGER in $TRIGGERS ; do

      echo "drop trigger $TRIGGER"

      /usr/bin/mysql -h $1 $2 -e "drop trigger $TRIGGER"

  done

fi

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


2、rename_grants.sh

#!/bin/bash

DATE=`date +%Y%m%d`

if [  -f "/tmp/grants$DATE.sql" ];then

  rm -fr /tmp/grants$DATE.sql;

fi

for  i  in `mysql  -N -s -e "select concat(\"show grants for '\",user,\"'@'\",host,\"';\") from mysql.user"|grep -w 'show grants'| mysql   -N |grep -w 'GRANT'| sed 's/$/;/g'  | grep $1 | awk -F'TO' '{print $2}'`;do  mysql -N -s -e "show  grants for $i"|grep -w 'GRANT'| sed 's/$/;/g'  >> /tmp/grants$DATE.sql;done

if [ -f "/tmp/grants$DATE.sql" ];then

 sed -i "s/$1/$2/g" /tmp/grants$DATE.sql;

fi

for  i  in `mysql  -N -s -e "select concat(\"show grants for '\",user,\"'@'\",host,\"';\") from mysql.user"|grep -w 'show grants'| mysql   -N |grep -w 'GRANT'| sed 's/$/;/g'  | grep $1 | awk -F'TO' '{print $2}'`;do  mysql -N -s -e "drop user $i" ;done

mysql  <  /tmp/grants$DATE.sql