MySQL8使用XtraBackup备份恢复

MySQL8使用XtraBackup备份恢复

evobot 1,170 2021-11-26

XtraBackup是由Percona提供的开源备份软件。它能在不关闭服务器的情况下复制普通文件。但为了避免不一致,它会使用redo日志文件。XtraBackup被许多公司广泛用做标准备份工具。与逻辑备份工具相比,其优势是备份速度非常快,恢复速度也非常快。

Percona XtraBackup的工作原理:

  1. XtraBackup复制InnoDB数据文件,这会导致内部不一致的数据,但是它会对文件执行崩溃恢复,以使其再次成为一个一致的可用数据库

  2. 这样做的可行性是因为InnoDB维护一个REDO日志,也称为事务日志。REDO日志包含了InnoDB数据每次更改的记录。当InnoDB启动时,REDO日志会检查数据文件和事务日志,并执行两个步骤。它将已提交的事务日志条目应用于数据文件,并对任何修改了数据但未提交的事务执行undo操作

  3. 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。全量备份命令:

方式一

  1. 基于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

在进行了全量备份后 ,我们可以通过增量备份的命令进行备份:

  1. 基于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
  1. 基于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,所以缺一不可。

方式二

  1. 基于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
  1. 基于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
  1. 基于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选项来防止回滚操作。

基于方式一的恢复

  1. 准备好备份片
[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
  1. 执行恢复命令
[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/
  1. 对data目录授权
[root@oracle mysql] chown -R mysql.mysql data/

基于方式二的恢复

  1. 准备好备份片
[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
  1. 执行恢复命令
[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/
  1. 对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选项一起使用来同时解密多个文件。



# MySQL