如何高效的重命名mysql 數據庫名稱

大家好:

現在分享一下最近的一個測試。

大家都知道,在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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章