XtraBackup是由Percona提供的开源备份软件。它能在不关闭服务器的情况下复制普通文件。但为了避免不一致,它会使用redo日志文件。XtraBackup被许多公司广泛用做标准备份工具。与逻辑备份工具相比,其优势是备份速度非常快,恢复速度也非常快。
Percona XtraBackup的工作原理:
-
XtraBackup复制InnoDB数据文件,这会导致内部不一致的数据,但是它会对文件执行崩溃恢复,以使其再次成为一个一致的可用数据库
-
这样做的可行性是因为InnoDB维护一个REDO日志,也称为事务日志。REDO日志包含了InnoDB数据每次更改的记录。当InnoDB启动时,REDO日志会检查数据文件和事务日志,并执行两个步骤。它将已提交的事务日志条目应用于数据文件,并对任何修改了数据但未提交的事务执行undo操作
-
Percona XtraBackup会在启动时记住日志序列号(LSN),然后复制数据文件。这需要一些时间来完成,如果文件正在改变,那么它会在不同的时间点反映数据库的状态。同时,Percona XtraBackup运行一个后台进程,用于监视事务日志文件,并从中复制更改。Percona XtraBackup需要持续这样做,因为事务日志是以循环方式写入的,并且可以在一段时间后重新使用。Percona XtraBackup开始执行后,需要复制每次数据文件更改对应的事务日志记录。
安装
- 下载rpm包
[root@mysql ~]# wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-8.0.4/binary/redhat/7/x86_64/percona-xtrabackup-80-8.0.4-1.el7.x86_64.rpm
[root@mysql ~]# yum localinstall percona-xtrabackup-80-8.0.4-1.el7.x86_64.rpm
权限
如果需要创建专门的用户去执行备份恢复操作,需要选项如下:
mysql> CREATE USER 'bkpuser'@'localhost' IDENTIFIED BY 's3cr%T';
mysql> GRANT BACKUP_ADMIN, SUPER, PROCESS, CREATE TABLESPACE, RELOAD, LOCK TABLES, REPLICATION CLIENT ON TO 'bkpuser'@'localhost';
mysql> GRANT SELECT, INSERT, CREATE ON performance_schema. TO 'bkpuser'@'localhost';
mysql> FLUSH PRIVILEGES;
备份和恢复
全量备份
在XtraBackup8中移除了innobackupex命令。
由于新的MySQL重做日志和数据字典格式,8.0版本只支持mysql8.0和percona8.0。
早于mysql8.0的版本需要使用xtrabackup2.4备份和恢复
- 备份命令
xtrabackup --user=root --backup --socket=/tmp/mysql.sock --target-dir=/xtrabackup
全量恢复
- 停止数据库
[root@oracle data]# service mysqld stop
Shutting down MySQL.. SUCCESS!
-
删除现有的data目录
rm -rf /usr/local/mysql/data/*
-
执行恢复命令
[root@oracle data]# xtrabackup --prepare --target-dir=/xtrabackup/
[root@oracle data]# xtrabackup --copy-back --target-dir=/xtrabackup/
[root@oracle data]# chwon -R mysql.mysql /usr/local/mysql/data/*
Tips:
--copy-back
命令表示将备份 复制 到datadir目录下,如果不想保留备份,可以使用--move-back命令,直接将备份移动到datadir目录下
增量备份
在进行增量备份之前,通过先进行一次全量备份。XtraBackup通过二进制方式在备份目录下写入xtrabackup_checkpoints文件。该文件其中一行会显示to_lsn,
该参数记录了数据库备份完成的LSN。全量备份命令:
方式一
- 基于base的备份
[root@oracle xtrabackup]# xtrabackup --user=root --backup --socket=/tmp/mysql.sock --target-dir=/xtrabackup/base
xtrabackup_checkpoints的内容:
[root@oracle xtrabackup]# cat /xtrabackup/base/xtrabackup_checkpoints
backup_type = **full-backuped**
from_lsn = 0
to_lsn = **19957274**
last_lsn = 19957284
flushed_lsn = 0
在进行了全量备份后 ,我们可以通过增量备份的命令进行备份:
- 基于base的incr1备份:
[root@oracle xtrabackup]# xtrabackup --user=root --backup --socket=/tmp/mysql.sock --target-dir=/xtrabackup/incr1 --incremental-basedir=/xtrabackup/base
xtrabackup_checkpoints的内容:
[root@oracle xtrabackup]# cat /xtrabackup/incr1/xtrabackup_checkpoints
backup_type = **incremental**
from_lsn = **19957274**
to_lsn = 19957304
last_lsn = 19957314
flushed_lsn = 0
- 基于incr1的incr2备份
[root@oracle xtrabackup]# xtrabackup --user=root --backup --socket=/tmp/mysql.sock --target-dir=/xtrabackup/incr2 --incremental-basedir=/xtrabackup/incr1/
xtrabackup_checkpoints的内容:
[root@oracle xtrabackup]# cat /xtrabackup/incr2/xtrabackup_checkpoints
backup_type = **incremental**
from_lsn = **19957304**
to_lsn = 19957364
last_lsn = 19957374
flushed_lsn = 0
结论:假设周一是基于base的备份,周二是基于base的incr1备份,周三是基于incr1的incr2备份,在恢复数据库的时候,需要使用base,incr1,incr2三个备份都存在时,才能进行完整的恢复,每个备份的from_lsn都是基于上一个备份的to_lsn,所以缺一不可。
方式二
- 基于base的备份
[root@oracle xtrabackup]# xtrabackup --user=root --backup --socket=/tmp/mysql.sock --target-dir=/xtrabackup/base
xtrabackup_checkpoints的内容:
[root@oracle xtrabackup]# cat /xtrabackup/base/xtrabackup_checkpoints
backup_type = **full-backuped**
from_lsn = 0
to_lsn = **19957274**
last_lsn = 19957284
flushed_lsn = 0
- 基于base的incr1备份
[root@oracle xtrabackup]# xtrabackup --user=root --backup --socket=/tmp/mysql.sock --target-dir=/xtrabackup/incr1 --incremental-basedir= /xtrabackup/base
xtrabackup_checkpoints的内容:
[root@oracle xtrabackup]# cat /xtrabackup/incr1/xtrabackup_checkpoints
backup_type = **incremental**
from_lsn = **19957274**
to_lsn = 19957304
last_lsn = 19957314
flushed_lsn = 0
- 基于base的incr2备份
[root@oracle xtrabackup]# xtrabackup --user=root --backup --socket=/tmp/mysql.sock --target-dir=/xtrabackup/incr2 --incremental-basedir= /xtrabackup/base/
xtrabackup_checkpoints的内容:
[root@oracle xtrabackup]# cat /xtrabackup/incr2/xtrabackup_checkpoints
backup_type = **incremental**
from_lsn = **19957274**
to_lsn = 19957394
last_lsn = 19957404
flushed_lsn = 0
结论:假设周一是基于base的备份,周二是基于base的incr1备份,周三是基于base的incr2备份,在恢复数据库的时候,需要使用base和incr1,incr2两个备份中的其中一个,才能进行完整的恢复,因为incr1和incr2的from_lsn都是基于base备份中的to_lsn,所以恢复数据库时,只需要base和任意一个基于base的增量备份。
增量备份恢复
增量备份和全量备份的--prepare执行的方式是不一样的。在全量备份中,可以通过两种操作保持数据库的一致性:已提交的事务将根据数据文件和日志文件进行重放操作,并回滚未提交的事务。在准备增量备份时,必须跳过未提交事务的回滚,因为在备份的过程中,可能存在进行中且未提交的事务,并且这些事务很可能在下一次的增量备份中才进行提交,所以必须使用--apply-log-only选项来防止回滚操作。
基于方式一的恢复
- 准备好备份片
[root@oracle xtrabackup]# ll
total 20
drwxr-x--- 6 root root 4096 Aug 5 08:30 base
drwxr-x--- 6 root root 4096 Aug 5 08:32 incr1
drwxr-x--- 6 root root 4096 Aug 5 08:52 incr2
- 执行恢复命令
[root@oracle xtrabackup]# xtrabackup --prepare --apply-log-only --target-dir=/xtrabackup/base
[root@oracle xtrabackup]# xtrabackup --prepare --apply-log-only --target-dir=/xtrabackup/base --incremental-dir=/xtrabackup/incr1
[root@oracle xtrabackup]# xtrabackup --prepare --target-dir=/xtrabackup/base --incremental-dir=/xtrabackup/incr2
[root@oracle xtrabackup]# xtrabackup --copy-back --target-dir=/xtrabackup/base/
- 对data目录授权
[root@oracle mysql] chown -R mysql.mysql data/
基于方式二的恢复
- 准备好备份片
[root@oracle xtrabackup]# ll
total 20
drwxr-x--- 6 root root 4096 Aug 5 08:30 base
drwxr-x--- 6 root root 4096 Aug 5 08:32 incr1
drwxr-x--- 6 root root 4096 Aug 5 08:52 incr2
- 执行恢复命令
[root@oracle xtrabackup]# xtrabackup --prepare --apply-log-only --target-dir=/xtrabackup/base
[root@oracle xtrabackup]# xtrabackup --prepare --target-dir=/xtrabackup/base --incremental-dir=/xtrabackup/incr2
[root@oracle xtrabackup]# xtrabackup --copy-back --target-dir=/xtrabackup/base/
- 对data目录授权
[root@oracle mysql] chown -R mysql.mysql data/
Tips:
--apply-log-only
命令应该用在所有增量备份(除最后一次增量备份),这就是为什么恢复脚本中,最后一次的命令不包含--apply-log-only
。即使--apply-log-only
在最后一次增量备份时被使用,备份仍将是一致的,但在这种情况下,数据库会执行回滚的操作。
压缩备份
[root@oracle xtrabackup]# xtrabackup --user=root --backup --compress --socket=/tmp/mysql.sock --target-dir=/xtrabackup/compress
压缩和未压缩的对比
[root@oracle xtrabackup]# du -h --max-depth=1
57M ./base
3.3M ./compress
如果想要加速备份的速度,可以采用--compress-threads命令
[root@oracle xtrabackup]# xtrabackup --user=root --backup --compress --compress-threads=4 --socket=/tmp/mysql.sock --target-dir=/xtrabackup/compress
解压缩
[root@oracle xtrabackup]# xtrabackup --decompress --target-dir=/xtrabackup/compress
如果出现报错:
xtrabackup: recognized server arguments: --datadir=/usr/local/mysql/data --server-id=1
xtrabackup: recognized client arguments: --decompress=1 --target-dir=/xtrabackup/compress
xtrabackup version 8.0.6 based on MySQL server 8.0.14 Linux (x86_64) (revision id: c0a2d91)
190805 09:07:23 [01] decompressing ./ibdata1.qp
sh: qpress: command not found
cat: write error: Broken pipe
Error: decrypt and decompress thread 0 failed.
使用如下解决方式:
[root@oracle ~]# wget http://www.quicklz.com/qpress-11-linux-x64.tar
[root@oracle ~]# tar xf qpress-11-linux-x64.tar
[root@oracle ~]# cp qpress /usr/bin
重新解压缩
[root@oracle xtrabackup]# xtrabackup --decompress --target-dir=/xtrabackup/compress
...省略...
190805 10:29:16 [01] decompressing ./mysql.ibd.qp
190805 10:29:16 [01] decompressing ./binlog.index.qp
190805 10:29:16 completed OK!
Tips:
--parallel
命令可以配合--decompress一
起使用,查看目录文件,会发现压缩文件和解压文件共存,如果不想保留原压缩文件,可以使用 --remove-original
命令:
[root@oracle compress]# ll
total 59236
-rw-r--r-- 1 root root 476 Aug 5 10:29 backup-my.cnf
-rw-r----- 1 root root 453 Aug 5 09:07 backup-my.cnf.qp
-rw-r--r-- 1 root root 155 Aug 5 10:29 binlog.000019
-rw-r----- 1 root root 183 Aug 5 09:07 binlog.000019.qp
-rw-r--r-- 1 root root 16 Aug 5 10:29 binlog.index
-rw-r----- 1 root root 93 Aug 5 09:07 binlog.index.qp
drwxr-x--- 2 root root 4096 Aug 5 10:29 company
-rw-r--r-- 1 root root 3329 Aug 5 10:29 ib_buffer_pool
-rw-r----- 1 root root 912 Aug 5 09:07 ib_buffer_pool.qp
-rw-r--r-- 1 root root 12582912 Aug 5 10:29 ibdata1
-rw-r----- 1 root root 253881 Aug 5 09:07 ibdata1.qp
drwxr-x--- 2 root root 4096 Aug 5 10:29 mysql
-rw-r--r-- 1 root root 24117248 Aug 5 10:29 mysql.ibd
-rw-r----- 1 root root 2191005 Aug 5 09:07 mysql.ibd.qp
drwxr-x--- 2 root root 12288 Aug 5 10:29 performance_schema
drwxr-x--- 2 root root 4096 Aug 5 10:29 sys
-rw-r--r-- 1 root root 10485760 Aug 5 10:29 undo_001
-rw-r----- 1 root root 224626 Aug 5 09:07 undo_001.qp
-rw-r--r-- 1 root root 10485760 Aug 5 10:29 undo_002
-rw-r----- 1 root root 220474 Aug 5 09:07 undo_002.qp
-rw-r--r-- 1 root root 18 Aug 5 10:29 xtrabackup_binlog_info
-rw-r----- 1 root root 105 Aug 5 09:07 xtrabackup_binlog_info.qp
-rw-r----- 1 root root 95 Aug 5 09:07 xtrabackup_checkpoints
-rw-r--r-- 1 root root 529 Aug 5 10:29 xtrabackup_info
-rw-r----- 1 root root 486 Aug 5 09:07 xtrabackup_info.qp
-rw-r--r-- 1 root root 2560 Aug 5 10:29 xtrabackup_logfile
-rw-r----- 1 root root 342 Aug 5 09:07 xtrabackup_logfile.qp
-rw-r--r-- 1 root root 262 Aug 5 10:29 xtrabackup_tablespaces
-rw-r----- 1 root root 234 Aug 5 09:07 xtrabackup_tablespaces.qp
不保留原压缩文件,使用 --remove-original
[root@oracle compress]# xtrabackup --decompress --remove-original --target-dir=/xtrabackup/compress
查看目录文件
[root@oracle compress]# ll
total 56380
-rw-r--r-- 1 root root 476 Aug 5 10:32 backup-my.cnf
-rw-r--r-- 1 root root 155 Aug 5 10:32 binlog.000019
-rw-r--r-- 1 root root 16 Aug 5 10:32 binlog.index
drwxr-x--- 2 root root 4096 Aug 5 10:32 company
-rw-r--r-- 1 root root 3329 Aug 5 10:32 ib_buffer_pool
-rw-r--r-- 1 root root 12582912 Aug 5 10:32 ibdata1
drwxr-x--- 2 root root 4096 Aug 5 10:32 mysql
-rw-r--r-- 1 root root 24117248 Aug 5 10:32 mysql.ibd
drwxr-x--- 2 root root 12288 Aug 5 10:32 performance_schema
drwxr-x--- 2 root root 4096 Aug 5 10:32 sys
-rw-r--r-- 1 root root 10485760 Aug 5 10:32 undo_001
-rw-r--r-- 1 root root 10485760 Aug 5 10:32 undo_002
-rw-r--r-- 1 root root 18 Aug 5 10:32 xtrabackup_binlog_info
-rw-r----- 1 root root 95 Aug 5 09:07 xtrabackup_checkpoints
-rw-r--r-- 1 root root 529 Aug 5 10:32 xtrabackup_info
-rw-r--r-- 1 root root 2560 Aug 5 10:32 xtrabackup_logfile
-rw-r--r-- 1 root root 262 Aug 5 10:32 xtrabackup_tablespaces
流式备份(Streaming Backups)
Percona XtraBackup支持xbstream流模式将备份发送到STDOUT,而不是将文件复制到备份目录。这允许您使用其他程序过滤备份的输出,从而为备份的存储提供更大的灵活性。例如,通过输出管道的方式可以实现压缩且备份可以自动加密。
使用xbstream作为流选项,可以并行复制和压缩备份,这可以显着加快备份过程。 如果备份既压缩又加密,则需要先解密才能解压缩。
-
并行压缩且并行复制备份
[root@oracle /]# xtrabackup --backup --socket=/tmp/mysql.sock --compress --compress-threads=8 --stream=xbstream --parallel=4 --target-dir=/xtrabackup/ >backup.xbstream
-
查看结果
[root@oracle xtrabackup]# ll backup.xbstream -rw-r--r-- 1 root root 3148078 Aug 6 15:01 backup.xbstream
恢复时必须先解压xbstream格式,再解压qp
-
解压xbstream
[root@oracle /]# xbstream -x < backup.xbstream -C /xtrabackup/
-
查看内容
[root@oracle xtrabackup]# ll total 2920 -rw-r----- 1 root root 453 Aug 6 15:03 backup-my.cnf.qp -rw-r----- 1 root root 183 Aug 6 15:03 binlog.000035.qp -rw-r----- 1 root root 93 Aug 6 15:03 binlog.index.qp drwxr-x--- 2 root root 4096 Aug 6 15:03 company -rw-r----- 1 root root 945 Aug 6 15:03 ib_buffer_pool.qp -rw-r----- 1 root root 315187 Aug 6 15:03 ibdata1.qp drwxr-x--- 2 root root 4096 Aug 6 15:03 mysql -rw-r----- 1 root root 2187997 Aug 6 15:03 mysql.ibd.qp drwxr-x--- 2 root root 4096 Aug 6 15:03 performance_schema drwxr-x--- 2 root root 4096 Aug 6 15:03 sys -rw-r----- 1 root root 212804 Aug 6 15:03 undo_001.qp -rw-r----- 1 root root 215761 Aug 6 15:03 undo_002.qp -rw-r----- 1 root root 105 Aug 6 15:03 xtrabackup_binlog_info.qp -rw-r----- 1 root root 95 Aug 6 15:03 xtrabackup_checkpoints -rw-r----- 1 root root 498 Aug 6 15:03 xtrabackup_info.qp -rw-r----- 1 root root 333 Aug 6 15:03 xtrabackup_logfile.qp -rw-r----- 1 root root 234 Aug 6 15:03 xtrabackup_tablespaces.qp
-
解压qp
[root@oracle /]# xtrabackup --decompress --remove-original --target-dir=/xtrabackup/
-
查看内容
[root@oracle xtrabackup]# ll total 56372 -rw-r--r-- 1 root root 476 Aug 6 15:04 backup-my.cnf -rw-r--r-- 1 root root 155 Aug 6 15:04 binlog.000035 -rw-r--r-- 1 root root 16 Aug 6 15:04 binlog.index drwxr-x--- 2 root root 4096 Aug 6 15:04 company -rw-r--r-- 1 root root 3458 Aug 6 15:04 ib_buffer_pool -rw-r--r-- 1 root root 12582912 Aug 6 15:04 ibdata1 drwxr-x--- 2 root root 4096 Aug 6 15:04 mysql -rw-r--r-- 1 root root 24117248 Aug 6 15:04 mysql.ibd drwxr-x--- 2 root root 4096 Aug 6 15:04 performance_schema drwxr-x--- 2 root root 4096 Aug 6 15:04 sys -rw-r--r-- 1 root root 10485760 Aug 6 15:04 undo_001 -rw-r--r-- 1 root root 10485760 Aug 6 15:04 undo_002 -rw-r--r-- 1 root root 18 Aug 6 15:04 xtrabackup_binlog_info -rw-r----- 1 root root 95 Aug 6 15:03 xtrabackup_checkpoints -rw-r--r-- 1 root root 544 Aug 6 15:04 xtrabackup_info -rw-r--r-- 1 root root 2560 Aug 6 15:04 xtrabackup_logfile -rw-r--r-- 1 root root 262 Aug 6 15:04 xtrabackup_tablespaces
加密备份(Encrypting Backups)
Percona XtraBackup支持使用xbstream选项加密和解密本地和流式备份,从而增加了另一层保护。使用GnuPG的libgcrypt库实现加密
加密
-encrypt-key
选项,通过ssl生成密钥
[root@oracle xtrabackup]# openssl rand -base64 24
LymjcKljN4xxtPUe3GkF/4mNzj3x4y9D
加密时指定密钥:
xtrabackup --backup --encrypt=AES256 --encrypt-key="LymjcKljN4xxtPUe3GkF/4mNzj3x4y9D" --target-dir=/xtrabackup/ --socket=/tmp/mysql.sock
查看备份的文件
[root@oracle xtrabackup]# ll
total 56468
-rw-r----- 1 root root 568 Aug 6 16:21 backup-my.cnf.xbcrypt
-rw-r----- 1 root root 247 Aug 6 16:21 binlog.000036.xbcrypt
-rw-r----- 1 root root 108 Aug 6 16:21 binlog.index.xbcrypt
drwxr-x--- 2 root root 4096 Aug 6 16:21 company
-rw-r----- 1 root root 3550 Aug 6 16:21 ib_buffer_pool.xbcrypt
-rw-r----- 1 root root 12600576 Aug 6 16:21 ibdata1.xbcrypt
drwxr-x--- 2 root root 4096 Aug 6 16:21 mysql
-rw-r----- 1 root root 24151104 Aug 6 16:21 mysql.ibd.xbcrypt
drwxr-x--- 2 root root 4096 Aug 6 16:21 performance_schema
drwxr-x--- 2 root root 4096 Aug 6 16:21 sys
-rw-r----- 1 root root 10500480 Aug 6 16:21 undo_001.xbcrypt
-rw-r----- 1 root root 10500480 Aug 6 16:21 undo_002.xbcrypt
-rw-r----- 1 root root 110 Aug 6 16:21 xtrabackup_binlog_info.xbcrypt
-rw-r----- 1 root root 95 Aug 6 16:21 xtrabackup_checkpoints
-rw-r----- 1 root root 595 Aug 6 16:21 xtrabackup_info.xbcrypt
-rw-r----- 1 root root 2744 Aug 6 16:21 xtrabackup_logfile.xbcrypt
-rw-r----- 1 root root 354 Aug 6 16:21 xtrabackup_tablespaces.xbcrypt
Tips:
通过使用--encrypt-threads
选项,可以指定多个线程并行使用加密。选项--encrypt-chunk-size
可用于指定每个加密线程的工作加密缓冲区的大小(以字节为单位)(默认为64K)。
解密
--decrypt
选项执行解密,如果不想保留原压缩文件,可以使用--remove-original
命令
xtrabackup --remove-original --decrypt=AES256 --encrypt-key="LymjcKljN4xxtPUe3GkF/4mNzj3x4y9D" --target-dir=/xtrabackup/
查看备份文件
[root@oracle xtrabackup]# ll
total 56380
-rw-r--r-- 1 root root 476 Aug 6 16:25 backup-my.cnf
-rw-r--r-- 1 root root 155 Aug 6 16:25 binlog.000036
-rw-r--r-- 1 root root 16 Aug 6 16:25 binlog.index
drwxr-x--- 2 root root 4096 Aug 6 16:25 company
-rw-r--r-- 1 root root 3458 Aug 6 16:25 ib_buffer_pool
-rw-r--r-- 1 root root 12582912 Aug 6 16:25 ibdata1
drwxr-x--- 2 root root 4096 Aug 6 16:25 mysql
-rw-r--r-- 1 root root 24117248 Aug 6 16:25 mysql.ibd
drwxr-x--- 2 root root 12288 Aug 6 16:25 performance_schema
drwxr-x--- 2 root root 4096 Aug 6 16:25 sys
-rw-r--r-- 1 root root 10485760 Aug 6 16:25 undo_001
-rw-r--r-- 1 root root 10485760 Aug 6 16:25 undo_002
-rw-r--r-- 1 root root 18 Aug 6 16:25 xtrabackup_binlog_info
-rw-r----- 1 root root 95 Aug 6 16:21 xtrabackup_checkpoints
-rw-r--r-- 1 root root 503 Aug 6 16:25 xtrabackup_info
-rw-r--r-- 1 root root 2560 Aug 6 16:25 xtrabackup_logfile
-rw-r--r-- 1 root root 262 Aug 6 16:25 xtrabackup_tablespaces
Tips:
--parallel
可以与--decrypt
选项一起使用来同时解密多个文件。