優化企業級備份策略,實現無負載資料庫備份及監控

火星人 @ 2014-03-09 , reply:0


前段時間寫過一篇文章 《企業級數據備份,rsync加shell編程,實現增量備份 》,這篇文章的備份原理是每天將資料庫導出來,打包,傳送到備份伺服器上去,在長時間使用的時候,發現了一些缺點,資料庫數據每日增加,每次在導出的時候,mysqldump及tar打包,佔用系統資源過多且耗時過長,導到持續CPU爆高,並且在傳輸數據文件的時候,雖然做了限速,但是還是影響網站打開速度.不得不優化備份程序及策略了. 我的備份伺服器配置還不錯的,只作存儲使用挺浪費的,想,為什麼不用mysql主從複製把數據同步到備份伺服器上,然後在備份伺服器上,導出,打包,如果這種構思成功的話,就能將導出數據及打包這種非常消耗資源動作轉移到備份伺服器上.且大大減少了傳輸時的佔用帶寬比,經過了解,mysql主從複製,基本上是不佔用帶寬的. 經過一上午的實驗,發現這種構思是成功的,並且成功的運用了生產環境.下面我就將生產環境中的一些配置及寫的一些檢查腳本簡要說明一下. 一,伺服器環境:
  1. 生產伺服器: A:192.168.1.10 : mysql版本 5.1.34
  2. 生產伺服器: B:192.168.1.11 : mysql版本 5.1.34
  3. 備份伺服器: C:192.168.1.20 : mysql版本 5.1.34
二,配置mysql主從同步 1,生產伺服器A配置: 開啟A伺服器mysqlbinlog,設置id號並重新啟動:
  1. vim /etc/my.cnf
  2. log-bin = binlog
  3. server-id = 1
  4. #service mysql restart
2:設置備份伺服器C同步A伺服器my的用戶名密碼 創建帳號:(A 伺服器上操作)
  1. mysql>GRANT super,REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY '123456';
  2. mysql>flush privileges;
  3. (註:slave 及 123456分別為用戶名密碼)
3,將A伺服器資料庫數據導出,傳輸到C伺服器上,並導入C伺服器資料庫 4,配置C伺服器的my.cnf 加入以下參數.並啟動C伺服器上的資料庫
  1. vim /etc/my.cnf
  2. server-id = 2 #此處id應與主伺服器id不同
  3. master-host=192.168.1.10
  4. master-user=slave
  5. master-password='123456'
  6. master-port=3306
  7. relay-log=relay-bin
  8. relay-log-index

    =relay-bin
  9. #service mysql start
5,查看A伺服器日誌及偏移量
  1. mysql>show master status\G 輸出如下圖

這裡面顯示日誌文件為 binlog.00629,偏移量為 1495278 (每台伺服器都不一樣,以自己伺服器為準) 6,在備份伺服器C上的mysql服務裡面運行以下命令,同步兩台伺服器
  1. mysql>stop slave;
  2. mysql>reset slave;
  3. 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;
  4. mysql>slave start;
啟動mysql slave 查看是否正常運行
  1. mysql>show slave status\G

如果
  1. Slave_IO_Running: Yes

  2. Slave_SQL_Running: Yes
那說明slave 是正常運行的 執行這些程序后,從伺服器應連接主伺服器,並同步生產伺服器A上面的任何更新. 三,啟動一個新的mysql 服務, 這裡簡述為mysql2,作為生產伺服器B的slave 1,拷貝my.cnf 作為mysql2配置文件,並作相應修改
  1. #cp /etc/my.cnf /etc/my2.cnf
  2. vim /etc/my2.cnf
  3. [client]
  4. port = 3307
  5. socket = /tmp/mysql2.sock
  6. [mysqld]
  7. user = mysql
  8. port = 3307
  9. socket = /tmp/mysql2.sock
  10. server-id = 3 #此處id應與主伺服器id不同
  11. master-host=192.168.1.11
  12. master-user=slave
  13. master-password='123456'
  14. master-port

    =3306
  15. relay-log=relay-bin
  16. relay-log-index=relay-bin
2,先初始化一下資料庫
  1. /usr/local/webserver/mysql/bin/mysql_install_db --datadir=/home/mysql/var2 --user=mysql
3,啟動mysql2伺服器
  1. /usr/local/webserver/mysql2/bin/mysqld_safe --defaults-file=/etc/my2.cnf --basedir=/usr/local/webserver/mysql --datadir=/home/mysql/var2 --user=mysql&
  2. 參數簡介
  3. --defaults-file=/etc/my2.cnf #指定配置文件路徑
  4. --basedir=/usr/local/webserver/mysql #指定程序文件路徑
  5. --datadir=/home/mysql/var2 #指定數據文件路徑
  6. --user=mysql& #指定啟動用戶
這樣.我們又啟動了一個新的mysql進程.
  1. 進入mysql2方式為 mysql --socket=/tmp/mysql2.sock –p密碼
  2. 導入數據至mysql2方式為: mysqldump --socket=/tmp/mysql2.sock -p密碼
按照上面的步驟,把 B 伺服器的數據導入到C伺服器的mysql2下,並啟動slave. 注意:如果生產伺服器里的表有innodb格式的,這樣的方法不行,重新編譯一個mysql伺服器啟動, 四:編寫腳本備份C伺服器中的數據 1,編寫腳本
  1. #vim /home/alldbbak/dbbak.sh
  2. #! /bin/bash
  3. for db in `ls /home/mysql/var/`
  4. do
  5. if [ -d /home/mysql/var/$db ];then
  6. mysqldump $db >/home/alldbbak/dbcache/$db.sql
  7. fi
  8. done
  9. cd /home/alldbbak/dbcache/
  10. tar -cvzf 192.168.1.10.`date "%Y%m%d"`.tar *
  11. find /home/alldbbak/ -name "*.tar" -mtime 5 -exec rm -rf {} \;
  12. mv *.tar ..
  13. rm -rf /home/alldbbak/dbcache/*.sql
  14. cd /home/alldbbak/
  15. for db in `ls /home/mysql/var2/`
  16. do
  17. if [ -d /home/mysql/var2/$db ];then
  18. mysqldump --socket=/tmp/mysql2.sock $db >/home/alldbbak/dbcache/$db.sql
  19. fi
  20. done
  21. cd /home/alldbbak/dbcache/

  22. tar -cvzf 192.168.1.11.`date "%Y%m%d"`.tar *
  23. find /home/alldbbak/ -name "*.tar" -mtime 5 -exec rm -rf {} \;
  24. mv *.tar ..
  25. rm -rf /home/alldbbak/dbcache/*.sql
  26. cd /home/alldbbak/
  27. done
腳本這塊解釋請參照《企業級數據備份,rsync加shell編程,實現增量備份
2, 定時運行
  1. #crontab –e
  2. 00 07 * * * sh /home/alldbbak/dbbak.sh #每天早上7點運行
五:編寫腳本檢查slave伺服器狀態,並在slave同步同出錯后重新同步 1, 先寫好sock文件與ip對應關係
  1. #vim /home/alldbbak/duiyin
  2. /tmp/mysql.sock 192.168.1.10
  3. /tmp/mysql2.sock 192.168.1.11
2, 編寫檢查腳本
  1. #vim /home/alldbbak/autocheck.sh
  2. #! /bin/bash
  3. for i in `seq 1 2`
  4. do
  5. server=`sed -n "$i"p /home/alldbbak/duiyin|awk '{print $2}'`
  6. socket=`sed -n "$i"p /home/alldbbak/duiyin|awk '{print $1}'`
  7. for m in `mysql --socket=$socket -e "show slave status\G"|grep Running|awk '{print $2}'|sed 'N;s/\n//g'`
  8. do
  9. if [ $m != "YesYes" ];then
  10. pos=(`mysql -h$server –p密碼 -e "show master status\G"|sed -n '2,3'p|awk '{print $2}'|sed 'N;s/\n/ /g'`)
  11. mysql --socket=$socket <<EOF
  12. slave stop;
  13. reset slave;
  14. change master to master_host="$server", master_user='slave',master_password='123456',master_log_file="${pos[0]}",master_log_pos=${pos[1]};
  15. slave start;
  16. EOF
  17. sleep 2
  18. yes=`mysql --socket=$socket -p密碼 -e "show slave status\G"|grep Running|awk '{print $2}'|sed 'N;s/\n//g'`
  19. if [ $yes == "YesYes" ];then
  20. fetion --mobile=飛信帳號 --pwd=飛信密碼 --to

    =監控手機號碼 --msg-utf8="$server 同步成功"
  21. else
  22. fetion --mobile=飛信帳號 --pwd=飛信密碼 --to=監控手機號碼 --msg-utf8="$server 同步失敗"
  23. fi
  24. fi
  25. done
  26. done
腳本解釋
  1. #! /bin/bash
  2. for i in `seq 1 2`
  3. do
  4. server=`sed -n "$i"p /home/alldbbak/duiyin|awk '{print $2}'` #分別賦值伺服器ip

  5. socket=`sed -n "$i"p /home/alldbbak/duiyin|awk '{print $1}'` #分別賦值sock文件
  6. for m in `mysql --socket=$socket -e "show slave status\G"|grep Running|awk '{print $2}'|sed 'N;s/\n//g'`
  7. #分別判斷兩個庫的Slave_IO_Running:與 Slave_SQL_Running 是否等於YesYes 這裡我把兩個Yes合併在一起了
  8. do
  9. if [ $m != "YesYes" ];then
  10. pos=(`mysql -h$server –p密碼 -e "show master status\G"|sed -n '2,3'p|awk '{print $2}'|sed 'N;s/\n/ /g'`)
  11. #如果兩個值不等於Yes,就重新獲取主伺服器上的值.賦值給了pos變數,這裡用了一個數組
  12. mysql --socket=$socket <<EOF
  13. slave stop;
  14. reset slave;
  15. change master to master_host="$server", master_user='slave',master_password='123456',master_log_file="${pos[0]}",master_log_pos=${pos[1]}; #重新同步一下slave庫,並啟動

  16. slave start;
  17. EOF
  18. # 進入mysql 運行命令,重新同步數據.
  19. sleep 2
  20. yes=`mysql --socket=$socket -p密碼 -e "show slave status\G"|grep Running|awk '{print $2}'|sed 'N;s/\n//g'`
  21. #2秒后重新判斷兩個庫的Slave_IO_Running:與 Slave_SQL_Running 是否等於YesYes
  22. if [ $yes == "YesYes" ];then
  23. fetion --mobile=飛信帳號 --pwd=飛信密碼 --to=監控手機號碼 --msg-utf8="$server 同步成功"

  24. else
  25. fetion --mobile=飛信帳號 --pwd=飛信密碼 --to=監控手機號碼 --msg-utf8="$server 同步失敗"
  26. fi
  27. fi
  28. done
  29. done
  30. #用飛信軟體,發送一下恢復結果給監控手機.飛信安裝可以在網上查一下資料.
2, 加入計劃任務
  1. */5 * * * * sh /home/alldbbak/autocheck.sh #每5會鍾執行一次
這樣的話,就可以添加一個同步監控了,出錯了,他能自動的去修復,如果修復不了只能手動去修復一下了 這樣改變一下備份的策略,非常好的優化了伺服器在備份時的負載,生產伺服器備份時只要增量的傳輸一些新生成的文件即可. 有什麼不明白的,可以加我QQ相互討論:410018348

本文出自 「運維你的人生」 博客,請務必保留此出處http://yaozb.blog.51cto.com/2762349/800334




[火星人 via ] 優化企業級備份策略,實現無負載資料庫備份及監控已經有183次圍觀

http://www.coctec.com/docs/linux/show-post-47581.html