實戰 xtrabackup 全量備份&恢復 MySQL

一、背景

咱們有一臺業務數據庫一直都只作了主從,雖然必定程度上解決了讀寫性能問題,可是這個是有風險的,好比某同窗刪除主庫數據,從庫也會跟着刪除,因此及時的備份仍是頗有必要的。計劃是天天全量備份兩次,爲何不增量備份呢?兩個緣由:html

(1)增量備份在多庫多表的場景下備份策略變得複雜,並且不易驗證業務正確性mysql

(2)增量備份在恢復的時候不能作到快速恢復,這在線上場景下是致命的,業務恢復分秒必爭linux

二、技術選型

業界經常使用的備份工具備兩個,一個是 MySQL 自帶的管理工具 mysqldump,它能完成通常的數據庫管理備份恢復工做,可是性能和功能比較弱,專業性欠缺。另一個是 MySQL諮詢公司Percona提供的 innobackupex,功能強大,性能優秀,是專業級的數據庫備份恢復工具,基本算是業界應用最普遍的備份恢復工具了。c++

Percona XtraBackup(簡稱PXB)是 Percona 公司開發的一個用於 MySQL 數據庫物理熱備的備份工具,支持 MySQl(Oracle)、Percona Server 和 MariaDB,而且開源。sql

Xtrabackup有兩個主要的工具:xtrabackup、innobackupex,如今xtrabackup版本升級到了2.4.4,相比以前的2.1有了比較大的變化:innobackupex 功能所有集成到 xtrabackup 裏面,只有一個 binary,另外爲了使用上的兼容考慮,innobackupex做爲 xtrabackup 的一個軟鏈,即xtrabackup如今支持非Innodb表備份,而且Innobackupex在下一版本中移除,建議經過xtrabackup替換innobackupex。數據庫

  (1)xtrabackup是C/C++編譯的二進制文件,只能備份InnoDB和XtraDB兩種數據表,而不能備份MyISAM數據表;bash

  (2)innobackupex則封裝了xtrabackup,是一個perl腳本封裝,因此能同時備份處理innodb和myisam,但在處理myisam時須要加一個讀鎖;服務器

整個備份過程以下圖:app

三、經常使用參數

--defaults-file:指明服務器的配置文件,此參數必須做爲innobackupex的第一個參數,不然報錯socket

--host:指明鏈接數據庫的主機

--user:指明執行數據庫備份的用戶名

--password:指明執行備份的密碼

--backup:指明爲備份,此參數能夠忽略

--apply-log:重作日誌

--copy-back:執行數據恢復

--slave-info:備份從庫的show slave status信息,僅用於在備份從庫時使用

--no-lock:不鎖表,僅適用於存儲引擎爲innodb,而且不在意備份位置點時使用

四、自動化備份恢復腳本

4.1 安裝:

sudo yum -y install libaio libaio-devel libev.x86_64 
sudo yum -y install perl  perl-DBD-MySQL perl-DBI perl-devel perl-Digest-MD5 perl-TermReadKey  perl-Time-HiRes

wget https://www.percona.com/downloads/Percona-XtraBackup-2.4/Percona-XtraBackup-2.4.15/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.15-1.el7.x86_64.rpm

rpm -ivh percona-xtrabackup-24-2.4.15-1.el7.x86_64.rpm

4.2 備份:

#全量備份 MySQL
set -x
echo "===========backup start========="`date -Iseconds`

IP=`/usr/sbin/ss |head |awk '{print $4}'|grep -vE '127.0.0.1|0.0.0.0'|awk -F: '/\./{print $1;exit}'`
bak_date=`date +"%Y-%m-%d_%H"`
bak_date_short=`date +"%Y-%m-%d"`
mysql_datadir=`cat /etc/my.cnf|grep datadir|awk -F= '{print $2}'`
#bak_base_dir=`echo $mysql_datadir|awk -F/ 'NF=NF-1{OFS="/";print $0}'`
bak_base_dir=/opt/data/bak_mysql
bak_dir=$bak_base_dir/${bak_date}__${IP}
FINISH_FLAG_FILE=$bak_dir/Finish.flag

## 全量備份
/usr/bin/innobackupex --defaults-file=/etc/my.cnf  \
--backup \
--datadir=$mysql_datadir \
--user=$username \
--password=${passwords[$IP]} \
--host=127.0.0.1 \
--port=3306 \
--kill-long-queries-timeout=30 \
--kill-long-query-type=select \
--lock-wait-timeout=60 \
--lock-wait-query-type=update \
--no-timestamp \
$bak_dir 
[[ $? -eq 0 ]] || { echo "Backup ERROR!"; sendSMS $telList "$IP Backup MySQL Fail!"; exit 110; }

bak_rsync(){
    ## TODO:
    # 能夠改爲自動建立目錄
    #傳輸備份到遠端機器:災備
    rsync -avz $bak_dir root@$remote_bak_ip:$bak_base_dir
    
    #傳輸結束標記文件,對端以此檢測文件傳輸完成
    touch $FINISH_FLAG_FILE
    rsync -avz $FINISH_FLAG_FILE root@$remote_bak_ip:$bak_dir
}

##(1) kinit 免密登陸任意 kerberos 受權機器 
kinit user <<<$kerberos_passwd
##(2)備份數據庫
#backup_mysql_full
##(3)傳輸備份到遠程機器
bak_rsync

echo "===========backup finish========="`date -Iseconds`

4.3 恢復:

# 全量恢復 MySQL
set -x
echo "===========recovery start========="`date -Iseconds`

IP=`/usr/sbin/ss |head |awk '{print $4}'|grep -vE '127.0.0.1|0.0.0.0'|awk -F: '/\./{print $1;exit}'`
username=root
bak_date=`date +"%Y-%m-%d_%H"`
bak_date_short=`date +"%Y-%m-%d"`
mysql_datadir=/opt/data/mysql
bak_base_dir=/opt/data/bak_mysql
bak_dir=$bak_base_dir/${bak_date}__${recovery_server_ip}
FINISH_FLAG_FILE=$bak_dir/Finish.flag
# 超時 N 秒
TIMEOUT=7200
kinit user <<<$kerberos_passwd


bak_recovery(){
    # TODO:
    # 此處應該先備份,可是磁盤不夠,先不作,直接刪除
    rm -rf ${mysql_datadir:?var is empty will exit}
    mkdir -p $mysql_datadir
    /usr/bin/innobackupex --defaults-file=/etc/my.cnf --user=root  --apply-log $bak_dir
    /usr/bin/innobackupex --defaults-file=/etc/my.cnf --user=root  --move-back $bak_dir
    chown -R mysql.mysql  $mysql_datadir 
}

execute_recovery(){
    service mysqld stop
    bak_recovery
    service mysqld start
    result=`mysql -uusername -ppasswd -NB -e  'select 1'`
    [[ $result -eq 1 ]] && rm -rf ${bak_dir:?var is empty  will exit} || { echo "Recovery ERROR!"; sendSMS $telList "$IP Recovery MySQL Fail!"; }
}

while [[ $c -lt $TIMEOUT ]]
do
    ((c++))
    mkdir -p $bak_dir
    rsync -avz root@$bak_server_ip:$FINISH_FLAG_FILE $FINISH_FLAG_FILE 2>/dev/null
    [[ $? -ne 0 ]] && continue
    rsync -avz root@$bak_server_ip:$bak_dir $bak_base_dir
    [[ $? -eq 0 ]] && execute_recovery && echo "SUCCESS!" && break
    sleep 1
done
# 若是文件在 TIMEOUT 時間內尚未恢復成功,那就發個告警吧~
[[ $c -ge $TIMEOUT ]] && echo `date +'%F %T'`"Recovery Timeout ..." && sendSMS $telList "$IP Recovery retry $c times, and it's Exception!"

echo "===========recovery finish========="`date -Iseconds`

附:CentOS7 安裝 mysql-5.7(glibc版)

#參考:https://blog.csdn.net/lidachao01/article/details/50555385

一、下載
nohup wget --no-check-certificate --user-agent="Mozilla/5.0 (X11;U;Linux i686;en-US;rv:1.9.0.3) Geco/2008092416 Firefox/3.0.3" https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.27-linux-glibc2.12-x86_64.tar.gz &

二、初始化
bin/mysqld --initialize  --basedir=/opt/data/mysql_basedir --datadir=/opt/data/mysql  --user=mysql --log-error=/opt/data/mysql/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/opt/data/mysql/mysql.sock --explicit_defaults_for_timestamp

bin/mysql_ssl_rsa_setup --basedir=/opt/data/mysql_basedir --datadir=/opt/data/mysql

bin/mysqld_safe --user=mysql --basedir=/opt/data/mysql_basedir --datadir=/opt/data/mysql &

三、須要修改 basedir、datadir
cp support-files/mysql.server /etc/init.d/mysqld 

# 在[mysqld]中添加或者修改一下內容:
basedir=/opt/data/mysql_basedir
datadir=/opt/data/mysql
socket=/opt/data/mysql/mysql.sock

vi /etc/profile  #配置環境變量 添加以下內容
export MYSQL_HOME="/opt/data/mysql_basedir"
export PATH="$PATH:$MYSQL_HOME/bin"

# source profile  #使配置及時生效
至此可用service mysqld start來啓動mysql數據庫。

四、配置開機啓動mysql服務
# chkconfig --add mysqld
# chkconfig --level 2345 mysqld on

五、首次登入mysql
# mysql -u root -p
Enter password:輸入以前生成的臨時密碼,應該會在初始化屏幕上顯示或者在 datadir log 中找到
mysql> SET PASSWORD = PASSWORD('123456');

六、外部訪問
use mysql;
select host,user from user;
grant all privileges  on *.* to root@'%' identified by "password";
flush privileges;

七、-- 可選操做:CentOS升級到7以後,使用firewalld代替了原來的iptables。下面記錄如何使用firewalld開放Linux端口
#  firewall-cmd --zone=public --add-port=3306/tcp --permanent
#  firewall-cmd --reload  #重啓防火牆

Refer:

[1] xtrabackup 使用說明(續)

http://www.cnblogs.com/zhoujinyi/p/5893333.html

[2] 【mysql】使用xtrabackup在線增量備份及恢復數據庫

https://www.cnblogs.com/chenpingzhao/p/4905310.html

[3] MySQL之——基於mysqldump全量備份還原

http://www.javashuo.com/article/p-uamskjts-ba.html

[4] pt-online-schema-change utf8mb4 錯誤解決方法

http://www.ttlsa.com/mysql/pt-online-schema-change-utf8mb4-error-solution/

[5] Download Percona XtraBackup

https://www.percona.com/downloads/XtraBackup/LATEST/

相關文章
相關標籤/搜索