一、基礎知識
1.1 mysql邏輯備份與實體備份的差別
MySQL 備份通常分為兩種類型:邏輯備份和實體備份。這兩種備份方法各有優缺點,适用于不同的場景。
邏輯備份:
邏輯備份是從資料庫中導出資料和結構的 SQL 語句。這種備份通常使用 mysqldump 工具來完成。邏輯備份的主要優點是它具有較高的可移植性,可以在不同架構和版本的 MySQL 伺服器上還原。但是,邏輯備份可能需要更長的時間來完成,特别是在處理大型資料庫時。
邏輯備份的主要特點:
- 生成的備份檔案是文本檔案,包含 SQL 語句。
- 備份和恢複速度相對較慢。
- 可移植性好,可以在不同版本和架構的 MySQL 伺服器上使用。
- 可以選擇性地備份和恢複特定的資料庫、表或記錄。
實體備份:
實體備份是直接複制資料庫的資料檔案、索引檔案和日志檔案。這種備份方法通常使用檔案系統快照或第三方工具(如 Percona XtraBackup)來完成。實體備份的主要優點是它通常更快,因為它不需要轉換資料。然而,實體備份可能不如邏輯備份可移植,因為它依賴于特定的檔案系統和作業系統。
實體備份的主要特點:
- 生成的備份檔案是二進制檔案,包含資料庫的實際資料檔案、索引檔案和日志檔案。
- 備份和恢複速度相對較快。
- 可移植性較差,通常隻能在相同版本和架構的 MySQL 伺服器上使用。
- 通常需要停止資料庫或在讀鎖模式下進行備份,以確定資料的一緻性。
總之,邏輯備份和實體備份有各自的優缺點,根據不同的應用場景和需求來選擇合适的備份方法。
今天我們分享的主角就是大名鼎鼎的mysql實體備份神器-Percona XtraBackup
二、Percona XtraBackup的安裝
2.1 環境描述
- 作業系統版本:CENTOS 7.9
- MYSQL資料庫版本:5.7
- 資料庫執行個體端口:3307
2.2 安裝過程
1、安裝yum源
yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm
2、安裝XtraBackup 2.4版本的percona-xtrabackup
安裝mysql對應版本的xtrabackup,不同伺服器安裝不同的版本
- mysql 5.1 – xtrabackup2.0
- mysql5.6 –xtrabackup 2.2
- mysql5.7 –xtrabackup2.4
yum install -y percona-xtrabackup-24.x86_64
3、常用參數說明
--defaults-file
同xtrabackup的--defaults-file參數
--apply-log
在備份目錄下,通過應用名稱為xtrabackup_logfile的交易日志檔案來準備備份。同時,建立新的交易日志。
--copy-back
做資料恢複時将備份資料檔案拷貝到MySQL伺服器的datadir ;
--remote-host=HOSTNAME
通過ssh将備份資料存儲到程序伺服器上;
--stream=[tar]
備 份檔案輸出格式, tar時使用tar4ibd , 該檔案可在XtarBackup binary檔案中獲得.如果備份時有指定--stream=tar, 則tar4ibd檔案所處目錄一定要在$PATH中(因為使用的是tar4ibd去壓縮, 在XtraBackup的binary包中可獲得該檔案)。
在 使用參數stream=tar備份的時候,你的xtrabackup_logfile可能會臨時放在/tmp目錄下,如果你備份的時候并發寫入較大的話 xtrabackup_logfile可能會很大(5G+),很可能會撐滿你的/tmp目錄,可以通過參數--tmpdir指定目錄來解決這個問題。
--tmpdir=DIRECTORY
當有指定--remote-host or --stream時, 事務日志臨時存儲的目錄, 預設采用MySQL配置檔案中所指定的臨時目錄tmpdir
--redo-only --apply-log組,
強制備份日志時隻redo ,跳過rollback。這在做多個增量備份合并時非常必要。
--use-memory=#
指定資料庫恢複時使用的記憶體大小,需要搭配--apply-log參數
--throttle=IOS
同xtrabackup的--throttle參數
--sleep=是給ibbackup使用的,指定每備份1M資料,過程停止拷貝多少毫秒,也是為了在備份時盡量減小對正常業務的影響,具體可以檢視ibbackup的手冊 ;
--compress[=LEVEL]
對備份資料迚行壓縮,僅支援ibbackup,xtrabackup還沒有實作;
--include=REGEXP
對 xtrabackup參數--tables的封裝,也支援ibbackup。備份包含的庫表,例如:--include="test.*",意思是要備份 test庫中所有的表。如果需要全備份,則省略這個參數;如果需要備份test庫下的2個表:test1和test2,則寫 成:--include="test.test1|test.test2"。也可以使用通配符,如:--include="test.test*"。
--databases=LIST
列出需要備份的databases,如果沒有指定該參數,所有包含MyISAM和InnoDB表的database都會被備份;
--uncompress
解壓備份的資料檔案,支援ibbackup,xtrabackup還沒有實作該功能;
--slave-info,
當備份一個作為複制環境的伺服器時,這個參數會自動将CHANGE MASTER語句寫到備份中,在恢複備份後,不必執行CHANGE MASTER語句。
--socket=SOCKET
指定mysql.sock所在位置,以便備份程序登入mysql.
--compact
建立一個不包含第二索引(除了主鍵之外的索引)的備份
--incremental-basedir
以上一次全量或增量備份的路徑,作為增量備份的基礎。指定這個參數的同時,應該同樣指定--incremental參數
--incremental
建立增量備份,當指定這個參數的時候,應該指定--incremental-lsn或--incremental-basedir參數,否則将會備份到--incremental-basedir路徑
--incremental-dir=DIRECTORY
指定增量備份的目錄,需要搭配--incremental參數。
--no-timestamp
這個參數會讓xtrabackup在備份的時候不建立帶有時間格式的子檔案夾。當指定了這個參數,備份會直接建立在指定的備份目錄下。
--tables-file=FILE
這個參數會接受一個字元串,這個字元串指定了一個檔案,這個檔案包含了要備份的表名,格式如database.table,一行一個。
--use-memory=# -apply-log 調節記憶體使用
--parallel= 多線程拷貝資料檔案,使用該參數要考慮線上的資料庫的壓力的問題,如果線程開啟較多,會對硬碟産生交大的壓力。
三、 備份與恢複過程
備份目錄:/backup/mysql
3.1 全量備份與恢複
全量備份
innobackupex --defaults-file=/etc/my3307.cnf --host=localhost --port=3307 -S /tmp/mysql.sock --user=root --password='Rootasdf2023' --no-timestamp /backup/mysql/full_`date +%Y-%m-%d_%H-%M-%S_%w`
全量恢複
1、删庫并停止資料庫
service mysqld stop
2、備份myql資料目錄
cp -rpf /data/3307/data /data/3307/data_bak
3、日志包含了redo以及undo的操作,應用過程類似與mysql hang機後的recovery操作,完成後備份處于一緻性狀态
innobackupex --apply-log /backup/mysql/full_2023-05-10_14-08-36_3
4、拷貝備份資料至my.cnf檔案規定的位置
innobackupex --defaults-file=/etc/my3307.cnf --copy-back --rsync /backup/mysql/full_2023-05-10_14-08-36_3
5、更改mysql資料目錄的權限為mysql
chown -R mysql:mysql /data/3307/data
6、啟動資料庫,至此資料恢複完成
/etc/init.d/mysql3307 start
3.2 增量備份與恢複
3.2.1 增量備份原理
增量備份有兩種方法:
方法一:針對全量的basedir做增量
總是針對全量的basedir做增量,這個方式恢複起來就特别簡單了,隻需要将最後一次的增量備份合并到全量備份裡,就可以恢複了。
第一種方法示例圖: 總是将1月1日的全備作為basedir,是以FROM_LSN号總是5000。
方法二:總是針對上一次增量,做增量備份
總是針對上一次的增量,做增量備份。這個方式的恢複,就要逐一合并了。總是把上一次(最近一次)的備份作為basedir
方法二示意圖:
下面介紹的方法是針對第二種的。
3.2.2 增量恢複實驗過程
1、先來一次全備,兩次增備
#全備
innobackupex --defaults-file=/etc/my3307.cnf --host=localhost --port=3307 -S /tmp/mysql.sock --user=root --password='Rootasdf2023' --no-timestamp /backup/mysql/full_`date +%Y-%m-%d_%H-%M-%S_%w`
#第一次增備
innobackupex --defaults-file=/etc/my3307.cnf --host=localhost --port=3307 -S /tmp/mysql.sock --user=root --password='Rootasdf2023' --no-timestamp --incremental-basedir=/backup/mysql/full_2023-05-10_14-08-36_3 --incremental /backup/mysql/incr_`date +%Y-%m-%d_%H-%M-%S_%w`
#第二次增備
innobackupex --defaults-file=/etc/my3307.cnf --host=localhost --port=3307 -S /tmp/mysql.sock --user=root --password='Rootasdf2023' --no-timestamp --incremental-basedir=/backup/mysql/incr_2023-05-10_14-11-28_3 --incremental /backup/mysql/incr_`date +%Y-%m-%d_%H-%M-%S_%w`
#備份檔案檢視
[root@mysqlserver mysql]# ls -l /backup/mysql/
total 4
drwxr-x--- 7 root root 4096 May 10 14:15 full_2023-05-10_14-08-36_3
drwxr-x--- 7 root root 318 May 10 14:11 incr_2023-05-10_14-11-28_3
drwxr-x--- 7 root root 318 May 10 14:14 incr_2023-05-10_14-13-17_3
[root@mysqlserver mysql]#
2、prepare準備過程
這就是增量備份最麻煩的地方,因為總共做了三次備份,是以先做三次prepare
(1)對全備做prepare:
innobackupex --apply-log --redo-only /backup/mysql/full_2023-05-10_14-08-36_3
(2)對第一次增量prepare:
innobackupex --apply-log --redo-only /backup/mysql/full_2023-05-10_14-08-36_3 --incremental-dir=/backup/mysql/incr_2023-05-10_14-11-28_3
(3)對第二次增量prepare:
注意,第二次的增備是最後一次,是以不需要加上–redo-only參數:
innobackupex --apply-log /backup/mysql/full_2023-05-10_14-08-36_3 --incremental-dir=/backup/mysql/incr_2023-05-10_14-13-17_3
(4)最後一步将兩次增量備份和全量做一次合并
innobackupex --apply-log /backup/mysql/full_2023-05-10_14-08-36_3
3、恢複資料
(1) 停止mysql服務
/etc/init.d/mysql3307 stop
(2)模拟删除庫(删除之前先備份一下目錄 )
rm -rf /data/3307/data
(3)恢複資料
innobackupex --defaults-file=/etc/my3307.cnf --copy-back --rsync /backup/mysql/full_2023-05-10_14-08-36_3
(4)修改權限
chown -R mysql:mysql /data/3307/data
(5)啟動資料庫,驗證相關資料
/etc/init.d/mysql3307 start
四、常見問題彙總
問題1:
恢複時報Xtrabackup –copy-back fail Can’t create/write to file ‘./undo_001’
解決方法:
/etc/my.cnf配置檔案中注釋掉如下代碼:
#innodb_undo_directory=.