用 mysqldump 來 Backup/Restore MySQL 的 DB data

今天收到客戶的要求要把 DB server 上的 MySQL data 做個定期備份,所以就順便實作一下~
首先,這裡的環境是:

兩台 DB server 上都有 MySQL Enterprise v2.0.56,
OS 都是 RedHat EL ES4U5,另外這兩台 DB server 上還有 Veritas 做 HA。
我們就不說廢話了,直接開始吧:

MySQL 備份資料庫主要有兩種方法,一種是用 Hard copy 的方法,也就是直接把 ~/mysql/data/[資料庫名稱]/* 通通備份下來,如果要到回去資料庫,資料庫版本要一樣喔,免得發生非預期的結果。不過這種方法備份還原時最好先把 mysqld 停下來。
要看 MySQL 是否執行中可用下面的指令 "mysqladmin status":
[root@KHXDBS1 ~]# /opt/mysql/enterprise/monitor/mysql/bin/mysqladmin status
/opt/mysql/enterprise/monitor/mysql/bin/mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)'
Check that mysqld is running and that the socket: '/tmp/mysql.sock' exists!
而要檢查剛剛所說的資料庫所在的位置,可以去查看一下 /etc/init.d/mysql 個檔案的內容,由於這裡的環境是兩台 DB server 後面接著一座 Storage,所以我把 datadir (資料庫路徑) 改到 /DB (由後端 Storage mount 過來)底下:
[root@KHXDBS1 ~]# grep "datadir=/" /etc/init.d/mysql
# datadir=/var/lib/mysql
datadir=/DB/var/lib/mysql
[root@KHXDBS1 ~]# cp -pR /DB/var/lib/mysql/AAA /DB/mysql/backup/.
其中 AAA 是這次要備份的的 schema 啦。

還有一種作法是用 mysqldump 將資料倒出來 *.sql,指令格式為:
mysqldump -h [Host] -u[DbUserName] -p[DbPassword] [DbName] > [filename].sql
簡單的例子:
mysqldump -h 127.0.0.1 -uroot -pOOXX AAA > /DB/mysql/backup/dbMysqlArchive_XXXX.sql
要做 Restore 時可以用下面的指令範例來倒:
mysql -h 127.0.0.1 -uroot -pOOXX AAA < /DB/mysql/backup/dbMysqlArchive_XXXX.sql
對了,Restore 之前要先確定 AAA 的 Schema 還存在喔~
下面是附上簡單寫的一個小 script 去每天晚上作個備份...給大家參考一下:
[root@KHXDBS1 ~]# crontab -l 10 2 * * * /bin/DB_archive.sh > /dev/null 2>&1
[root@KHXDBS1 ~]# cat /bin/DB_archive.sh
#!/bin/sh -vx
#
# DB server : Backup DB data
# Version: @01
#
INITIAL_DIR=/opt/logs
HOSTNAME=`hostname |cut -c -7`
LOG_APPENDIX=`date +"%Y-%m%d"`
LOCK_FILE=$INITIAL_DIR/.dbMysqlArchive_lock
LOG_FILE=$INITIAL_DIR/$HOSTNAME-dbMysqlArchive_$LOG_APPENDIX.log
ERR_COUNTER=0
FIX_COUNTER=0
MAIN_SEPERATOR="==============="
SEC_SEPERATOR="#---------------------------------------------------------------------------------------#"
NOW=`date +%Y-%m-%d-%H:%M:%S`
ARC_EXT=`date +%Y%m%d%H`
ARC_DIR=/DB/mysql/backup
ARC_FILE=$ARC_DIR/dbMysqlArchive_$ARC_EXT.sql

if [ ! -f "$LOCK_FILE" ]; then
touch $LOCK_FILE
else
echo $MAIN_SEPERATOR >> $LOG_FILE
echo $NOW >> $LOG_FILE
echo "$LOCK_FILE exist" >> $LOG_FILE
echo $MAIN_SEPERATOR >> $LOG_FILE
exit
fi

if [ `rsh khxdb hostname|cut -c -7|grep $HOSTNAME|wc -l` = 1 ]; then
/usr/bin/find $INITIAL_DIR -name "$HOSTNAME-dbMysqlArchive*.log" -mtime +8 -exec rm {} \;
/usr/bin/find $ARC_DIR -name "dbMysqlArchive_*.sql" -mtime +8 -exec rm {} \;

echo $SEC_SEPERATOR >> $LOG_FILE
echo "# DB server mysql data archive script starting #" >> $LOG_FILE
echo $SEC_SEPERATOR >> $LOG_FILE
#------------------------ Archive MySQL data ----------------------------------------------#
echo "Start to excute mysqldump command at $NOW ..." >> $LOG_FILE
echo "" >> $LOG_FILE
/opt/mysql/enterprise/monitor/mysql/bin/mysqldump -h 127.0.0.1 -uroot -pOOXX AAA > $ARC_FILE
if [ `ls -l $ARC_FILE| wc -l` = 1 ]; then
echo "$ARC_FILE created..." >> $LOG_FILE
else
echo "$ARC_FILE create fail, Please check it now..." >> $LOG_FILE
fi
rm -rf $LOCK_FILE
echo $SEC_SEPERATOR >> $LOG_FILE
echo "# DB server MySQL data archive script finished #" >> $LOG_FILE
echo $SEC_SEPERATOR >> $LOG_FILE
#------------------------------------------------------------------------------------------#
else
echo $NOW >> $LOG_FILE
echo "This server is NOT the active one !!!" >> $LOG_FILE
echo "Check script is stopping !!!" >> $LOG_FILE
echo $SEC_SEPERATOR >> $LOG_FILE
rm -rf $LOCK_FILE
fi
[root@KHXDBS1 ~]#
備份完會像下面所示的例子喔:
[root@KHXDBS1 ~]# ls -alrt /DB/mysql/backup/
total 168
drwxr-xr-x 3 root root 4096 Oct 14 15:25 ..
-rw-r--r-- 1 root root 77092 Oct 15 02:10 dbMysqlArchive_2008101502.sql
drwxr-xr-x 2 root root 4096 Oct 14 15:55 .

搞定!收工。
0 Responses