目录
- 一:xtrabackup 介绍
- 二:实现数据备份
- 1. 实现全备份
- 2. 实现增量备份
- 3. 实现差异备份
- 4. 全备份时压缩数据
- 5. 全备份时排除指定表不备份
- 6. 全备份时排除指定库不备份
- 三:实现数据还原
- 1. 全备份数据恢复流程
- 2. 全备份压缩后的数据恢复流程
- 3. 增量备份数据恢复流程
- 4. 差异备份数据恢复流程
- 5. 全备份排除指定表时数据恢复方法
- 6. 全备份排除指定数据库时数据恢复方法
一:xtrabackup 介绍
Xtrabackup 是由 Percona 公司开源的一款 MySQL 物理热备份工具,以实现对 MySQL 或 MariaDB这类数据库的数据库进行物理备份。
官网: https://www.percona.com/mysql/software/percona-xtrabackup
xtrabackup具有以下特点:
1、属于物理备份工具,备份过程中是直接拷贝的数据库的物理文件,而不是像逻辑备份工具一样,要连接到MySQL服务端后通过执行大量的读操作,从而将对应的sql语句写入备份文件,所以xtrabackup备份过程中不会增加MySQL服务端的负载;
2、属于多线程备份工具,备份速度和数据恢复速度都很快;不像逻辑备份数据一样,恢复数据的时候只能单线程按顺序读取sql语句,然后再执行;
3、版本兼容性较差,不同版本的 XtraBackup 可能只能与特定版本的 MySQL 或 MariaDB 兼容。需要确保使用与数据库版本相匹配的 XtraBackup 版本。
4、一般用于全备份场景,排除指定数据不备份,恢复时比较繁琐。
5、支持innodb、mysaim等存储引擎的备份,备份速度受到服务器性能(IO等)影响;
二:实现数据备份
1. 实现全备份
-
--datadir
:指定MySQL的数据目录 -
--target-dir
:指定备份数据的存放目录 -
--backup
:表示执行一个全备份操作 -
--defaults-file
:指定MySQL配置文件路径,不指定就默认会去/etc/my.cnf、 /etc/mysql/my.cnf、~/.my.cnf
查找 -
--parallel
:指定使用多少个线程参与备份,如果10个CPU,一般设置为7左右。不指定就默认是单线程
例如:MySQL数据目录是/var/lig/mysql
,需要将MySQL的所有数据备份到/backup/
下
# 需要管理员权限才行,因为要访问/var/lib/mysql目录
sudo xtrabackup --backup --parallel=6 \
--host="127.0.0.1" --user="root" --password="redhat" --port=3306 \
--datadir="/var/lib/mysql" --target-dir="/backup/xtrabackup_full"
最后出现 [Xtrabackup] completed OK! 表示备份完成
注意:进行全备份时,备份文件的大小和MySQL数据目录大小差不多一样大,并且备份过程中对硬盘I/O的要求比较高;
2. 实现增量备份
-
--target-dir
:指定增量备份文件的存放位置 -
--incremental-basedir
:指定了前一个备份的目录。这个目录可以是全备份或另一个增量备份的目录。通过比较--incremental-basedir
中的数据与当前数据库的状态,来确定自上次备份以来哪些数据发生了变化。
1、先创建一个完整的备份
sudo xtrabackup --backup --parallel=6 \
--host="127.0.0.1" --user="root" --password="redhat" --port=3306 \
--datadir="/var/lib/mysql" --target-dir="/backup/xtrabackup_full"
2、基于全备份文件创建第一次增量备份
sudo xtrabackup --backup --parallel=6 \
--incremental-basedir="/backup/xtrabackup_full" \
--host="127.0.0.1" --user="root" --password="redhat" --port=3306 \
--target-dir="/backup/xtrabackup_incre1"
3、基于第一次增量备份创建第二次增量备份
sudo xtrabackup --backup --parallel=6 \
--incremental-basedir="/backup/xtrabackup_incre1" \
--host="127.0.0.1" --user="root" --password="redhat" --port=3306 \
--target-dir="/backup/xtrabackup_incre2"
4、基于第 N-1 次增量备份创建第N次增量备份
sudo xtrabackup --backup --parallel=6 \
--incremental-basedir="第n-1次备份文件的数据路径" \
--host="127.0.0.1" --user="root" --password="redhat" --port=3306 \
--target-dir="本次备份存放目录"
3. 实现差异备份
差异备份就是备份自上次完全备份以来所有发生变化的数据。
1、先创建一个完整的备份
sudo xtrabackup --backup --parallel=6 \
--host="127.0.0.1" --user="root" --password="redhat" --port=3306 \
--datadir="/var/lib/mysql" --target-dir="/backup/xtrabackup_full"
2、后续的每一次备份都基于这个全备份实现
sudo xtrabackup --backup --parallel=6 \
--host="127.0.0.1" --user="root" --password="redhat" --port=3306 \
--incremental-basedir="/backup/xtrabackup_full" \
--target-dir="/backup/xtrabackup_diff"
4. 全备份时压缩数据
因为全备份的备份数据太大了,可以在备份过程中将数据进行压缩,减少磁盘空间的占用。
不同版本使用的默认压缩算法和支持的压缩算法不同,具体需要根据版本号查看官方文档了解。例如从XtraBackup 8.0.34版本开始,默认的压缩算法就是 ZSTD。
链接:https://docs.percona.com/percona-xtrabackup/8.0/create-compressed-backup.html
链接:https://docs.percona.com/percona-xtrabackup/8.0/create-compressed-backup.html#version-updates
sudo xtrabackup --backup --parallel=6 \
--compress --compress-threads=3 \
--host="127.0.0.1" --user="root" --password="redhat" --port=3306 \
--datadir="/var/lib/mysql" --target-dir="/backup/xtrabackup_full_compress"
-
--compress
:不指定使用的压缩算法,默认就按照当前xtrabackup默认指定的压缩算法进行压缩 -
--compress-threads
:默认是1,表示指定多少个线程来参与压缩,一般为CPU的70%左右
备份时对数据进行压缩,默认使用zstd算法时,基本上能达到7倍左右压缩效率,但是压缩过程中会使用更多的CPU资源。
5. 全备份时排除指定表不备份
--tables-exclude
:用于指定需要排除那些表不进行备份,支持正则和扩展正则;
sudo xtrabackup --backup --parallel=6 \
--host="127.0.0.1" --user="root" --password="redhat" --port=3306 \
--datadir="/var/lib/mysql" --target-dir="/backup/xtrabackup_full" \
--tables-exclude='lct_net_manager\.tb_err_future_loc_20.*|lct_net_manager\.tb_heartbeat_data_20.*'
6. 全备份时排除指定库不备份
--databases-exclude
:用于指定排除哪些数据库不备份
sudo xtrabackup --backup --parallel=6 \
--host="127.0.0.1" --user="root" --password="redhat" --port=3306 \
--datadir="/var/lib/mysql" --target-dir="/backup/xtrabackup_full" \
--databases-exclude='history'
三:实现数据还原
-
--prepare
:表示对备份的数据进行预处理操作 -
--use-memory
:增加用于恢复操作的内存大小,通过这个选项可以加速恢复过程。 -
--target-dir
:指定备份数据的位置
1. 全备份数据恢复流程
1、 先停止MySQL后,清空MySQL数据目录,为了安全可以先将旧数据目录备份,然后创建新的数据目录
sytemctl stop mysql.service
mv /var/lib/mysql /var/lib/mysql-bakcup
mkdir /var/lib/mysql && chown mysql.mysql /var/lib/mysql
2、将全备份数据进行预处理操作
物理备份是通过直接拷贝 MySQL 数据目录下的文件实现,而逻辑备份可以通过开启事务来确保数据的一致性,但物理备份在备份过程中无法避免数据的并发写入。
假设执行数据备份时,若有新的数据写入 MySQL,某些数据的元信息可能已记录到系统表中,但其数据部分可能尚未完全写入到数据文件中。这就导致了备份的文件里面记录了不完整的数据或未进行完成的事务。如果直接用这些数据去恢复MySQL,会导致数据损坏或一致性错误。
所以进行预处理( prepare 阶段)的作用就是回滚未提交的事务,丢弃不完整的数据,应用未完成的事务。这样就可以保证MySQL的数据文件和元数据信息对的上,才能确保恢复后的数据文件完整、可靠,并能够成功启动 MySQL。
sudo xtrabackup --prepare --parallel=6 --use-memory=3G \
--target-dir="/backup/xtrabackup_full"
说明:如果是全备份,多次执行预处理操作时不会有什么影响的;
3、将备份的数据拷贝到MySQL数据目录下
sudo xtrabackup --copy-back --parallel=6 \
--target-dir="/backup/xtrabackup_full" --datadir=/var/lib/mysql
-
--copy-back
:将备份数据复制到mysql数据目录 -
-
-move-back
:将备份数据移动到mysql数据目录,此时备份文件就没了
4、重新启动MySQL
systemctl restart mysql.service
2. 全备份压缩后的数据恢复流程
1、先停止MySQL后,清空MySQL数据目录,为了安全可以先将旧数据目录备份,然后创建新的数据目录
sytemctl stop mysql.service
mv /var/lib/mysql /var/lib/mysql-bakcup
mkdir /var/lib/mysql && chown mysql.mysql /var/lib/mysql
2、将压缩后的全备份数据进行解压
需要提前在操作系统上安装相关的压缩工具,例如使用zstd的算法来压缩备份数据,也需要安装对应的工具,xtrbackup解压缩数据的时候会调用这个工具,如果不安装就没法解压成功;
sudo xtrabackup --decompress --parallel=6 \
--target-dir="/backup/xtrabackup_full"
--decompress
:会自动选择压缩时的算法,然后调用系统上的工具来进行解压。
3、对备份的数据进行预处理操作
sudo xtrabackup --prepare --use-memory=3G --parallel=6 \
--target-dir="/backup/xtrabackup_full"
4、将备份的数据拷贝到MySQL数据目录下
sudo xtrabackup --copy-back --parallel=6 \
--target-dir="/backup/xtrabackup_full" --datadir=/var/lib/mysql
5、重新启动MySQL
systemctl restart mysql.service
3. 增量备份数据恢复流程
1、先停止MySQL后,清空MySQL数据目录,为了安全可以先将旧数据目录备份,然后创建新的数据目录
sytemctl stop mysql.service
mv /var/lib/mysql /var/lib/mysql-bakcup
mkdir /var/lib/mysql && chown mysql.mysql /var/lib/mysql
2、先将全备份数据进行预处理
sudo xtrabackup --prepare --parallel=6 --use-memory=3G \
--apply-log-only \
--target-dir="/backup/xtrabackup_full"
3、将第一个增量备份数据应用到全备份数据中
sudo xtrabackup --prepare --parallel=6 --use-memory=3G \
--apply-log-only \
--target-dir="/backup/xtrabackup_full" \
--incremental-dir="/backup/xtrabackup_incre1"
4、再将第二个增量备份数据应用到全备份数据中
sudo xtrabackup --prepare --parallel=6 --use-memory=3G \
--apply-log-only \
--target-dir="/backup/xtrabackup_full" \
--incremental-dir="/backup/xtrabackup_incre2"
5、重复以上请步骤,按照顺序一次将 第三次到第 N-1 次的增量备份数据合并到全备份文件中
6、最后一个增量备份文件合并时,不能加 --apply-log-only
而是集体进行一次彻底回滚来保证一致性
sudo xtrabackup --prepare --parallel=6 --use-memory=3G \
--target-dir="/backup/xtrabackup_full" \
--incremental-dir="最后一次增量备份文件存放路径"
-
--incremental-dir
:指定的就是存放增量备份数据的目录 -
--target-dir
:指定的就是全备份数据的目录 -
--apply-log-only
:默认未执行完的事务在 prepare 操作时会被回滚,通过这个参数可以不回滚这些事务,等待所有增备数据都合并了,再进行一次彻底的回滚(最后一个增量合并不加--apply-log-only
)
7、将处理后的数据复制到MySQL数据目录下
将备份的数据拷贝到MySQL数据目录下
sudo xtrabackup --copy-back --parallel=6 --use-memory=3G \
--target-dir="/backup/xtrabackup_full" \
--datadir=/var/lib/mysql
8、重新启动MySQL
systemctl restart mysql.service
4. 差异备份数据恢复流程
1、 先停止MySQL后,清空MySQL数据目录,为了安全可以先将旧数据目录备份,然后创建新的数据目录
sytemctl stop mysql.service
mv /var/lib/mysql /var/lib/mysql-bakcup
mkdir /var/lib/mysql && chown mysql.mysql /var/lib/mysql
2、预处理全备份数据(仅应用日志)
xtrabackup --prepare --parallel=6 --use-memory=3G \
--apply-log-only \
--target-dir="/backup/xtrabackup_full"
3、合并差异备份数据到全备份
xtrabackup --prepare --use-memory=3G --parallel=6 \
--apply-log-only \
--target-dir="/backup/xtrabackup_full" \
--incremental-dir="/backup/xtrabackup_diff"
4、完成全备份数据的预处理(最终应用日志)
xtrabackup --prepare -use-memory=3G --parallel=6 \
--target-dir="/backup/xtrabackup_full"
5、将处理后的数据复制到MySQL数据目录下
sudo xtrabackup --copy-back --parallel=6 \
--target-dir="/backup/xtrabackup_full" \
--datadir=/var/lib/mysql
6、重新启动MySQL
systemctl restart mysql.service
5. 全备份排除指定表时数据恢复方法
xtrabackup排除指定的表不备份,实际上就是排除这些表的idb文件不备份,所以这就导致了数据恢复后,这张表的属性信息还在数据库里面。
1、先将备份的数据进行恢复
2、通过客户端工具连接到MySQL服务端,然后执行drop table
将这个数据表删除即可;
6. 全备份排除指定数据库时数据恢复方法
一般情况下,某个数据库的所有数据文件都是存储在MySQL数据目录下以数据库名的目录中的,全备份排除指定数据库不备份,就是不将这个目录进行备份。
但是这个数据库的属性信息还是保留在MySQL中的,所以需要先创建要给空目录,然后在执行删除操作,才会将属性信息也一并跟着删除;
1、先将备份的数据进行恢复
2、在MySQL数据目录下创建一个和排除数据库同名的目录文件(注意权限)
3、通过客户端工具连接到MySQL服务端,然后执行drop database
将这个数据库删除即可;