您的位置:首页 > 博客中心 > 数据库 >

数据库热备份神器 - XtraBackup

时间:2022-03-15 17:54

常见的热备份方案

LVM方案

利用Linux的LVM技术来实现热备份,将MySQL的数据目录放到LVM逻辑卷上,然后通过LVM快照技术备份逻辑卷的内容。第一次备份是全量备份,之后的备份都是增量备份。在还原时,将快照中的数据目录恢复到ySQL的数据目录即可。

使用LVM这种技术不仅可以备份MySQL还可以备份MongoDB等其他数据库,但使用LVM做热备份方案也比较麻烦,因为需要手动创建逻辑卷、迁移数据目录、创建快照以及给数据库加锁等等,所以LVM并不是常用的热备份方案。

XtraBackup方案

因为LVM的麻烦,所以人们都希望使用专业的工具去做热备份,这个工具就是XtraBackup。XtraBackup是由Percona开源的免费数据库热备份工具,它能对InnoDB数据库和XtraDB存储引擎的数据库非阻塞地备份。因为XtraBackup在备份过程中不会打断正在执行的事务,而事务日志中记录了哪些是备份前写入的数据哪些是备份后写入的数据,所以无需加锁。

另外,XtraBackup提供了对备份数据的压缩功能,可以节约备份文件占用的磁盘空间及网络带宽。但XtraBackup在备份使用MyISAM作为存储引擎的表时会加读锁,即表中的数据可读但不可写,不过这也不是问题,之前提到了可以使用联机热备份的方式来解决加读锁的问题。同样,XtraBackup支持全量备份和增量备份,因为XtraBackup的方便性,所以一般都是采用XtraBackup来做热备份方案。

XtraBackup热备份原理

因为XtraBackup是主流的MySQL热备份方案,所以这里简单介绍一下XtraBackup热备份原理:

  • XtraBackup是一种物理备份工具,通过协议连接到MySQL服务端,然后读取并复制底层的数据文件,完成物理备份。需要注意的是XtraBackup支持对InnoDB做全量备份和增量备份,但只能对MyISAM做全量备份
    技术图片

现在已经知道了XtraBackup是通过读取并复制底层的数据文件,完成物理备份的。其中全量备份比较简单,直接备份数据文件中的所有内容即可。而增量备份则需要区分新数据和旧数据,然后仅备份新数据,所以稍微复杂以些。

XtraBackup增量备份的原理如下:

增量备份只备份新增的数据,所以XtraBackup会去读取数据文件中的内容来判断哪些是旧数据哪些是新数据,然后只去备份新数据。在MySQL的数据文件里,数据是存放在row这种结构中的,而row存放在page中,page则存在于extend中。

MySQL会为每一个page都标记上一个LSN编号,通过对比该编号就可以得知哪些数据是新的,哪些数据是旧的。然后XtraBackup只需要从数据文件中,将这些新的page数据备份出来就行了。

示意图:

技术图片

那么XtraBackup是如何得知哪些LSN是新的呢?首先我们要知道LSN是一个全局递增的编号,每次对page中的数据进行修改时都会产生新的LSN编号。假设现在有6个page,各自的LSN编号如下:
技术图片

上图中,LSN编号为3的表示被修改过3次,LSN编号为5的表示被修改过5次,以此类推。假设此时对这些page进行一次全量备份,那么这6个page都会被备份下来。经过一段时间后,其中有三个page被修改了,LSN编号发生了变化,如下所示:
技术图片

当进行增量备份时,XtraBackup就会将之前备份的pageLSN编号与数据文件中与之对应的pageLSN编号进行对比,若数据文件里的LSN编号大于备份里的LSN编号则代表数据文件中的page是新数据,那么XtraBackup就会对其进行备份。若等于则代表数据没有发生变化,不进行备份。因为LSN编号是全局递增的,所以不存在小于的情况。这就是XtraBackup增量备份的原理。


安装XtraBackup

在了解了XtraBackup和其热备份的实现原理后,接下来我们实践一下如何使用该工具。首先需要安装官方提供的yum仓库:

[root@PXC-Node3 ~]# yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm

然后激活该yum仓库:

[root@PXC-Node3 ~]# percona-release setup ps80

现在就可以直接通过yum命令本地安装XtraBackup了:

[root@PXC-Node3 ~]# yum install -y percona-xtrabackup-24 

安装完成后,输出一下版本信息验证xtrabackup命令是否可用:

[root@PXC-Node3 ~]# xtrabackup --version
xtrabackup: recognized server arguments: --server-id=3 --datadir=/var/lib/mysql --log_bin 
xtrabackup version 2.4.18 based on MySQL server 5.7.26 Linux (x86_64) (revision id: 29b4ca5)
[root@PXC-Node3 ~]# 

常用命令

XtraBackup命令种类:

使用innobackupex命令进行全量热备份示例:

[root@PXC-Node3 ~]# innobackupex --defaults-file=/etc/my.cnf --host=192.168.190.134 --user=admin --password=Abc_123456 --port=3306 /home/backup
  • --defaults-file:指定MySQL的配置文件所在路径,因为XtraBackup需要通过读取配置文件才能知道数据目录在哪
  • --host:指定MySQL服务的ip地址,因为全量备份时需要备份表结构,所以得连接到MySQL加读锁
  • --user:指定使用哪个MySQL用户进行备份
  • --password:MySQL用户的密码
  • --port:指定MySQL服务的端口号
  • /home/backup:备份文件存储的目录

备份的文件目录如下:

[root@PXC-Node3 ~]# ls /home/backup/
2020-01-26_10-33-29
[root@PXC-Node3 ~]# ls /home/backup/2020-01-26_10-33-29/
backup-my.cnf   ibdata1  performance_schema  test  xtrabackup_binlog_info  xtrabackup_info
ib_buffer_pool  mysql    sys                 tpcc  xtrabackup_checkpoints  xtrabackup_logfile
[root@PXC-Node3 ~]#

以上这是一个最简单的全量热备份示例,可以看到备份出来的目录和文件有很多,并且也没有对这些备份文件进行压缩。如果需要备份的数据量比较大的话,不压缩备份文件就会很占用存储空间。但使用常规的压缩命令,如tarzip等,则需要两次I/O操作,因为得先使用XtraBackup备份了数据之后,才能对产生的备份文件进行压缩。因此备份的数据量较大时,对系统I/O和CPU的影响就比较明显。

好在XtraBackup提供了流式压缩的功能,通过流式压缩可以将备份数据直接写到压缩文件中,而不用先备份再压缩,所以只需要一次I/O操作。如下:
技术图片

想在备份时使用流式压缩只需要指定--stream参数即可,如下示例:

[root@PXC-Node3 ~]# innobackupex --defaults-file=/etc/my.cnf --host=192.168.190.134 --user=admin --password=Abc_123456 --port=3306 --no-timestamp --stream=xbstream -> /home/backup/backup.xbstream
  • --no-timestamp:指定不生成时间戳目录
  • --stream:指定使用的压缩类型,目前只支持tarxbstream
  • /home/backup/backup.xbstream:指定生成的压缩文件名称

当备份一些涉及隐私的数据时,我们希望对备份文件进行加密,以防备份文件意外泄露时所带来的影响。而XtraBackup也提供了加密备份的功能,与加密相关的参数如下:

例如,当还原“增量备份1”时,需要先处理其前一个备份点的事务日志,即图中的“全量热备份”。接着再处理“增量备份1”这个备份点的事务日志,然后合并“增量备份1”的数据到“全量热备份”中。这样才能保证多个备份点合并到全量备份点后的数据是一致的,最后还原“全量热备份”中的数据即可。

再例如,要还原的是“增量备份2”,那么就得先处理“全量热备份”,然后处理“增量备份1”,接着处理“增量备份2”,按从前往后的顺序依次将这三个备份点的事务日志都给处理了后,才能合并备份点的数据到全量备份中,最后还原“全量热备份”中的数据。其余则以此类推......

接下来实操一下增量冷还原,这里有三个与上图对应的备份点目录:

/home/backup/2020-01-26_10-33-29/  # 全量热备份
/home/backup/increment/2020-01-27_10-11-24/  # 增量备份1
/home/backup/increment/2020-01-27_10-15-11/  # 增量备份2

因为是冷还原,所以得先关闭MySQL服务:

[root@PXC-Node3 ~]# systemctl stop mysqld

在本例中要还原的是“增量备份2”这个备份点的数据,按照之前的说明,首先处理全量备份点的事务日志,执行如下命令:

[root@PXC-Node3 ~]# innobackupex --apply-log --redo-only /home/backup/2020-01-26_10-33-29/
  • --redo-only:指定不回滚未提交的事务,因为下个备份点的事务日志里可能会提交该备份点未提交的事务。如果回滚了就会导致下个备份点无法正常提交

然后处理“增量备份1”的事务日志,并将"增量备份1"的数据合并到全量备份点上:

[root@PXC-Node3 ~]# innobackupex --apply-log --redo-only /home/backup/2020-01-26_10-33-29/ --incremental-dir=/home/backup/increment/2020-01-27_10-11-24/
  • --incremental-dir:指定要合并到全量备份的增量备份目录

接着处理“增量备份2”的事务日志,并将"增量备份2"的数据合并到全量备份点上。由于只还原到“增量备份2”这个备份点,所以就不需要加上--redo-only参数了,因为没有下个备份点了:

[root@PXC-Node3 ~]# innobackupex --apply-log /home/backup/2020-01-26_10-33-29/ --incremental-dir=/home/backup/increment/2020-01-27_10-15-11/

与全量冷还原一样,也需清空数据目录及表分区的数据目录:

[root@PXC-Node3 ~]# rm -rf /var/lib/mysql/*
[root@PXC-Node3 ~]# rm -rf /mnt/p0/data/*
[root@PXC-Node3 ~]# rm -rf /mnt/p1/data/*

完成以上步骤后,就可以使用如下命令完成备份文件的还原了:

[root@PXC-Node3 ~]# innobackupex --defaults-file=/etc/my.cnf --copy-back /home/backup/2020-01-26_10-33-29/  # 注意这里指定的是全量备份点的目录

接着给还原后的目录文件赋予mysql用户权限:

[root@PXC-Node3 ~]# chown -R mysql:mysql /var/lib/mysql/*
[root@PXC-Node3 ~]# chown -R mysql:mysql /mnt/p0/data/*
[root@PXC-Node3 ~]# chown -R mysql:mysql /mnt/p1/data/*

到此为止还原就完成了,最后启动MySQL服务并自行验证下数据是否正常即可:

[root@PXC-Node3 ~]# systemctl start mysqld

热门排行

今日推荐

热门手游