mysql rename database 脚本

1. 脚本输出背景

   因为mysql 没有提供原生的 rename database (其实在5.1.7时引入了该命令,但是因为一些问题在5.1.23又废弃了)。所以如果我们想对数据库重命名的话,可能大多数人都会想到 使用 mysqldump 导出然后重新导入,但是数据库越大,这个过程耗时就越长。为了能快速的完成 rename database 就有了下面的脚本。

NOTE: 后续脚本如果有变更,会及时上传,如果脚本使用中出现问题,可以给我留言(留下联系方式)。

 

2. 脚本使用注意事项

# 该脚本很简单,只需提供 5 个参数(必须是5个参数)

Usage: ./rename_database.sh
For example: ./rename_database.sh user password 127.0.0.1 databasename_old database_new

NOTE: 为了安全起见,脚本中注释掉了自动删除 databasename_old 库的代码

3. rename database 脚本

#!/bin/bash
##Script function
# The script is used to rename database of mysql. The script has been tested in the version 5.6 and 5.7 of mysql.

##Script instructions 
start=`date +%s`
TIMESTAMP=`date +%s`
set -e
if [ "$1"x = "--help"x ]; then
    echo -e "\n-----------------------------------------------------------------------------------------"
    echo "Usage: $0     "
		echo "For example: $0 user password 127.0.0.1 databasename_old database_new"
		echo "Please try again"
		echo -e "-----------------------------------------------------------------------------------------\n"
		exit 1
    
elif [ $# -ne 5 ]; then
    echo -e "\n-----------------------------------------------------------------------------------------"
		echo "Usage: $0     "
		echo "For example: $0 user password 127.0.0.1 databasename_old database_new"
		echo "Please try again"
		echo -e "-----------------------------------------------------------------------------------------\n"
		exit 1
fi



##set password for mysql login
export MYSQL_PWD=$2

##Check whether the new database is exist
db_exists=`mysql -u $1 -h $3 -e "show databases like '$5'" -sss`
if [ -n "$db_exists" ]; then
    echo "ERROR: New database $5 already exists"
    exit 1
fi

##Check the character set of the old database
character_set=`mysql -u $1 -h $3 -e "show create database $4\G" -sss| grep ^Create | awk -F'CHARACTER SET ' '{print $2}' | awk '{print $1}'`

##Calculate the number of tables(BASE TABLE),triggers,procedures,functions,views in the old database 
echo -e "\n-----------------------------------------------------------------------------------------"
echo "Calculate the number of tables(BASE TABLE),triggers,procedures,functions,views in the old database:"
echo -e "-----------------------------------------------------------------------------------------\n"

TABLES_OLD=`mysql -u $1 -h $3 -e "select count(1) from information_schema.tables where table_schema='$4' and TABLE_TYPE='BASE TABLE'" -sss`
echo "There are $TABLES_OLD BASE TABLES in $4"

VIEWS_OLD=`mysql -u $1 -h $3 -e "select count(1) from information_schema.views where TABLE_SCHEMA='$4'" -sss`
echo "There are $VIEWS_OLD VIEWS in $4"

TRIGGERS_OLD=`mysql -u $1 -h $3 -e "select count(1) from information_schema.triggers where TRIGGER_SCHEMA='$4'" -sss`
echo "There are $TRIGGERS_OLD TRIGGERS in $4"

PROCEDURES_OLD=`mysql -u $1 -h $3 -e "select count(1) from mysql.proc where type='PROCEDURE' and db='$4'" -sss`
echo "There are $PROCEDURES_OLD PROCEDURES in $4"

FUNCTIONS_OLD=`mysql -u $1 -h $3 -e "select count(1) from mysql.proc where type='FUNCTION' and db='$4'" -sss`
echo "There are $FUNCTIONS_OLD FUNCTIONS in $4"
echo -e "-----------------------------------------------------------------------------------------\n"


##Check if you can get table information from the old database 
TABLES=`mysql -u $1 -h $3 -e "select TABLE_NAME from information_schema.tables where table_schema='$4' and TABLE_TYPE='BASE TABLE'" -sss`
STATUS=$?
if [ "$STATUS" != 0 ] || [ -z "$TABLES" ]; then
    echo "Error retrieving tables from $4"
    exit 1
fi

##Create new database
echo -e "\n-----------------------------------------------------------------------------------------"
echo "create database $5 DEFAULT CHARACTER SET $character_set"
echo -e "-----------------------------------------------------------------------------------------\n"
mysql -u $1 -h $3 -e "create database $5 DEFAULT CHARACTER SET $character_set"


##Dump the view definition in old database if exist
VIEWS=`mysql -u $1 -h $3 -e "select TABLE_NAME from information_schema.tables where table_schema='$4' and TABLE_TYPE='VIEW'" -sss`
if [ -n "$VIEWS" ]; then
    echo -e "\n-----------------------------------------------------------------------------------------"
    mysqldump -u $1 -h $3 $4 --set-gtid-purged=OFF $VIEWS > /tmp/${4}_views${TIMESTAMP}.dump
    if [ $? = 0 ]; then
        echo "Dump the view successful in /tmp/${4}_views${TIMESTAMP}.dump"
    else
        echo "Error: !!! Dump view failed"
    
    fi
    echo -e "-----------------------------------------------------------------------------------------\n"
fi


##Dump triggers in old database and drop triggers in old database if exist
## We must drop the triggers on the table of old database,else execute "rename table" command on the table with trigger we will encounter the below error
##ERROR 1435 (HY000): Trigger in wrong schema
#TRIGGERS=`mysql -u $1 -h $3 $4 -e "show triggers\G"| grep Trigger: | awk '{print $2}' `
TRIGGERS=`mysql -u $1 -h $3 $4 -e "select TRIGGER_NAME from information_schema.triggers where TRIGGER_SCHEMA='$4'\G"| grep TRIGGER_NAME: | awk '{print $2}' `
if [ -n "$TRIGGERS" ]; then
		echo -e "\n-----------------------------------------------------------------------------------------"
		echo -e "Dump and Drop triggers "
		echo -e "-----------------------------------------------------------------------------------------"
		#mysqldump -u $1 -h $3 $4 -d -t -R -E > /tmp/${4}_trig_pro_fun${TIMESTAMP}.dump
		for TRIGGER in $TRIGGERS; do
				mysql -u $1 -h $3 $4 -e "show create trigger $TRIGGER\G" >> /tmp/${4}_triggers${TIMESTAMP}.dump
				if [ $? = 0 ]; then
    		    echo "drop trigger $TRIGGER"
    		    mysql -u $1 -h $3 $4 -e "drop trigger $TRIGGER"
    		else
    		    echo -e "Error: !!!Dump the $TRIGGER failed, the script is terminated"
    		    exit 1
    		fi
		done
		echo -e "\nDump the TRIGGER successful in /tmp/${4}_trig_pro_fun${TIMESTAMP}.dump"
		
		sed -i '/Trigger/d'                    /tmp/${4}_triggers${TIMESTAMP}.dump 
		sed -i '/sql_mode/d'                   /tmp/${4}_triggers${TIMESTAMP}.dump 
		sed -i '/character_set_client/d'       /tmp/${4}_triggers${TIMESTAMP}.dump 
		sed -i '/collation_connection/d'       /tmp/${4}_triggers${TIMESTAMP}.dump 
		sed -i '/Database Collation/d'         /tmp/${4}_triggers${TIMESTAMP}.dump 
		sed -i '/row in set/d'                 /tmp/${4}_triggers${TIMESTAMP}.dump 
		sed -i '/ERROR:/d'                     /tmp/${4}_triggers${TIMESTAMP}.dump 
		sed -i '/No query specified/d'         /tmp/${4}_triggers${TIMESTAMP}.dump 
		sed -i '/\*/d'                         /tmp/${4}_triggers${TIMESTAMP}.dump
		sed -i 's/SQL Original Statement://g'  /tmp/${4}_triggers${TIMESTAMP}.dump 
		sed -i '1i\delimiter @@'               /tmp/${4}_triggers${TIMESTAMP}.dump
		sed -i 's/end/end @@/ig'               /tmp/${4}_triggers${TIMESTAMP}.dump
		
fi

##Dump function,procedure,event in old database if exist
echo -e "-----------------------------------------------------------------------------------------\n"
if [ $PROCEDURES_OLD -gt 0 -o $FUNCTIONS_OLD -gt 0 ]; then
		echo -e "\n-----------------------------------------------------------------------------------------"
		echo -e "Dump function and procedure in $4 "
		echo -e "-----------------------------------------------------------------------------------------"
		mysqldump -u $1 -h $3 $4 -d -t -R -E --set-gtid-purged=OFF --skip-triggers > /tmp/${4}_pro_fun${TIMESTAMP}.dump
		if [ $? = 0 ]; then
		    echo -e "Dump the Function and Procedure successful in /tmp/${4}_pro_fun${TIMESTAMP}.dump"
		else
		    echo -e "Error: !!!Function and Procedure dump failed, requiring manual intervention"
		fi
fi

##Rename table name 
echo -e "\n\n-----------------------------------------------------------------------------------------"
echo "Begin rename tables ......"
echo -e "-----------------------------------------------------------------------------------------"
for TABLE in $TABLES; do
    echo "rename table $4.$TABLE to $5.$TABLE"
    mysql -u $1 -h $3 $4 -e "SET FOREIGN_KEY_CHECKS=0; rename table $4.$TABLE to $5.$TABLE"
    if [ $? != 0 ]; then
        echo "Error: !!!$4.$TABLE rename to $5.$TABLE failed"
        echo "Error: !!!Only part of the tables in $4 have been renamed successfully, requiring manual intervention (note the trigger)"
        exit 1
    fi
done
echo -e "-----------------------------------------------------------------------------------------\n"

##Load views to new database
if [ -n "$VIEWS" ]; then
    echo -e "\n-----------------------------------------------------------------------------------------"
    echo -e "Begin loading views to new database $5......"
    mysql -u $1 -h $3 $5 < /tmp/${4}_views${TIMESTAMP}.dump
    if [ $? = 0 ]; then
        echo -e "Load views to new database $5 successful"
    else
        echo -e "Error: !!!load views to $5 failed, requiring manual intervention"
    fi
    echo -e "-----------------------------------------------------------------------------------------\n"
fi


##Load triggers,procedures,functions to new database
if [ $PROCEDURES_OLD -gt 0 -o $FUNCTIONS_OLD -gt 0 ]; then
    echo -e "\n-----------------------------------------------------------------------------------------"
    echo "Begin loading routines and events to new database $5......"
    mysql -u $1 -h $3 $5 < /tmp/${4}_pro_fun${TIMESTAMP}.dump
    if [ $? = 0 ]; then
        echo -e "Load routines and events to new database $5 successful"
    else
        echo -e "Error: !!!load routines and events to $5 failed, requiring manual intervention"
    fi
    echo -e "-----------------------------------------------------------------------------------------\n"
fi

if [ -n "$TRIGGERS" ]; then
    echo -e "\n-----------------------------------------------------------------------------------------"
    echo "Begin loading triggers to new database $5 ......"
    mysql -u $1 -h $3 $5 < /tmp/${4}_triggers${TIMESTAMP}.dump
    if [ $? = 0 ]; then
        echo -e "Load triggers to new database $5 successful"
    else
        echo -e "Error: !!!load triggers to $5 failed, requiring manual intervention"
    fi
        
    echo -e "-----------------------------------------------------------------------------------------\n"
fi




##Check whether the number of table,view,triggers,procedures,functions in old database and new database is consistent.
echo -e "\n-----------------------------------------------------------------------------------------"
echo -e "Check whether the number of table,view,triggers,procedures,functions in old database and new database is consistent."

TABLES_NEW=`mysql -u $1 -h $3 -e "select count(1) from information_schema.tables where table_schema='$5' and TABLE_TYPE='BASE TABLE'" -sss `
if [ $TABLES_OLD -ne $TABLES_NEW ]; then		
		echo -e "WARNING: The number of tables in database $4 and database $5 is not equal, please review!!!\n\n"	 
fi

VIEWS_NEW=`mysql -u $1 -h $3 -e "select count(1) from information_schema.views where TABLE_SCHEMA='$5'" -sss`
if [ $VIEWS_OLD -ne $VIEWS_NEW ]; then
		echo "WARNING: The number of views in database $4 and database $5 is not equal, please review!!!\n\n"	 
fi


TRIGGERS_NEW=`mysql -u $1 -h $3 -e "select count(1) from information_schema.triggers where TRIGGER_SCHEMA='$5'" -sss`
if [ $TRIGGERS_OLD -ne $TRIGGERS_NEW ]; then
		echo "WARNING: The number of triggers in database $4 and database $5 is not equal, please review!!!\n\n" 
fi

PROCEDURES_NEW=`mysql -u $1 -h $3 -e "select count(1) from mysql.proc where type='PROCEDURE' and db='$5'" -sss`
if [ $PROCEDURES_OLD -ne $PROCEDURES_NEW ]; then
		echo "WARNING: The number of triggers in database $4 and database $5 is not equal, please review!!!\n\n" 
fi

FUNCTIONS_NEW=`mysql -u $1 -h $3 -e "select count(1) from mysql.proc where type='FUNCTION' and db='$5'" -sss`
if [ $FUNCTIONS_OLD -ne $FUNCTIONS_NEW ]; then
		echo "WARNING: The number of functions in database $4 and database $5 is not equal, please review!!!\n\n"
fi
echo -e "-----------------------------------------------------------------------------------------\n"	

##Drop the old database
#TABLES=`mysql -u $1 -h $3 -e "select TABLE_NAME from information_schema.tables where table_schema='$4' and TABLE_TYPE='BASE TABLE'" -sss`
#if [ -z "$TABLES" ]; then
#		echo -e "\n-----------------------------------------------------------------------------------------"
#    echo "Dropping database $4"
#    mysql -u $1 -p$2 -h $3 $4 -e "drop database $4" 2>/dev/null
#    echo -e "-----------------------------------------------------------------------------------------\n"
#fi

##Process the privileges for new database
if [ `mysql -u $1 -p$2 -h $3 -e "select count(*) from mysql.columns_priv where db='$4'" -sss 2>/dev/null` -gt 0 ]; then
    COLUMNS_PRIV="    UPDATE mysql.columns_priv set db='$5' WHERE db='$4';"
fi
if [ `mysql -u $1 -p$2 -h $3 -e "select count(*) from mysql.procs_priv where db='$4'" -sss 2>/dev/null` -gt 0 ]; then
    PROCS_PRIV="    UPDATE mysql.procs_priv set db='$5' WHERE db='$4';"
fi
if [ `mysql -u $1 -p$2 -h $3 -e "select count(*) from mysql.tables_priv where db='$4'" -sss 2>/dev/null` -gt 0 ]; then
    TABLES_PRIV="    UPDATE mysql.tables_priv set db='$5' WHERE db='$4';"
fi
if [ `mysql -u $1 -p$2 -h $3 -e "select count(*) from mysql.db where db='$4'" -sss 2>/dev/null` -gt 0 ]; then
    DB_PRIV="    UPDATE mysql.db set db='$5' WHERE db='$4';"
fi
if [ -n "$COLUMNS_PRIV" ] || [ -n "$PROCS_PRIV" ] || [ -n "$TABLES_PRIV" ] || [ -n "$DB_PRIV" ]; then
		echo -e "\n-----------------------------------------------------------------------------------------"
    echo "IF you want to change the privileges to new database you need to run all output below:"
    echo -e "-----------------------------------------------------------------------------------------"
    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;"
    echo -e "-----------------------------------------------------------------------------------------"
fi

##Compute the time elapsed of the shell
finished=`date +%s`
echo -e "\n-----------------------------------------------------------------------------------------"
echo -e "The operation of rename database $4 to $5 completed"
elapsed_time=$(($finished - $start))
echo -e "It took $elapsed_time s to rename the database $4"
echo -e "-----------------------------------------------------------------------------------------\n"

 

你可能感兴趣的:(Mysql)