1. 程式人生 > >Linux上自動備份MySQL

Linux上自動備份MySQL

在資料庫表丟失或損壞的情況下,備份你的資料庫是很重要的。如果發生系統崩潰,你肯定想能夠將你的表儘可能丟失最少的資料恢復到崩潰發生時的狀態。本文主要對MyISAM表做備份恢復。

備份策略一:直接拷貝資料庫檔案

備份策略二:使用mysqldump備份資料庫(一個星期全備一次,每天增量備份)

一、 直接拷貝資料檔案

直接拷貝資料檔案最為直接、快速、方便,但缺點是基本上不能實現增量備份。為了保證資料的一致性,需要在備份檔案前,執行以下 SQL 語句:FLUSH TABLES WITH READ LOCK;也就是把記憶體中的資料都重新整理到磁碟中,同時鎖定資料表,以保證拷貝過程中不會有新的資料寫入。這種方法備份出來的資料恢復也很簡單,直接拷貝回原來的資料庫目錄下即可。

   為了方便的拷貝出資料檔案,我寫了一個指令碼讓其每天執行一次做備份。在/目錄下建一個目錄用來放置指令碼檔案,

#mkdir /scripts

建立一個備份資料庫的一個指令碼檔案

#vi backup_mysql.sh

#!/bin/bash

backup_dir=/backup/databak   #備份檔案放置目錄

backup_target_dir=/backup/db

backup_logs_dir=/backup/logs   #備份日誌目錄

db=bcmedia

DATE=$(date +%Y%m%d)

#得到10天前的日期

ccDATE=$(date "-d 10 day ago" +%Y%m%d)

echo "開始複製資料表"  >> $backup_logs_dir/$db$DATE

echo "-----------`date +"%Y-%m-%d %H:%M:%S"`--------------------"  >> $backup_logs_dir/$db$DATE

cp -R /data/$db $backup_target_dir/   #mysql資料庫的資料目錄為/data

echo "開始壓縮資料表"  >> $backup_logs_dir/$db$DATE

echo "------------------------"  >> $backup_logs_dir/$db$DATE

cd $backup_target_dir

tar -zcvf  $backup_dir/db$DATE.tar.gz $db/ >> $backup_logs_dir/$db$DATE

if [ $? -eq 0 ]

then

 echo "backup succeed" >> $backup_logs_dir/$db$DATE

else

 echo "backup fail" >> $backup_logs_dir/$db$DATE

fi

echo "開始刪除原資料表"  >> $backup_logs_dir/$db$DATE

echo "-----------------------"  >> $backup_logs_dir/$db$DATE

rm -rf $backup_target_dir/* && echo “刪除原資料表” >> $backup_logs_dir/$db$DATE

echo  "刪除10天前資料" >>$backup_logs_dir/$db$DATE

if [ -e $backup_dir/db$ccDATE.tar.gz ]

then

 rm -rf $backup_dir/db$ccDATE.tar.gz

 echo "Delete $backup_dir/db$ccDATE.tar.gz succeed" >>$backup_logs_dir/$db$DATE

else

 echo "Not found $backup_dir/db$ccDATE.tar.gz file" >>$backup_logs_dir/$db$DATE

fi

if [ -e $backup_logs_dir/$db$ccDATE ]

then

 rm -rf $backup_logs_dir/$db$ccDATE

 echo "Delete $backup_logs_dir/$db$ccDATE succeed" >>$backup_logs_dir/$db$DATE

else

 echo "Not found $backup_logs_dir/$db$ccDATE file" >>$backup_logs_dir/$db$DATE

fi

儲存退出並新增可執行的許可權

#chmod 755 backup_mysql.sh

讓指令碼每天執行一次,每天備份一次資料庫,在crontab 裡面新增一行

Crontab –e

10 4 * * * /scripts/ backup_mysql.sh  #每天4點10分執行指令碼備份資料庫

      還原資料庫的時候只要把備份出的檔案拷貝到資料庫放置資料的目錄下,修改許可權。重啟下資料庫就完成了恢復了。

二、 使用mysqldump備份資料庫

          mysqldump 是採用SQL級別的備份機制,它將資料表導成 SQL 指令碼檔案,在不同的 MySQL 版本之間升級時相對比較合適,這也是最常用的備份方法。關於mysqldump的更詳細解釋用/MysqlDir/bin/mysqldump –help 來檢視詳細的解釋。

      我們使用的資料庫備份完成之後有10個G如果每天都做一次全備,不方便,就一個星期做一次全備,一天做一次增量備份。為了不影響線上業務,實現線上備份,並且能增量備份,最好的辦法就是採用主從複製機制(replication),在 slave 機器上做備份。詳細的mysqlreplication請參看mysql主主、主從複製詳解

    一個星期一次的全備的指令碼,指令碼檔案放在/scripts目錄下,備份時需要一些目錄,注意需要手動建立。

#vi mysql_full_bak.sh

#!/bin/bash

# This is mysql mysqlfullbak scripts

#2009-08-20

#badboy

user=bak  

passwd=123456

databak_dir=/backup/cacti   #備份的目錄

eMailFile=$databak_dir/email.txt

DATE=`date +%Y%m%d`

logFile=$databak_dir/logs/mysql$DATE.log

database=cacti

echo "     " > $eMailFile

echo "---------------------------------" >> $eMailFile

echo $(date +"%y-%m-%d %H:%M:%S") >> $eMailFile

cd /data

dumpFile=$database$DATE.sql

GZDumpFile=$database$DATE.tar.gz

options="-u$user -p$passwd --opt --extended-insert=false --triggers=false -R --hex-blob --flush-logs --delete-master-logs -B $database"

mysqldump $options > $dumpFile  #匯出資料檔案

if [[ $? == 0 ]]; then

  tar cvzf $GZDumpFile $dumpFile >> $eMailFile 2>&1

  echo "BackupFileName:$GZDumpFile" >> $eMailFile

  echo "DataBase Backup Success" >> $eMailFile

  scp $GZDumpFile 地址”:/Dir   #傳送備份檔案到另一臺計算機,需要做好ssh信任

  rm -f $dumpFile           #刪除備份的檔案

  rm –rf $databak_dir/daily/*  #刪除每天備份的檔案

else

  echo "DataBase Backup Fail!" >> $emailFile

  mail -s " DataBase Backup Fail " $eMail < $eMailFile  #如果備份不成功傳送郵件通知

fi

echo "--------------------------------------------------------" >> $logFile

cat $eMailFile >> $logFile

更多mysqldump的選項請檢視mysqldump –help

每天增量備份的指令碼,定義為每天4點10分時執行此檔案,備份上一天4點10分之後到今天4點之前的資料

#vi mysqldailybak.sh

#!/bin/bash

# This is mysql mysqldailybak scripts

# 2009-08-20

# badboy

/usr/bin/mysqladmin flush-logs   #

user=bak

passwd=123456

database=cacti

daily_databak_dir=$databak_dir/daily  #備份目錄,需要建立

eMailFile=$daily_databak_dir/email.txt

DATE=`date +%Y%m%d`

logFile=$daily_databak_dir/mysql$DATE.log

echo "     " > $eMailFile

echo "---------------------------------" >> $eMailFile

echo $(date +"%y-%m-%d %H:%M:%S") >> $eMailFile

echo "---------------------------------" >> $eMailFile

TIME=$(date "-d 10 day ago" +%Y%m%d%H%M%S)

StartTime=$(date "-d 1 day ago" +"%Y-%m-%d %H:%M:%S")

echo “Delete 10 days before the log ” >> $eMailFile

mysql -u$user -p"$passwd" -e "purge master logs before ${TIME}" && echo "delete 10 days before log" |tee -a $eMailFile   #刪除10天前的2進位制檔案

filename=/data/`cat /data/mysql-bin.index |awk -F "/" '{print $2}'`   # 2進位制檔案

for i in $filename

do

echo "$StartTime start backup binlog " >> $eMailFile

mysqlbinlog -u$user -p$passwd -d $batabase --start-datetime="$StartTime" $i >> $daily_databak_dir/daily$DATE |tee -a $eMailFile

done

if [ $? = 0 ]

then

 cd $daily_databak_dir

 tar -zcvf $daily_databak_dir/$database$DATE.tar.gz daily$DATE >>/dev/null 2>&1

 #scp $daily_databak_dir/$database$DATE.tar.gz 地址”:/Dir  #傳送備份檔案到另一臺計算機,需要做好ssh信任

 echo "daily backup succeed" >> $eMailFile

else

 echo "daily backup fail" >> $eMailFile

 mail -s "MySQL Backup" $eMail < $eMailFile  #備份失敗之後傳送郵件通知

fi

cat $eMailFile > $logFile

新增可執行的許可權                             

#chmod 755 /scripts/mysql_full_bak.sh /scripts/mysqldailybak.sh

加到crontab裡面讓指令碼自動執行,如果有專門用於備份的伺服器,可以利用ssh認證、scp命令,自動傳送到另一臺伺服器上,保證資料的安全。可以參看rsync引數詳解、利用ssh、rsync 實現資料的定時同步

#su –bak

#crontab –e

10 4 * * 1-6 /scripts/mysqldailybak.sh   #禮拜一到禮拜六執行每天備份指令碼

10 4 * * 0 /scripts/mysql_full_bak.sh   #禮拜天執行全備份的指令碼

如果想把備份之後的資料檔案,傳送到另一臺伺服器上,做好ssh信任之後把指令碼中紅色的哪行註釋去掉就行。需要更多scp的資料請檢視scp --help