由於公司業務和應用的調整,之前在Mysql中的很多表都不需要了,故需要對數據庫進行整理。
剛開始,我在想:不就刪除一些表嗎?很好解決,寫個簡單的腳本就可以了。我先看了數據庫中有80000多個表,很多表都是以IP命名的,而這些表就是要清理的對象。
於是我使用下面一條命令,先將所有表名導出到一個文件中:
mysql -uroot -p123456 -A -e "use cdn;show tables;" >allDBName.txt
然後,執行:cat allDBName.txt|grep "^[0-9]\{1,3\}\.[0-9]\{1,3\}\.">ipDB.txt 將以IP開始的表名導入到ipDB.txt中。再使用如下腳本,進行刪除。
#! /bin/bash
cat ipDB.txt|while read DBname
do
mysql -uroot -p123456 -A -e "use cdn;DROP TABLE IF EXISTS $DBname;" 2>>drop.err
if [ $? -ne 0 ] ;then
echo "Drop $DBname failed"
fi
done
exit 0
我在後台執行了以上腳本,也沒看執行是否正確,個人感覺應該沒問題了,於是就做其它事情去了。可是,一段時間後,我在information_schema數據庫下,執行下列語句,查看數據庫大小時,發現與刪除表之前的數據庫大小不減,反而增加了(實際環境中,正在跑著業務)。
select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as datasize from TABLES where table_schema='cdn';
再看剛才腳本的目錄下,多了一個drop.err文件,發現裡面全是同一個錯誤:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''192.168.1.30'' at line 1
我很疑惑,為什麼會報錯呢?於是我在終端中進入到數據庫,執行:
DROP TABLE IF EXISTS ‘192.168.1.30’;
可是還是報相同的錯誤,我很是疑惑。WHY?根本就沒道理啊,沒有語法錯誤啊!後來仔細一想,感覺不對:表名裡面的點一概失算特殊字符,可能是這個問題。於是我查閱了一些資料,遇到這種問題的解決方法是:把表名放到``裡面,注意`是跟字母在一起的數字1的左邊的字符,試了一下,果然成功了。
於是,我將腳本中的 $DBname變成`$DBname`,但是中興的時候,居然又報錯了:command not found,仔細一想應該是雙引號的問題,於是將引號改成單引號,膽碼如下:
#! /bin/bash
cat ipDB.txt|while read DBname
do
mysql -uroot -p123456 -A -e 'use cdn;DROP TABLE IF EXISTS `$DBname`;' 2>>drop.err
if [ $? -ne 0 ] ;then
echo "Drop $DBname failed"
fi
done
exit 0
然後執行,沒有再報錯,問題應該解決了吧!可我一查看標的數量,居然還是沒有變化,天理何在啊!沒報錯了,但怎麼就沒將表刪除了。再仔細想想,原來是shell腳本中特殊字符的處理,改成以下就好了:
#! /bin/bash
cat ipDB.txt|while read DBname
do
mysql -uroot -p123456 -A -e "use cdn;DROP TABLE IF EXISTS \`$DBname\`;" 2>>drop.err
if [ $? -ne 0 ] ;then
echo "Drop $DBname failed"
fi
done
exit 0
此時,再次執行,沒報錯,再看看表的數量,果然變少了。居然被幾個符號搞了一天!唉!吸取點教訓吧!