mysql主從備份方案

如今通用的mysql主從方案已經很成熟,例如,如今公司作的是一主+兩從方案,若是主機宕掉,採用域名方式切換從機,也很是方便。node

如今增長一套方案,實現如下功能:mysql

一、方便的備份可刻盤,或者靈活的備份到第三主機。sql

二、若是出現誤刪除,可恢復。數據庫

第一點是必要的,如出現重大物理災難,例如整個機房癱瘓,刻盤恢復是很重要的,固然這種狀況極低。服務器

設計總體備份圖以下:網絡

 

備份方案socket

數據庫主機是 ***.***.***.245,***.***.***.246,  ***.***.***.39。spa

過程以下設計

一、39從機會每週執行一次定時腳本database_dump_senior.sh一次,生成dump出一份備份,舉例來講每週日上午10點。每次dump出一份都會記錄當天的日期,並將導出的databases_product.sql和binlog_info.txt文件保存到當前日期下,例如 /home/data/mysql_bak/dumps/2013_08_06/ 下。而後rsync同步到245和246的文件夾下。 日誌

二、245會有定時腳本每隔十分鐘執行一次(能夠按需設定),讀取dumps文件夾下的從機binlog信息,讀取binlog_info.txt裏的日期信息生成日期文件夾,讀取binlog_info.txt文件找到要備份的binglog日誌,cp到binlog文件夾下。如/home/data/mysql_bak/binlog/2013_08_06/下。而後同步一份到246和39

三、39和245都會在每次腳本執行時清除8天未被修改過的數據,這樣能夠保持每臺服務器至少有兩個版本的備份。在網絡斷掉的狀況下是有用處的。

 

目錄結構

/home/data/mysql_bak/------dumps
     ------2013_08_06
      ------databases_product.sql
      ------ binlog_info.txt
   ------2013_08_13
      ------databases_product.sql
      ------ binlog_info.txt
   ------binlog_info.txt

------binlog
     ------2013_08_06
              ------mysql-bin.000385
              ------mysql-bin.000386
   ------2013_08_13
              ------mysql-bin.000386
              ------mysql-bin.000387

爲了不轉儲時主機壓力過大,採用在從機備份的方式,39從機在stop slave 後開始 dump一份全庫的備份,而後記錄從機備份的位置,保存在binlog_info.txt裏。binlog_info.txt 保存內容以下:

              current_date:2013_08_15

      Master_Log_File: mysql-bin.000386

  Read_Master_Log_Pos: 90835176

               Relay_Log_File: netease-test-namenode-relay-bin.000022

              Relay_Log_Pos: 253

   Relay_Master_Log_File: mysql-bin.000386

   Exec_Master_Log_Pos: 90835176

               Until_Log_File:

               Until_Log_Pos: 0

current_date 是由腳本根據系統時間生成,其他是讀取從機變量。

 

出現風險的情況

一、  從機39壞了,binlog_info.txt未被替換成新的,這時主機會按從原有的binlog_info.txt讀取到的位置信息,一直保存最新的binlog。

二、  主機245壞了,因爲在246和39備份了binlog,能夠將數據恢復精確到到最後十分鐘(主機定時任務時間)。

三、  從機 246 壞了,無任何影響。

四、採用binlog在主機備份是保證數據始終與主機一致,更高的可靠性。

五、經過刪除腳本,保證不管何時都會有兩份備份,一份最新的,一份上週的。

 

這些都要配合從機狀態監測。

腳本

從機39上跑的腳本:

#!/bin/sh 
current_date=`date +%Y_%m_%d`;
back_path="/home/data/mysql_bak/dumps";
`mkdir -p ${back_path}/${current_date}`;
#中止與主機同步
mysql --socket=/home/mysql/data_product/mysql.sock -e "stop slave";
echo "now, slave stopped!";

#導出全部數據庫
echo "dump all databases begin!";
`mysqldump --all-databases --socket=/home/mysql/data_product/mysql.sock > ${back_path}/${current_date}/databases_product.sql`;
echo "dump all databases end!";

#保存當前日期
`echo "current_date:${current_date}" > ${back_path}/${current_date}/binlog_info.txt`;
#保存如今導出時的binlog位置
`mysql --socket=/home/mysql/data_product/mysql.sock -e "show slave status \G"|egrep 'Log_File|Log_Pos' >> ${back_path}/${current_date}/binlog_info.txt`;

#拷貝一份到備份的根目錄
`cp ${back_path}/${current_date}/binlog_info.txt ${back_path}/binlog_info.txt`;

#從新開啓與主機同步
mysql --socket=/home/mysql/data_product/mysql.sock -e "start slave";
echo "now, slave started!";

#刪除8天前備份,這樣每次保存最新一份,和最新一份的上一份。
find ${back_path}/  -type f -ctime +8 -exec rm -rf {} \;

#刪除空文件夾
find ${back_path}/ -type d -regex ".*/[0-9_]+$"|(while read arg;do if [ `ls  $arg |wc -l` -eq 0 ]; then rmdir $arg ; fi; done)

echo "old backups has been deleted!";

#將備份binlog位置信息文件,傳送給主庫
rsync -avz --delete ${back_path}/ ***.***.***.245::database_bak/dumps/
rsync -avz --delete ${back_path}/ ***.***.***.246::database_bak/dumps/

主機245上跑的腳本

#!/bin/sh save binlogs

#全局變量
back_path="/home/data/mysql_bak";
mysql_path="/home/mysql/data_product";

#判斷若是不存在binlog的備份信息文件,則退出
if [ ! -f "${back_path}/dumps/binlog_info.txt" ];then
    echo "ERROR,binlog_info.txt not exist,please check your file!";
    exit;
fi

cd ${mysql_path};

#讀取備份binlog位置以及日期信息
echo "now,get the backup binlog position info!"
current_date=`cat ${back_path}/dumps/binlog_info.txt|grep 'current_date'|sed 's/current_date://g'|tr ' ' '\0'`; 
logFile=`cat ${back_path}/dumps/binlog_info.txt |grep 'Relay_Master_Log_File'|sed 's/Relay_Master_Log_File://g'|tr ' ' '\0'`;
echo -e "current date is : ${current_date}\nBinlog file is : ${logFile}\n";

#若是不存在則,建立備份文件夾
`mkdir -p ${back_path}/binlog/${current_date}`; 
 
#備份記錄binlog文件以後的剩餘binlog文件
cat mysql-bin.index |grep  -A100 ${logFile}|sed "s/.\///"|awk -v back_path=${back_path} -v current_date=${current_date} \
'{print "now save:" $0 ;system("cp " $0 " "back_path"/binlog/"current_date"/"$0);}';

echo "backup binlog ended!";

#刪除8天前備份,這樣每次保存最新一份,和最新一份的上一份。
find /home/data/mysql_bak/binlog/  -type f -ctime +8 -exec rm -rf {} \;

#刪除空文件夾
find /home/data/mysql_bak/binlog/ -type d -regex ".*/[0-9_]+$"|(while read arg;do if [ `ls  $arg |wc -l` -eq 0 ]; then rmdir $arg ; fi; done)

echo "old backups has been deleted!";

#將備份binlog信息同步到從庫
rsync -avz --delete ${back_path}/binlog/ ***.***.***.39::database_bak/binlog/
rsync -avz --delete ${back_path}/binlog/ ***.***.***.246::database_bak/binlog/
相關文章
相關標籤/搜索