前段時間寫過一篇文章 《企業級數據備份,rsync加shell編程,實現增量備份 》,這篇文章的備份原理是每天將數據庫導出來,打包,傳送到備份服務器上去,在長時間使用的時候,發現了一些缺點,由於數據庫數據每日增加,每次在導出的時候,mysqldump及tar打包,佔用系統資源過多且耗時過長,導到持續CPU爆高,並且在傳輸數據文件的時候,雖然做了限速,但是還是影響網站打開速度。所以不得不優化備份程序及策略了。
我的備份服務器配置還不錯的,只作存儲使用挺浪費的,所以想,爲什麼不用mysql主從複製把數據同步到備份服務器上,然後在備份服務器上,導出,打包,如果這種構思成功的話,就能將導出數據及打包這種非常消耗資源動作轉移到備份服務器上。且大大減少了傳輸時的佔用帶寬比,經過了解,mysql主從複製,基本上是不佔用帶寬的。
經過一上午的實驗,發現這種構思是成功的,並且成功的運用了生產環境。下面我就將生產環境中的一些配置及寫的一些檢查腳本簡要說明一下。
一,服務器環境:
- 生產服務器: A:192.168.1.10 : mysql版本 5.1.34
- 生產服務器: B:192.168.1.11 : mysql版本 5.1.34
- 備份服務器: C:192.168.1.20 : mysql版本 5.1.34
二,配置mysql主從同步
1,生產服務器A配置:
開啓A服務器mysqlbinlog,設置id號並重新啓動:
- vim /etc/my.cnf
- log-bin = binlog
- server-id = 1
- #service mysql restart
2:設置備份服務器C同步A服務器my的用戶名密碼
創建帳號:(A 服務器上操作)
- mysql>GRANT super,REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY '123456';
- mysql>flush privileges;
- (注:slave 及 123456分別爲用戶名密碼)
3,將A服務器數據庫數據導出,傳輸到C服務器上,並導入C服務器數據庫
4,配置C服務器的my.cnf 加入以下參數.並啓動C服務器上的數據庫
- vim /etc/my.cnf
- server-id = 2 #此處id應與主服務器id不同
- master-host=192.168.1.10
- master-user=slave
- master-password='123456'
- master-port=3306
- relay-log=relay-bin
- relay-log-index=relay-bin
- #service mysql start
5,查看A服務器日誌及偏移量
- mysql>show master status\G 輸出如下圖
這裏面顯示日誌文件爲 binlog.00629,偏移量爲 1495278 (每臺服務器都不一樣,以自己服務器爲準)
6,在備份服務器C上的mysql服務裏面運行以下命令,同步兩臺服務器
- mysql>stop slave;
- mysql>reset slave;
- mysql>change master to master_host='192.168.1.10', master_user='slave',master_password='123456',master_log_file=’binlog.00629',master_log_pos=1495278;
- mysql>slave start;
啓動mysql slave
查看是否正常運行
- mysql>show slave status\G
如果
- Slave_IO_Running: Yes
- Slave_SQL_Running: Yes
那說明slave 是正常運行的
執行這些程序後,從服務器應連接主服務器,並同步生產服務器A上面的任何更新。
三,啓動一個新的mysql 服務, 這裏簡述爲mysql2,作爲生產服務器B的slave
1,拷貝my.cnf 作爲mysql2配置文件,並作相應修改
- #cp /etc/my.cnf /etc/my2.cnf
- vim /etc/my2.cnf
- [client]
- port = 3307
- socket = /tmp/mysql2.sock
- [mysqld]
- user = mysql
- port = 3307
- socket = /tmp/mysql2.sock
- server-id = 3 #此處id應與主服務器id不同
- master-host=192.168.1.11
- master-user=slave
- master-password='123456'
- master-port=3306
- relay-log=relay-bin
- relay-log-index=relay-bin
2,先初始化一下數據庫
- /usr/local/webserver/mysql/bin/mysql_install_db --datadir=/home/mysql/var2 --user=mysql
3,啓動mysql2服務器
- /usr/local/webserver/mysql2/bin/mysqld_safe --defaults-file=/etc/my2.cnf --basedir=/usr/local/webserver/mysql --datadir=/home/mysql/var2 --user=mysql&
- 參數簡介
- --defaults-file=/etc/my2.cnf #指定配置文件路徑
- --basedir=/usr/local/webserver/mysql #指定程序文件路徑
- --datadir=/home/mysql/var2 #指定數據文件路徑
- --user=mysql& #指定啓動用戶
這樣。我們又啓動了一個新的mysql進程。
- 進入mysql2方式爲 mysql --socket=/tmp/mysql2.sock –p密碼
- 導入數據至mysql2方式爲: mysqldump --socket=/tmp/mysql2.sock -p密碼
按照上面的步驟,把 B 服務器的數據導入到C服務器的mysql2下,並啓動slave.
注意:如果生產服務器裏的表有innodb格式的,這樣的方法不行,必須重新編譯一個mysql服務器啓動,
四:編寫腳本備份C服務器中的數據
1,編寫腳本
- #vim /home/alldbbak/dbbak.sh
- #! /bin/bash
- for db in `ls /home/mysql/var/`
- do
- if [ -d /home/mysql/var/$db ];then
- mysqldump $db >/home/alldbbak/dbcache/$db.sql
- fi
- done
- cd /home/alldbbak/dbcache/
- tar -cvzf 192.168.1.10.`date +"%Y%m%d"`.tar *
- find /home/alldbbak/ -name "*.tar" -mtime +5 -exec rm -rf {} \;
- mv *.tar ..
- rm -rf /home/alldbbak/dbcache/*.sql
- cd /home/alldbbak/
- for db in `ls /home/mysql/var2/`
- do
- if [ -d /home/mysql/var2/$db ];then
- mysqldump --socket=/tmp/mysql2.sock $db >/home/alldbbak/dbcache/$db.sql
- fi
- done
- cd /home/alldbbak/dbcache/
- tar -cvzf 192.168.1.11.`date +"%Y%m%d"`.tar *
- find /home/alldbbak/ -name "*.tar" -mtime +5 -exec rm -rf {} \;
- mv *.tar ..
- rm -rf /home/alldbbak/dbcache/*.sql
- cd /home/alldbbak/
- done
腳本這塊解釋請參照《企業級數據備份,rsync加shell編程,實現增量備份》
2, 定時運行
- #crontab –e
- 00 07 * * * sh /home/alldbbak/dbbak.sh #每天早上7點運行
五:編寫腳本檢查slave服務器狀態,並在slave同步同出錯後重新同步
1, 先寫好sock文件與ip對應關係
- #vim /home/alldbbak/duiyin
- /tmp/mysql.sock 192.168.1.10
- /tmp/mysql2.sock 192.168.1.11
2, 編寫檢查腳本
- #vim /home/alldbbak/autocheck.sh
- #! /bin/bash
- for i in `seq 1 2`
- do
- server=`sed -n "$i"p /home/alldbbak/duiyin|awk '{print $2}'`
- socket=`sed -n "$i"p /home/alldbbak/duiyin|awk '{print $1}'`
- for m in `mysql --socket=$socket -e "show slave status\G"|grep Running|awk '{print $2}'|sed 'N;s/\n//g'`
- do
- if [ $m != "YesYes" ];then
- pos=(`mysql -h$server –p密碼 -e "show master status\G"|sed -n '2,3'p|awk '{print $2}'|sed 'N;s/\n/ /g'`)
- mysql --socket=$socket <<EOF
- slave stop;
- reset slave;
- change master to master_host="$server", master_user='slave',master_password='123456',master_log_file="${pos[0]}",master_log_pos=${pos[1]};
- slave start;
- EOF
- sleep 2
- yes=`mysql --socket=$socket -p密碼 -e "show slave status\G"|grep Running|awk '{print $2}'|sed 'N;s/\n//g'`
- if [ $yes == "YesYes" ];then
- fetion --mobile=飛信帳號 --pwd=飛信密碼 --to=監控手機號碼 --msg-utf8="$server 同步成功"
- else
- fetion --mobile=飛信帳號 --pwd=飛信密碼 --to=監控手機號碼 --msg-utf8="$server 同步失敗"
- fi
- fi
- done
- done
腳本解釋
- #! /bin/bash
- for i in `seq 1 2`
- do
- server=`sed -n "$i"p /home/alldbbak/duiyin|awk '{print $2}'` #分別賦值服務器ip
- socket=`sed -n "$i"p /home/alldbbak/duiyin|awk '{print $1}'` #分別賦值sock文件
- for m in `mysql --socket=$socket -e "show slave status\G"|grep Running|awk '{print $2}'|sed 'N;s/\n//g'`
- #分別判斷兩個庫的Slave_IO_Running:與 Slave_SQL_Running 是否等於YesYes 這裏我把兩個Yes合併在一起了
- do
- if [ $m != "YesYes" ];then
- pos=(`mysql -h$server –p密碼 -e "show master status\G"|sed -n '2,3'p|awk '{print $2}'|sed 'N;s/\n/ /g'`)
- #如果兩個值不等於Yes,就重新獲取主服務器上的值。賦值給了pos變量,這裏用了一個數組
- mysql --socket=$socket <<EOF
- slave stop;
- reset slave;
- change master to master_host="$server", master_user='slave',master_password='123456',master_log_file="${pos[0]}",master_log_pos=${pos[1]}; #重新同步一下slave庫,並啓動
- slave start;
- EOF
- # 進入mysql 運行命令,重新同步數據。
- sleep 2
- yes=`mysql --socket=$socket -p密碼 -e "show slave status\G"|grep Running|awk '{print $2}'|sed 'N;s/\n//g'`
- #2秒後重新判斷兩個庫的Slave_IO_Running:與 Slave_SQL_Running 是否等於YesYes
- if [ $yes == "YesYes" ];then
- fetion --mobile=飛信帳號 --pwd=飛信密碼 --to=監控手機號碼 --msg-utf8="$server 同步成功"
- else
- fetion --mobile=飛信帳號 --pwd=飛信密碼 --to=監控手機號碼 --msg-utf8="$server 同步失敗"
- fi
- fi
- done
- done
- #最後用飛信軟件,發送一下恢復結果給監控手機。飛信安裝可以在網上查一下資料。
2, 加入計劃任務
- */5 * * * * sh /home/alldbbak/autocheck.sh #每5會鍾執行一次
這樣的話,就可以添加一個同步監控了,出錯了,他能自動的去修復,如果修復不了只能手動去修復一下了
這樣改變一下備份的策略,非常好的優化了服務器在備份時的負載,生產服務器備份時只要增量的傳輸一些新生成的文件即可。
有什麼不明白的,可以加我QQ相互討論:410018348
最後推廣一下我的網站 看電影網