MySQL中xtrabackup備份恢復全攻略(r12筆記第11天)

2021-02-24 楊建榮的學習筆記

   XtraBackup是Percona推出的一款備份工具,算是對於mysqldump的一個補充。對於大批量數據的導入使用mysqldump會出現一定的瓶頸,這一點做過一些數據遷移項目的同學可能感同身受。

  數據遷移中的數據量,小有小的好,大有大的招,見招拆招,找到適合的場景是最佳的。

    如果現在去Percona官網下載,就會發現最新的版本已經是2.4.6了。下載可以選擇一個完整的打包,或者逐個的rpm根據需求來安裝也可以。完整的工具大概在60M左右。

    而目前的MySQL版本大多都在5.5, 5.6, 對於5.7相對來說要新一些。中間會有一些時間的過渡,在多年前,可能相對來說用2.0版本一下的還比較多。

   XtraBackup其實包含兩個工具,一個是xtrabackup,另外一個是innobackupex。我們暫且以一個較早的版本作為演示,然後使用新版本來對比下。

# xtrabackup --version
xtrabackup version 1.6.5 for Percona Server 5.1.59

innobackupex --version
InnoDB Backup Utility v1.5.1-xtrabackup; Copyright 2003, 2009 Innobase Oy
and Percona Inc 2009-2012.  All Rights Reserved.

   可以看到這兩個工具的版本還有一些差別,

xtrabackup主要是用於熱備份innodb,或者是 xtradb表中數據的工具,不能備份其他類型的表,也不能備份數據表結構;

innobackupex是將xtrabackup進行封裝的perl腳本,可以備份和恢復MyISAM表以及數據表結構。

   所以總體來看InnoDB的使用場景雖然最為普遍,但是還得考慮到MyISAM,兩者總體來說,使用innobackex的場景會多一些。

  使用innobackupex備份,命令選項還不少,可以使用innobackupex --help來查看明細的參數使用。

比如我需要做一個全備。可以採用如下類似的方式,在備份命令中加幾個輔助選項,備份使用socket連接,備份目錄在/home/databak/full/20170322下。

innobackupex --socket=/home/mysql/mysql.sock  /home/databak/full/20170322  --no-timestamp --no-lock --throttle=100備份後查看對應的目錄,備份的數據情況如下,其中紅色的幾個文件是備份中額外生成的。整體看來和源庫的目錄結構一樣。

# du -sh ./*
2.6G    ./backend
4.0K    ./backup-my.cnf
646M    ./gm
1.0G    ./ibdata1
99M     ./mobile_activity
5.0G    ./mobile_billing
1.1M    ./mysql
2.0G    ./oem_mon
212K    ./performance_schema
112K    ./test
4.0K    ./xtrabackup_binary
4.0K    ./xtrabackup_checkpoints
4.0K    ./xtrabackup_logfile對於上面生成的文件,我們簡單看一下。

binary結尾的文件是備份中用到的可執行文件,這個可以對應幾個版本,比如xtrabackup_51,xtrabackup_55等

# more xtrabackup_binary
xtrabackup_55logfile結尾的文件的內容無法直接查看,但是可以用strings來看。通過strings解析可以看到對應的二進位日誌,當然事務的Xid也有的。

# strings xtrabackup_logfile
xtrabkup 170322 16:33:40
{       ';{
        ';{
MySQLXid
./mysql-bin.000009
        393102654
08360000000039DB下面的這個文件就更特別了,這個是作為數據的備份恢復的關鍵,裡面有著備份恢復所有的檢查點LSN,從下面的數據來看,這是一個全備,因為from_lsn=0.

# cat xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 30754980731
last_lsn = 30754980731

而在源庫的目錄結構下,我們稍作過濾,也會得到一個幾乎和這個工具備份出來一樣的目錄結構來。  

# du -sh ./*|grep -v mysql-bin|grep -v innodb|grep -v log
2.6G    ./backend
646M    ./gm
1.0G    ./ibdata1
4.5M    ./ib_lru_dump
99M     ./mobile_activity
5.0G    ./mobile_billing
1.1M    ./mysql
4.0K    ./mysql.pid
0       ./mysql.sock
2.0G    ./oem_mon
212K    ./performance_schema
112K    ./test所以xtrabackup這樣一個工具就是一個熱備工具,有點類似有文件級別的拷貝,但是不止於此,我們往下看。   

  數據恢復是DBA最重要的工作之一,多年之前,這個「之一「的字眼還要去掉。數據無法恢復,則備份無意義。

   數據的恢復還是使用innobackupex這個工具,這是參數有些差別。

   這裡的數據恢復分為兩個步驟,prepare和還原恢復,prepare的意義就在於,如果我們備份數據的時候,存在未提交的事務,但是數據卻存在於備份中,這樣就是一個數據不一致的狀態,在啟動資料庫的時候需要走一個前滾,然後是一個回滾的操作。這個體現主要就在於logfile和ibdata。是使用apply-log這個選項實現的。

   我們使用如下的方式來做。

innobackupex --defaults-file=/home/databak/full/20170322/backup-my.cnf --user=root --apply-log /home/databak/full/20170322這個過程其實就會隱式調用xtrabackup_55這個可執行文件,調用的命令類似於:

xtrabackup_55  --defaults-file="/home/databak/full/20170322/backup-my.cnf"默認會使用100M的內存,也可以使用選項--use-memory來調整,整個過程會重構redo日誌文件和ibdata.

   這個步驟完成之後就是最關鍵的地方了,還原恢復。這個過程是使用copy-back的選項實現的。

innobackupex --defaults-file=/home/databak/full/20170322/backup-my.cnf --user=root --copy-back /home/databak/full/20170322整個過程就是大量的拷貝工作。

完成之後需要修改一下文件的屬主,默認是root,然後啟動即可。


   我們接下來看看增量備份和恢復,先來創建一些數據。我們在資料庫test下創建一個表test2.

> create table test2 (id int);
Query OK, 0 rows affected (0.01 sec)
> insert into test2 values(1),(2);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

因為剛剛已經做了全備,我們繼續做一個增備。

使用的命令如下:

 innobackupex --defaults-file=/etc/my.cnf --user=root --incremental-basedir=/home/databak/incre/20170322 --incremental /home/databak/incre/20170322但是很不幸,執行失敗了。這個錯誤帶有典型的意義。

170322 18:05:34  innobackupex: Starting ibbackup with command: xtrabackup_55  --defaults-file="/etc/my.cnf" --backup --suspend-at-end --target-dir=/home/databak/incre/20170322/2017-03-22_18-05-32 --incremental-basedir='/home/databak/incre/20170322'
innobackupex: Waiting for ibbackup (pid=4079) to suspend
innobackupex: Suspend file '/home/databak/incre/20170322/2017-03-22_18-05-32/xtrabackup_suspended'
...
xtrabackup: Error: cannot open /home/databak/incre/20170322/xtrabackup_checkpoints
xtrabackup: error: failed to read metadata from /home/databak/incre/20170322/xtrabackup_checkpoints
innobackupex: Error: ibbackup child process has died at /usr/bin/innobackupex line 349.原因就在於裡面的一個關鍵文件 _checkpoints

使用增備得有一個參考點,從哪裡開始,即從哪個LSN開始,這個LSN在指定的參數--incremental-basedir=/home/databak/incre/20170322 下不存在,因為這個是一個新目錄,所以需要指向全庫備份的目錄。

  然後修復後備份就沒問題了,英為有了這個參考點LSN,所以需要要說明的是這個備份其實有累計增量和差異增量了。

  這個怎麼理解呢,比如周日做一個全備,周一做一個增備,周二做一個周日全備到周二的一個增備,這就是一個累計增量備份,而周三的時候做一個周二至周三數據變化的備份,就是一個差異增量備份。

  下面的是一個累計增量備份。因為基準是上次的一個全備,備份後會自動生成一個目錄,比如 2017-03-22_18-07-38

  innobackupex --defaults-file=/etc/my.cnf --user=root --incremental-basedir=/home/databak/full/20170322 --incremental /home/databak/incre/20170322   為了區別兩次增量,我繼續插入兩行數據。

> insert into test2 values (3),(4);
Query OK, 2 rows affected (0.00 sec)  這樣表test2就有4條數據了,每次插入2條。

  下面的是一個差異增量備份。基於上一次的增備。

 innobackupex --defaults-file=/etc/my.cnf --user=root --incremental-basedir=/home/databak/incre/20170322/2017-03-22_18-07-38 --incremental /home/databak/incre/20170322  整個恢復的過程是下面的形式,還是一個prepare的過程,首先是全備:

innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log --redo-only /home/databak/full/20170322然後是增備,注意這裡標紅的參數。

innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log --redo-only /home/databak/full/20170322 --incremental-dir=/home/databak/incre/20170322/2017-03-22_18-07-38這樣做其實是一個merge的過程,對於增備來說,會生成如下的幾個文件,都是.delta, .meta之類的文件。

[test]# ll
total 132
-rw-r--r-- 1 mysql mysql    61 Mar 22 17:58 db.opt
-rw-rw---- 1 mysql mysql  8556 Mar 22 18:03 test2.frm
-rw-r--r-- 1 root  root  81920 Mar 22 18:08 test2.ibd.delta
-rw-r--r-- 1 root  root     18 Mar 22 18:08 test2.ibd.meta

增備目錄下的checkpoint文件就有意思了。有一個很清晰的LSN的增量描述。

[ 2017-03-22_18-07-38]# cat *checkpoints
backup_type = incremental
from_lsn = 30754980731
to_lsn = 30754984465
last_lsn = 30754984465而prepare之後的全備裡面的checkpoint文件其實已經發生了變化

# cat *checkpoints
backup_type = full-prepared
from_lsn = 0
to_lsn = 30754984465
last_lsn = 30754984465這個時候我們使用如下的方式來還原恢復。

#innobackupex --defaults-file=/etc/my.cnf --user=root --copy-back /home/databak/incre/20170322/2017-03-22_18-07-38這個時候表test2裡面的數據是幾條? 是2條。

   這個過程我們相當於完成了一個全備+一個增備的數據恢復過程。

  而我們在一個增備之後又插入了一些數據,這個怎麼繼續恢復呢,還是prepare的過程。這個路徑需要注意,還是merge到全備中。

innobackupex --defaults-file=/etc/my.cnf --user=root --apply-log --redo-only /home/databak/full/20170322  --incremental-dir=/home/databak/incre/20170322/2017-03-22_18-11-26繼續還原恢復。

innobackupex --defaults-file=/etc/my.cnf --user=root --copy-back /home/databak/full/20170322再次查看數據,我們要恢復的4條數據都恢復回來了。

> select *from test2;
+-+
| id   |
+-+
|    1 |
|    2 |
|    3 |
|    4 |
+-+
4 rows in set (0.06 sec)

innobackupex中的選項很多,有幾個還是比較有特色的,比如stream選項,--slave-info選項能夠方便搭建從庫,生成偏移量的信息,比如並行--parallel等,還可以根據LSN來備份,選項是--incremental-lsn

對於stream選項,默認是打包,可以結合管道來實現壓縮,比如:innobackupex --defaults-file=/etc/my.cnf --user=root --stream=tar  /home/databak/full/20170322_2 | gzip > /home/databak/full/20170322_2/20170322_2.tar.gz   

   很多時候其實我不想備份整個庫,我只想備份一個表,那麼這個操作如何來實現呢。

innobackupex --defaults-file=/etc/my.cnf --user=root --include='test.test2'  /home/databak/full/20170322_2這裡有幾點需要注意,工具還是會逐個去掃描,只是那些不符合的會被忽略掉,也就意味著備份出來的情況和全備的目錄結構是一樣的,但是指定的表會備份出ibd,frm文件。

[test]# ll
total 1036
-rw-r--r-- 1 mysql mysql    8556 Mar 22 18:34 test2.frm
-rw-r--r-- 1 root  root  1048576 Mar 22 19:26 test2.ibd
[ test]# cd ../mysql
[ mysql]# ll
total 0而且有一點值得吐槽一下的是,ibdata也會完整備份出來,如果這個文件很大,那就相當不給力了。

不過也別對這種備份失去信心,有一個場景還是很實用的。那就是遷移表。

   

  還是剛剛的這個場景,如果表test2需要拷貝到另外一套環境中,我們可以使用Innobackupex來做物理備份,然後還原導入,達到遷移的目的。

下面的命令會聲明指定目錄下的備份需要導出對象。    innobackupex --apply-log --export /home/databak/full/20170322_2/2017-03-22_19-26-46這個過程的直接產物就是生成了一個.exp文件,在MySQL原生版本中是.cfg文件

[ test]# ll
total 1052
-rw-r--r-- 1 root  root    16384 Mar 22 19:29 test2.exp
-rw-r--r-- 1 mysql mysql    8556 Mar 22 18:34 test2.frm
-rw-r--r-- 1 root  root  1048576 Mar 22 19:26 test2.ibd對表test2做數據信息截斷。

> alter table test2 discard tablespace;
Query OK, 0 rows affected (0.07 sec)然後就是物理拷貝,複製.exp文件和.ibd文件到指定目錄下,修改屬主權限。

然後使用import的方式即可完成導入。

> alter table test2 import tablespace;
Query OK, 0 rows affected (0.00 sec)有另外一點值得說的是,這個.exp文件是不是必須的,其實也不是。

我們只拷貝.ibd文件也照樣可以。可能在新版本中會有一些警告提示,我們重新來做一下。

[test]> alter table test2 discard tablespace;
Query OK, 0 rows affected (0.03 sec)同時刪除剛剛拷貝過來的.exp文件。

然後拷貝ibd文件到指定目錄,賦權限

導入表空間信息。

[test]> alter table test2 import tablespace;
Query OK, 0 rows affected (0.00 sec)查看數據的情況,發現數據還是回來了。

[test]> select *from test2;
+-+
| id   |
+-+
|    1 |
|    2 |
|    3 |
|    4 |
+-+
4 rows in set (0.00 sec)當然這個過程中還是有很多需要注意的地方。

相關焦點

  • MySQL數據備份與恢復(二) -- xtrabackup工具
    上一篇介紹了邏輯備份工具mysqldump,本文將通過應用更為廣泛的物理備份工具xtrabackup來演示數據備份及恢復的第二篇內容(本文篇幅較長
  • xtrabackup 實現MySQL資料庫備份
    因此我們這裡就來介紹xtrabackup的使用。Xtrabackup提供了兩種命令行工具:xtrabackup:專用於備份InnoDB和XtraDB引擎的 數據;innobackupex:這是一個perl腳本,在執行過程中會調用xtrabackup命令,這樣用該命令即可以實現備 份InnoDB,也可以備份MyISAM引擎的對象。
  • xtrabackup 備份原理
    mysqldump 是邏輯備份工具,在數據量越來越大的情況下,備份和恢復所需要的時間越來越長,於是出現了
  • 組複製常規操作-使用xtrabackup備份恢復或添加組成員 | 全方位認識MySQL8.0 Group Replication
    19 xtrabackup_info-rw-r 1 root root 5632 Oct 12 17:19 xtrabackup_logfile-rw-r 1 root root 262 Oct 12 17:19 xtrabackup_tablespaces將備份數據傳輸到新的等待加入組的Server node4的主機中(對於node4的資料庫Server初始化安裝
  • MySQL - Xtrabackup簡介
    Xtrabackup是由percona開源的免費資料庫熱備份軟體,它能對InnoDB資料庫和XtraDB存儲引擎的資料庫非阻塞地備份(對於MyISAM的備份同樣需要加表鎖);mysqldump備份方式是採用的邏輯備份,其最大的缺陷是備份和恢復速度較慢,如果資料庫大於50G,mysqldump備份就不太適合
  • Mysql 物理備份Xtrabackup
    . 28 mysql dba     4096 7月  10 2020 sharedrwxr-xr-x.  2 mysql dba     4096 7月  11 2020 support-filesdrwxr-xr-x.  3 mysql dba     4096 7月  10 2020 var創建備份目錄[root@localhost
  • 【MySQL在線熱備神器】MySQL · 物理備份 · Percona XtraBackup 備份原理
    簡單來說,innobackupex 在 xtrabackup 之上做了一層封裝。一般情況下,我們是希望能備份 MyISAM 表的,雖然我們可能自己不用 MyISAM 表,但是 mysql 庫下的系統表是 MyISAM 的,因此備份基本都通過 innobackupex 命令進行;另外一個原因是我們可能需要保存位點信息。
  • xtrabackup 原理及實施
    Xtrabackup 必須持續的做這個操作,是因為事務日誌是會輪轉重複的寫入,並且事務日誌可以被重用。所以 xtrabackup 自啟動開始,就不停的將事務日誌中每個數據文件的修改都記錄下來。上面就是 xtrabackup 的備份過程。接下來是準備(prepare)過程。
  • 問題定位 | Peronca Xtrabackup 8.0近日踩坑總結 - xtrabackup 2.4和8.0區別
    xtrabackup 2.4和8.0區別google查到xtrabackup 8.0與2.4版本行為有所不同:Xtrabackup 2.4 備份後生成的 xtrabackup_binlog_info 文件記錄的 GTID 信息是準確的,但是備份恢復後 show master status 顯示的 GTID 是不準確的。
  • mysql資料庫之安裝、主從搭建、備份恢復
    使用xtrabackup備份和恢復資料庫:1. mysql-5.7.29資料庫安裝:  mysql資料庫安裝有多種方式,可以使用yum安裝,也可以編譯安裝,還有一種就是二進位安裝,不需要編譯。本文介紹的就是二進位的安裝方式。
  • MYSQL 增量恢復
    ,需要使用base,incr1,incr2三個備份都存在時,才能進行完整的恢復,每個備份的from_lsn都是基於上一個備份的to_lsn,所以缺一不可。incr1,incr2兩個備份中的其中一個,才能進行完整的恢復,因為incr1和incr2的from_lsn都是基於base備份中的to_lsn,所以恢復資料庫時,只需要base和任意一個基於base的增量備份。
  • 一、Percona-XtraBackup介紹
    然後將這些信息寫在一個位圖文件中。xtrabackup使用位圖文件來讀取增量備份所需的數據頁。Percona XtraBackup恢復原理xtrabackup可以通過使用xtrabackup --copy-back或xtrabackup --move-back
  • 如何讓xtrabackup恢復速度提升20倍?
    ,實時檢測mysql redo的變化,一旦發現redo中有新的日誌寫入,立刻將日誌記入後臺日誌文件xtrabackup_log中。  恢復階段則啟動xtrabackup內嵌的innodb實例,回放xtrabackup日誌xtrabackup_log,將提交的事務信息變更應用到innodb數據/表空間,同時回滾未提交的事務(這一過程類似innodb的實例恢復)。如圖所示:
  • 備份恢復,DBA最後一道防線,你完全掌握了嗎?
    最近項目碰到備份恢復的相關的事項,結合自己的經驗,鞏固一下知識。怎樣理解備份恢復MySQL使用環境中,基本都會搭建高可用架構最基本的主從,當主庫發生故障導致無法使用的時,可以切換從節點提供服務。那如果:這時可以通過之前備份+binglog進行恢復數據。備份的目的是發生災難時進行恢復。
  • Xtrabackup工作原理
    舊版本的Xtrabackup包含兩個主要的工具,xtrabackup和innobackupex。兩者的區別是:xtrabackup只能備份innodb和xtradb兩種引擎的表。innobackupex是一個封裝了xtrabackup的Perl腳本,支持同時備份innodb和MyISAM。
  • 除了mysqldump,還有更牛逼的備份工具嗎?
    之前文章中介紹過使用mysqldump命令進行mysql數據的簡單邏輯備份,這個工具簡單易用,但是功能不夠強大,對於增量備份和恢復,其實是不能友好支持的。本篇文章聊聊另外一個DBA常用的備份工具Xtrabackup。
  • 刪庫不跑路:詳解MySQL數據恢復
    2.直接恢復直接恢復是使用備份文件做全量恢復,這是最常見的場景2.1.mysqldump備份全量恢復使用 mysqldump 文件恢復數據非常簡單,直接解壓了執行gzip -d backup.sql.gz | mysql -u<user> -h<host> -P<port> -p2.2.xtrabackup
  • 詳解 MySQL 數據恢復
    2、直接恢復直接恢復是使用備份文件做全量恢復,這是最常見的場景。2.1 mysqldump 備份全量恢復使用 mysqldump 文件恢復數據非常簡單,直接解壓了執行:gzip -d backup.sql.gz | mysql -u<user> -h<host> -P<port> -p2.2
  • 誰說刪庫就要跑路來著,MySQL數據恢復了解一下
    如果 binlog 格式不為 row,那麼在誤操作數據後就沒有辦法做閃回操作,只能老老實實地走備份恢復流程。直接恢復是使用備份文件做全量恢復,這是最常見的場景。2.1 mysqldump 備份全量恢復使用 mysqldump 文件恢復數據非常簡單,直接解壓了執行:gzip -d backup.sql.gz | mysql -u<user> -h<host> -P<port>
  • 手把手教你MySQL數據恢復
    2.1 mysqldump 備份全量恢復使用 mysqldump 文件恢復數據非常簡單,直接解壓了執行:gzip -d backup.sql.gz | mysql -u<user> -h<host> -P<port> -p2.2