mysql和mariadb備份工具xtrabackup和mariabackup(mariadb上版本必須用這個)


簡介 

  xtraBackup(PXB) 工具是 Percona 公司用 perl 語言開發的一個用於 MySQL 數據庫物理熱備的備份工具,支持 MySQl(Oracle)、Percona Server 和 MariaDB,並且全部開源,真可謂是業界良心。阿里的 RDS MySQL 物理備份就是基於這個工具做的。由於是采取物理拷貝的方式來做的備份,所以速度非常快,幾十G數據幾分鍾就搞定了,而它巧妙的利用了mysql 特性做到了在線熱備份,不用像以前做物理備份那樣必須關閉數據庫才行,直接在線就能完成整庫或者是部分庫的全量備份和增量備份。新版本的xtrabackup改成了cmake安裝,和以前有點不一樣。

版本說明:這里安裝的版本是2.4.6,而2.3.3之后不備份死鎖了,如果數據庫是mysql 5.7之后的必須要裝2.4.4才可以用,當然了, 會向下兼容的。

bin/
├── innobackupex -> xtrabackup
├── xbcloud
├── xbcloud_osenv
├── xbcrypt
├── xbstream
└── xtrabackup 

  其中最主要的是 innobackupex 和 xtrabackup,前者是一個 perl 腳本,后者是 C/C++ 編譯的二進制。Percona 在2.3 版本用C重寫了 innobackupex ,innobackupex 功能全部集成到 xtrabackup 里面,只有一個 binary,另外為了使用上的兼容考慮,innobackupex 作為 xtrabackup 的一個軟鏈接。對於二次開發來說,2.3 擺脫了之前2個進程協作的負擔,架構上明顯要好於之前版本。(Percona XtraBackup 2.3 發布之后,推薦的備份方法是使用 xtrabackup 腳本。 )

xtrabackup 是用來備份 InnoDB 表的,不能備份非 InnoDB 表,和 mysqld server 沒有交互;innobackupex 腳本用來備份非 InnoDB 表,同時會調用 xtrabackup 命令來備份 InnoDB 表,還會和 mysqld server 發送命令進行交互,如加讀鎖(FTWRL)、獲取位點(SHOW SLAVE STATUS)等。簡單來說,innobackupex 在 xtrabackup 之上做了一層封裝。

一般情況下,我們是希望能備份 MyISAM 表的,雖然我們可能自己不用 MyISAM 表,但是 mysql 庫下的系統表是 MyISAM 的,因此備份基本都通過 innobackupex 命令進行;另外一個原因是我們可能需要保存位點信息。

另外幾個工具相對小眾些,xbcrypt 是加解密備份文件用的;xbstream 類似於tar,是 Percona 自己實現的一種支持並發寫的流文件格式;兩者在備份和解壓時都會用到(如果備份用了加密和並發)。xbcloud 工具的作用是:把全部或部分 xbstream 檔案從雲上下載或上傳到雲。

XtraBackup原理

  2.3版本之前 innobackupex 和 xtrabackup 這2個工具之間的交互和協調是通過控制文件的創建和刪除來實現的,2.3版本將 innobackupex 功能全部集成到 xtrabackup 里面,也就不需要他們之間的通信。這里介紹基於老的架構(2.2版本),但是原理和2.3是一樣的,只是實現上的差別。

PXB 備份過程

  1. innobackupex 在啟動后,會先 fork 一個進程,啟動 xtrabackup進程,然后就等待 xtrabackup 備份完 ibd 數據文件;
  2. xtrabackup 在備份 InnoDB 相關數據時,是有2種線程的,1種是 redo 拷貝線程,負責拷貝 redo 文件,1種是 ibd 拷貝線程,負責拷貝 ibd 文件;redo 拷貝線程只有一個,在 ibd 拷貝線程之前啟動,在 ibd 線程結束后結束。xtrabackup 進程開始執行后,先啟動 redo 拷貝線程,從最新的 checkpoint 點開始順序拷貝 redo 日志;然后再啟動 ibd 數據拷貝線程,在 xtrabackup 拷貝 ibd 過程中,innobackupex 進程一直處於等待狀態(等待文件被創建)。
  3. xtrabackup 拷貝完成idb后,通知 innobackupex(通過創建文件),同時自己進入等待(redo 線程仍然繼續拷貝);
  4. innobackupex 收到 xtrabackup 通知后,執行FLUSH TABLES WITH READ LOCK (FTWRL),取得一致性位點,然后開始備份非 InnoDB 文件(包括 frm、MYD、MYI、CSV、opt、par等)。拷貝非 InnoDB 文件過程中,因為數據庫處於全局只讀狀態,如果在業務的主庫備份的話,要特別小心,非 InnoDB 表(主要是MyISAM)比較多的話整庫只讀時間就會比較長,這個影響一定要評估到。
  5. 當 innobackupex 拷貝完所有非 InnoDB 表文件后,通知 xtrabackup(通過刪文件) ,同時自己進入等待(等待另一個文件被創建);
  6. xtrabackup 收到 innobackupex 備份完非 InnoDB 通知后,就停止 redo 拷貝線程,然后通知 innobackupex redo log 拷貝完成(通過創建文件);
  7. innobackupex 收到 redo 備份完成通知后,就開始解鎖,執行 UNLOCK TABLES;
  8. 最后 innobackupex 和 xtrabackup 進程各自完成收尾工作,如資源的釋放、寫備份元數據信息等,innobackupex 等待 xtrabackup 子進程結束后退出。

在上面描述的文件拷貝,都是備份進程直接通過操作系統讀取數據文件的,只在執行 SQL 命令時和數據庫有交互,基本不影響數據庫的運行,在備份非 InnoDB 時會有一段時間只讀(如果沒有MyISAM表的話,只讀時間在幾秒左右),在備份 InnoDB 數據文件時,對數據庫完全沒有影響,是真正的熱備。

InnoDB 和非 InnoDB 文件的備份都是通過拷貝文件來做的,但是實現的方式不同,前者是以page為粒度做的(xtrabackup),后者是 cp 或者 tar 命令(innobackupex),xtrabackup 在讀取每個page時會校驗 checksum 值,保證數據塊是一致的,而 innobackupex 在 cp MyISAM 文件時已經做了flush(FTWRL),磁盤上的文件也是完整的,所以最終備份集里的數據文件都是寫入完整的。

增量備份

PXB 是支持增量備份的,但是只能對 InnoDB 做增量,InnoDB 每個 page 有個 LSN 號,LSN 是全局遞增的,page 被更改時會記錄當前的 LSN 號,page中的 LSN 越大,說明當前page越新(最近被更新)。每次備份會記錄當前備份到的LSN(xtrabackup_checkpoints 文件中),增量備份就是只拷貝LSN大於上次備份的page,比上次備份小的跳過,每個ibd文件最終備份出來的是增量 delta 文件。

MyISAM 是沒有增量的機制的,每次增量備份都是全部拷貝的。

增量備份過程和全量備份一樣,只是在 ibd 文件拷貝上有不同。

恢復過程

如果看恢復備份集的日志,會發現和 mysqld 啟動時非常相似,其實備份集的恢復就是類似 mysqld crash后,做一次 crash recover。

恢復的目的是把備份集中的數據恢復到一個一致性位點,所謂一致就是指原數據庫某一時間點各引擎數據的狀態,比如 MyISAM 中的數據對應的是 15:00 時間點的,InnoDB 中的數據對應的是 15:20 的,這種狀態的數據就是不一致的。PXB 備份集對應的一致點,就是備份時FTWRL的時間點,恢復出來的數據,就對應原數據庫FTWRL時的狀態。

因為備份時 FTWRL 后,數據庫是處於只讀的,非 InnoDB 數據是在持有全局讀鎖情況下拷貝的,所以非 InnoDB 數據本身就對應 FTWRL 時間點;InnoDB 的 ibd 文件拷貝是在 FTWRL 前做的,拷貝出來的不同 ibd 文件最后更新時間點是不一樣的,這種狀態的 ibd 文件是不能直接用的,但是 redo log 是從備份開始一直持續拷貝的,最后的 redo 日志點是在持有 FTWRL 后取得的,所以最終通過 redo 應用后的 ibd 數據時間點也是和 FTWRL 一致的。

所以恢復過程只涉及 InnoDB 文件的恢復,非 InnoDB 數據是不動的。備份恢復完成后,就可以把數據文件拷貝到對應的目錄,然后通過mysqld來啟動了。

查看數據庫支持引擎(mysql和mariadb默認是Innodb引擎):

show engines;

查看數據庫表支持的引擎

show create table table_name; 

安裝

1、下載地址

  你可以根據自己的需求選擇不同的操作系統和版本(我這里是用最新的版本)

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.11/binary/tarball/percona-xtrabackup-2.4.11-Linux-x86_64.libgcrypt145.tar.gz

2、加壓縮后,mv更改目錄名為xtrabackup,然后加入環境變量方便使用。

export PATH=$PATH:/root/xtrabackup/bin/
source /etc/profile

完整備份

   xtrabackup選項

  xtrabackup 工具有許多參數,具體可去官網查詢(xtrabackup 參數選項 | innobackupex 參數選項),這里簡單介紹 innobackupex 一些常用的參數。

  1) innobackupex 參數選項

  --defaults-file=[MY.CNF]    //指定配置文件:只能從給定的文件中讀取默認選項。 且必須作為命令行上的第一個選項;必須是一個真實的文件,它不能是一個符號鏈接。

  --databases=#    //指定備份的數據庫和表,格式為:--database="db1[.tb1] db2[.tb2]" 多個庫之間以空格隔開,如果此選項不被指定,將會備份所有的數據庫。

  --include=REGEXP    //用正則表達式的方式指定要備份的數據庫和表,格式為 --include=‘^mydb[.]mytb’ ,對每個庫中的每個表逐一匹配,因此會創建所有的庫,不過是空的目錄。--include 傳遞給 xtrabackup --tables。

  --tables-file=FILE    //此選項的參數需要是一個文件名,此文件中每行包含一個要備份的表的完整名稱,格式為databasename.tablename。該選項傳遞給 xtrabackup --tables-file,與--tables選項不同,只有要備份的表的庫才會被創建。

  注意:部分備份(--include、--tables-file、--database)需要開啟 innodb_file_per_table 。

  --compact    //創建緊湊型備份,忽略所有輔助索引頁,只備份data page;通過--apply-log中重建索引--rebuild-indexs。

  --compress    //此選項指示xtrabackup壓縮備份的InnoDB數據文件,會生成 *.qp 文件。

  --decompress    //解壓縮qp文件,為了解壓縮,必須安裝 qpress 工具。 Percona XtraBackup不會自動刪除壓縮文件,為了清理備份目錄,用戶應手動刪除 * .qp文件:find /data/backup -name "*.qp" | xargs rm。

  --no-timestamp    //指定了這個選項備份將會直接存儲在 BACKUP-DIR 目錄,不再創建時間戳文件夾。

  --apply-log    //應用 BACKUP-DIR 中的 xtrabackup_logfile 事務日志文件。一般情況下,在備份完成后,數據尚且不能用於恢復操作,因為備份的數據中可能會包含尚未提交的事務或已經提交但尚未同步至數據文件中的事務。因此,此時數據文件仍處於不一致狀態。“准備”的主要作用正是通過回滾未提交的事務及同步已經提交的事務至數據文件使得數據文件處於一致性狀態。

  --use-memory=#    //此選項接受一個字符參數(1M/1MB,1G/1GB,默認100M),僅與--apply-log一起使用,該選項指定prepare時用於崩潰恢復(crash-recovery)的內存。

  --copy-back    //拷貝先前備份所有文件到它們的原始路徑。但原路徑下不能有任何文件或目錄,除非指定 --force-non-empty-directories 選項。

  --force-non-empty-directories    //恢復時指定此選項,可使 --copy-back 和 --move-back 復制文件到非空目錄,即原data目錄下可以有其他文件,但是不能有與恢復文件中同名的文件,否則恢復失敗。

  --rsync    //此選項可優化本地文件(非InnoDB)的傳輸。rsync工具一次性拷貝所有非InnoDB文件,而不是為每個文件單獨創建cp,在備份恢復很多數據庫和表時非常高效。此選項不能和 --stream 一起使用。

  --incremental    //這個選項告訴 xtrabackup 創建一個增量備份,而不是完全備份。它傳遞到 xtrabackup 子進程。當指定這個選項,可以設置 --incremental-lsn 或 --incremental-basedir。如果這2個選項都沒有被指定,--incremental-basedir 傳遞給 xtrabackup 默認值,默認值為:基礎備份目錄的第一個時間戳備份目錄。

  --incremental-basedir=DIRECTORY    //該選項接受一個字符串參數,該參數指定作為增量備份的基本數據集的完整備份目錄。它與 --incremental 一起使用。

  --incremental-dir=DIRECTORY    //該選項接受一個字符串參數,該參數指定了增量備份將與完整備份相結合的目錄,以便進行新的完整備份。它與 --incremental 選項一起使用。

  --redo-only    //在“准備基本完整備份” 和 “合並所有的增量備份(除了最后一個增備)”時使用此選項。它直接傳遞給xtrabackup的 xtrabackup --apply-log-only 選項,使xtrabackup跳過"undo"階段,只做"redo"操作。如果后面還有增量備份應用到這個全備,這是必要的。有關詳細信息,請參閱xtrabackup文檔。

  --parallel=NUMBER-OF-THREADS    //此選項接受一個整數參數,指定xtrabackup子進程應用於同時備份文件的線程數。請注意,此選項僅適用於文件級別,也就是說,如果您有多個.ibd文件,則它們將被並行復制; 如果您的表一起存儲在一個表空間文件中,它將不起作用。

  2) xtrabackup 參數選項

  --apply-log-only    //這個選項使在准備備份(prepare)時,只執行重做(redo)階段,這對於增量備份非常重要

 

  這里這用的是centos7.4.x和5.5.56-MariaDB MariaDB Server,這里以zabbix數據庫備份為背景。

3、創建備份的目錄

mkdir -p /data/mysql

4、進行完整備份

innobackupex --defaults-file=/etc/my.cnf --user=root  --password=123456 --socket=/var/lib/mysql/mysql.sock  /data/root

5、查看備份目錄(連接數據庫,開始拷貝redo log,拷貝innodb表文件,鎖表、拷貝非innodb表文件,停止拷貝redo log,解鎖。)

  其中zabbix和test、mysql、performance_schema都是已經備份的數據庫,backup-my.cnf是備份的my.cnf配置文件。

xtrabackup_checkpoints:備份類型(如完全或增量)、備份狀態(如是否已經為prepared狀態)和LSN(日志序列號)范圍信息;

 xtrabackup_info:記錄備份的基本信息,uuid、備份命令、備份時間、binlog、LSN、以及其他加密壓縮等信息。

xtrabackup_logfile:備份的重做日志文件。

 6、全盤恢復

   6.1首先停止數據庫服務,並准備好數據的恢復目錄(為了不覆蓋原有的數據,建議重新找個位置存放數據庫文件,我這里是默認的/var/lib/mysql/),

systemctl stop mariadb

  6.2准備(prepare)一個完全備份: --apply-log ( /data/root/2018-05-09_01-28-45/ 為備份目錄,執行之后 xtrabackup_checkpoints 文件中的 backup_type = full-prepared )

[root@bogon root]# innobackupex --apply-log /data/root/2018-05-09_01-28-45/

  6.3執行恢復操作:

innobackupex  --defaults-file=/etc/my.cnf --copy-back --rsync /data/root/2018-05-09_01-28-45/

  提示我們這個說原來數據庫存放目錄是不是空的(它其實說不讓我們在原來的數據庫目錄恢復,要不你換地方,要不你刪除原來所有的數據庫文件,我這里為了防止意外,就換個地方)

  

  首先,我們得修改my.cnf配置文件中數據庫存放位置的路徑,更改后的目錄是我們剛才新建的目錄。

  

  再此執行恢復操作,提示OK。

  

  6.4、剛才我們停止了mariadb服務,現在我們除了要開啟數據庫服務外,還得給新的mysql目錄所有文件mysql用的屬主和屬組的權限。

[root@bogon root]# chown -R mysql.mysql /data/mysql
[root@bogon root]# systemctl start mariadb

  測試,我們最開始備份了所有所有數據庫(備份完成后,我刪除了zabbix配置里面的幾個監控項,當恢復完成后原來的監控項都已經恢復)

增量備份、恢復

   注意、只有InnoDB引擎支持增量備份,MyISAM只支持完整備份。

  1、首先我們要對數據庫進行一個全備。

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock --no-timestamp /data/backup/all_backup

  2、然后我們修改數據庫操作,再進行第一次增量備份。注意,--incremental-basedir=指的是對誰進行增量備份,這里我們是第一次增量備份,所以這里指的應該是全備。

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock  --no-timestamp --incremental /data/backup/incremental-dir-1 --incremental-basedir=/data/backup/all_backup/

  3、然后我們再對數據庫進行修改,再進行第二次增量備份。這里我們增量的部分是相對第一次增量備份到第二次增量備份的差異部分,所以這里--incremental-basedir=應該是指的第一次增量備份incremental-dir-1

innobackupex -uroot -p123456 --no-timestamp --socket=/var/lib/mysql/mysql.sock  --incremental /data/backup/incremental-dir-2/  --incremental-basedir=/data/backup/incremental-dir-1/

  4、上面我們對數據庫進行了兩次不同的修改,也做了兩次增量,下面我們來看增量備份的恢復方法(為了試驗效果明顯,我這里刪除了兩次增量備份增加的部分)。首先我們要准備一個完整備份(全備)

innobackupex --apply-log --redo-only /data/backup/all_backup/

  5、然后恢復第一次增量備份恢復,注意:只要不是最后一次增量備份的恢復,都需要加上--redo-only參數。

innobackupex --apply-log --redo-only /data/backup/all_backup/  --incremental-dir=/data/backup/incremental-dir-1

  6、第二次增量備份的恢復,這里是最后一次增量備份的恢復,所以不用加--redo-only參數。

innobackupex --apply-log /data/backup/all_backup/  --incremental-dir=/data/backup/incremental-dir-2

  7、將兩次增量備份,合並到完整備份中(合並完成后,跟完整備份的恢復方法一樣)

innobackupex --apply-log /data/backup/all_backup/

  8、為了數據一致性,先停止mariadb數據庫服務。這里我們的數據庫文件目錄是/var/lib/mysql下,我給他換個位置到/data/mysql(你也可以直接mv  /var/lib/mysql  var/lib/mysql.bak,然后再新建一個mysql目錄),記得要修改/etc/my.cnf文件中datadir=路徑。

mkdir -p /data/mysql

  9、恢復的目錄有了,我們下面開始恢復,想到與被上面合成到一起的增量備份文件copy到/data/mysql/這個目錄下。

innobackupex --copy-back /data/backup/all_backup/

  10、只恢復文件還不行,這會兒/data/mysql/下的文件(包含一級目錄都是屬主和屬組都是root,,我們需要給mysql權限)

chown mysql:mysql -R /data/mysql/

  11、啟動數據庫服務,增量備份的備份和恢復完整。

systemctl restart  mariadb

差異備份、恢復(建議使用)

   增量備份的優缺點:

  1、上面我們說了xtrabackup的增量備份和恢復,增量備份有它的好處,就是每次進行相對上次備份有不同的地方進行備份,但是中間如果哪個備份掛了(丟失了),那就沒法恢復了,而且增量備份一般都是每間隔幾個小時備份一次(最次也得每天進行一次增量備份)。恢復起來其實是很麻煩的,可能需要你恢復的時候,增量備份已經好幾百個了,除非你寫腳本,否則個人感覺很麻煩的。

  2、我們知道增量備份的時候有個參數--incremental-dir=,它的意思是根據之前的哪次備份進行差異性備份,以前增量情況是首先一個全備,第一次增量的做法是根據全備進行備份,第二次增量備份的做法是根據第一次增量備份進行備份,依次類推。很麻煩。

  3、既然可以指定根據哪次做增量備份,我們就直接每次根據完整備份進行增量備份----差異備份。這樣做的好處是恢復時候只需要恢復最后一次增量備份就行,缺點是我們每次都是根據完整備份進行備份,長時間下去會占用空間很大。

備份:

1、首先進行一次完整備份

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock --no-timestamp /data/backup/all_backup

2、第一次次增量備份

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock  --no-timestamp --incremental /data/backup/incremental-dir-1 --incremental-basedir=/data/backup/all_backup/

3、第二次增量備份

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock  --no-timestamp --incremental /data/backup/incremental-dir-2 --incremental-basedir=/data/backup/all_backup/

4、第三次增量備份

innobackupex -uroot -p123456 --socket=/var/lib/mysql/mysql.sock  --no-timestamp --incremental /data/backup/incremental-dir-3 --incremental-basedir=/data/backup/all_backup/

注意,上面我們每次備份都是根據完整備份進行增量備份的。

恢復:

1、首先准備一個全備

innobackupex --apply-log --redo-only /data/backup/all_backup/

2、恢復最后一次備份,這里恢復是肯定最后一次恢復,所以不用加--redo-only參數

innobackupex --apply-log /data/backup/all_backup/  --incremental-dir=/data/backup/incremental-dir-3

3、將增量備份合並到完整備份中。

innobackupex --apply-log /data/backup/all_backup/

4、為了數據一致性,先停止mariadb數據庫服務。這里我們的數據庫文件目錄是/var/lib/mysql下,我給他換個位置到/data/mysql(你也可以直接mv  /var/lib/mysql  var/lib/mysql.bak,然后再新建一個mysql目錄),記得要修改/etc/my.cnf文件中datadir=路徑。

mkdir -p /data/mysql

5、恢復的目錄有了,我們下面開始恢復,想到與被上面合成到一起的增量備份文件copy到/data/mysql/這個目錄下。

innobackupex --copy-back /data/backup/all_backup/

6、只恢復文件還不行,這會兒/data/mysql/下的文件(包含一級目錄都是屬主和屬組都是root,,我們需要給mysql權限)

chown mysql:mysql -R /data/mysql/

7、啟動數據庫服務,增量備份的備份和恢復完整。

systemctl restart  mariadb

注意:

  1、完整備份需要備份到另外一個位置,如果你恢復失敗的,你的完整備份里面的參數也會跟着改變了,這個時候需要再恢復就困難了。相反我只需要把完整備份的備份cp到完整備份的目錄里面就OK了,可以接着折騰了。

  2、如果你不備份你的完整備份,一旦恢復失敗,想要重新恢復,那你就等着哭吧。

參考與:https://www.linuxidc.com/Linux/2017-03/142380.htm

 

mariadb10.1以上版本使用的是mariabackup這個備份工具,而不是 xtrabackup,mariabackup是要單獨安裝的。安裝完后按照一下步驟操作:

yum -y  install MariaDB-backup

  

源服務器:

  注意:這里如果你備份的是10.3的版本數據庫,一定要以10.3版本的數據恢復,否則將無法恢復,親測,10.3.8的版本文件無法在10.1.34上無法恢復。

1、源服務器創建一個備份的目標目錄,例如mkdir var/databasebackup,附加讀寫權限;

2、用mariabackup --backup --target-dir /data/mysqlbak --user username --password userpassword ,備份的是服務器上所有數據庫,當然你也可以加參數--databases來指定要備份數據庫;

目標服務器:

1、同樣建立一個還原的目標目錄,例如mkdir /data/mysqlbak,附加讀寫權限;

2、把源服務器上備份的數據庫文件拷貝到目標服務器/data/mysqlbak下;

3、先用mariabackup --prepare --target-dir /data/mysqlbak --user username --password userpassword,將備份文件規范化,這里可以獲得備份文件的備份log節點,有助於主從同步使用,假如你有主從同步的話;

4、用 mariabackup --copy-back --target-dir /data/mysqlbak --user username --password userpassword ,來還原數據庫;(記住在還原前清掉數據庫目錄)

5、將數據庫文件附上數據庫權限,chown -R mysql:mysql /var/lib/mysql

6、重啟服務器systemctl restart mysql。

 https://blog.csdn.net/qooer_tech/article/details/80811615


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM