shell指令碼實現mysql資料庫表和表結構的對比
阿新 • • 發佈:2019-02-13
在專案維護和開發中,經常需要知道兩個資料庫之間有哪些差異,如兩個資料庫中資料表有什麼不同(表的名稱,數量),相同的表字段是否相同(欄位數目,約束,欄位型別,大小等),有各種資料庫管理工具可以實現這一點,但是別人的東西用起來總是沒有自己的順手(比如有的工具直接生成了修改的sql語句),鑑於此原因,決定自己寫個簡單的shell指令碼來實現這個功能。 思想:比較兩個庫A、B中資料表的不同,可以對兩個庫分別使用show tables指令,將表名形成兩個臨時檔案,然後遍歷其中一個臨時檔案的行,同時在另外一個臨時檔案中搜索該表名,如果找到說明兩個資料庫中都有這張表,同時將這個表名放入到新的臨時檔案,作為後面欄位對比的依據。欄位對比使用desc 表名(這裡的表名是上面挑選出來的相同的表名)的方式進行。下面通過程式碼來進行說明。
#!bin/sh
#資料庫A的屬性
DB1_NAME=test1
DB1_HOST=192.168.0.1
DB1_USER=root
DB1_PWD=test
#資料庫B的屬性
DB2_NAME=test2
DB2_HOST=192.168.0.2
DB2_USER=root
DB2_PWD=test
#資料庫比較結果的存放位置
DIFFERENT_TABLES_FILE=/home/different_tables.txt
DIFFERENT_COLUMNS_FILE=/home/different_columns.txt
TEMP_FILE_URL=/home/temp
SAME_RESULT_TEMP=${TEMP_FILE_URL} /same_result_temp.txt
#首先定義一個函式方便後面的比較
##############
# 引數1:臨時檔案1,作為比較的基準進行遍歷
# 引數2:臨時檔案2,在這個檔案裡邊搜尋檔案1中的表名
# 引數3:存放不同表名的結果檔案
# 引數4:存放相同表名的臨時檔案
##############
compareTables(){
i=2 #從第二行開始遍歷
while read line
do
row=$i
nameA=$(awk 'NR=='$row' {print $0}' $1) #從臨時檔案1中遍歷取出資料庫A的每一個表名
nameB=$(grep -w -i "$nameA" $2) #在臨時檔案2中搜索這個表名
if [ -z "$nameB" ]; then
echo "$nameA">>$3
else
if [ $nameA = $nameB ] ; then
if [ -f $4 ]; then
same_name=$(grep -w -i "$nameA" $4)
fi
if [ -z "$same_name" ]; then
echo "$nameA">>$4
fi
else
echo "$nameA">>$3
fi
fi
: $((i++))
done<$1
}
##開始比較兩個資料庫表的不同
echo "start...compare...tables"
#首先使用show tables獲得兩個庫中所有的表的名稱,放到臨時檔案
fileA=${TEMP_FILE_URL}/temp_dbA.txt
fileB=${TEMP_FILE_URL}/temp_dbB.txt
mysql -h${DB1_HOST} -u${DB1_USER} -p${DB1_PWD} -e"use ${DB1_NAME};show tables;">fileA
mysql -h${DB2_HOST} -u${DB2_USER} -p${DB2_PWD} -e"use ${DB2_NAME};show tables;">fileB
#呼叫函式進行對比
cd $TEMP_FILE_URL
rm -rf $SAME_RESULT_TEMP
echo "Those tables are unique in ${DB1_NAME}:">${DIFFERENT_TABLES_FILE}
compareTables $fileA $fileB $DIFFERENT_TABLES_FILE $SAME_RESULT_TEMP
echo "Those tables are unique in ${DB2_NAME}:">>${DIFFERENT_TABLES_FILE}
compareTables $fileB $fileA $DIFFERENT_TABLES_FILE $SAME_RESULT_TEMP
echo "compare...tables...end"
##開始比對兩個資料庫之間相同表名欄位之間的不同
echo "compare...column...start"
rm -rf ${DIFFERENT_COLUMNS_FILE}
compareColumns(){
while read line
do
table_line=$line
map_line=$(grep -w -i "$table_line" $2)
if [ -z "$map_line" ];then
echo "$table_line">>$3
fi
done<$1
}
#呼叫函式得出結果,此處需要遍歷剛開始得到的相同表名的檔案
while read line
do
table_name=$line
table_desc1=${TEMP_FILE_URL}/table_desc1.txt
table_desc2=${TEMP_FILE_URL}/table_desc2.txt
echo "the comparing table name is $table_name"
mysql -h${DB1_HOST} -u${DB1_USER} -p${DB1_PWD} -e"use ${DB1_NAME};desc ${table_name}">${table_desc1}
mysql -h${DB2_HOST} -u${DB2_USER} -p${DB2_PWD} -e"use ${DB2_NAME};desc ${table_name}">${table_desc2}
echo "different columns in ${DB1_NAME}.${table_name}">>${DIFFERENT_COLUMNS_FILE}
compareColumns ${table_desc1} ${table_desc2} ${DIFFERENT_COLUMNS_FILE}
echo "different columns in ${DB2_NAME}.${table_name}">>${DIFFERENT_COLUMNS_FILE}
compareColumns ${table_desc2} ${table_desc1} ${DIFFERENT_COLUMNS_FILE}
done<${SAME_RESULT_TEMP}
echo "compare...column...end"
##最後,清理臨時資料
cd ${TEMP_FILE_URL}
rm -rf *
至此,指令碼完成。