MySQL备份教程(2)物理备份工具Xtrabackup使用教程

TangLu MySQL 2021-04-03 8716 0

一、MySQL中的物理备份

通常将直接复制数据文件作为备份手段的方式称为物理备份,相比逻辑备份而言,物理备份最大的优点就是备份和恢复速度都非常快速,并且支持增量备份,物理备份过程中对服务器负载更低,备份期间不锁表、不中断业务(MyISAM引擎依然存在FTWRL),所以适用于大型数据库的备份。物理备份的缺点则是很难发现数据文件是否有损坏的情况,而且如果不能访问底层数据文件也无法使用物理备份。

MySQL 中最常用的物理备份方式是Percona出品的Xtrabackup,该工具在备份时通过 InnoDB checkpoint LSN记录数据位置,然后拷贝redo log和.idb文件,备份期间如果有新数据产生会被记录在一个innobackup_log文件中,所以 xtrabackup 备份完成后的数据是接近备份完成那一刻而不是备份起始那一刻的。


二、安装Xtrabackup方法

Xtrabackup 8之前的版本在安装完成后还有一个innobackup工具,它是为了兼容对非innodb表的备份。由于MySQL 8.0 表结构发生了变化,Xtrabackup 8 不再支持innobackupex,所以建议统一使用xtrabackup工具进行备份


方法1、使用二进制包安装Xtrabackup

访问Percona官网(https://www.percona.com/downloads)下载页面可以按需选择合适的版本,注意Xtrabackup的8.0版本仅支持对MySQL 8.0备份

xtrabackup.png


方法2、使用YUM安装

通过Percona官网的YUM源进行安装

yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm  #安装Xtrabackup官方YUM源 
yum install percona-xtrabackup-24  #mysql8以前版本
yum install percona-xtrabackup-80  #mysql8之后版本


方法3、使用RPM包安装

官网的RPM包下载地址同样在https://www.percona.com/downloads,使用该方法可能出现依赖问题,需要提前确保perl-DBD-mysql、libev等依赖已经安装好。如果在安装过程中出现Processing Dependency: libmysqlclient.so.18()(64bit) for package: perl-DBD-MySQL-4.023-6.el7.x86_64问题,需要安装mysql-community-libs-compat,该软件包可以通过MySQL源码包中获取,如mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar。如提示libev.so.4()(64bit) is needed by percona-xtrabackup-2.3.4-1.el7.x86_64 ,则配置好EPEL源安装libev即可

微信截图_20250108145240.png


三、Xtrabackup工具常用选项

· --defaults-file:xtrabackup需要通过my.cnf配置文件来获取数据存储路径,该选项必须是第一个选项,--defaults-file=/etc/my.cnf
· --user:执行备份操作的MySQL用户(非系统用户),该用户需要有MySQL的相关权限,一般用root即可
· --password:MySQL用户的密码
· --databases:指定要备份的数据库,多个数据库以空格隔开,如"db1 db2",在指定某数据库时也可以只指定其中的某张表(MySQL需要配置innodb_file_per_table = 1)

· --databases-exclude:备份时排除指定的数据库

· --no-timestamp:使用这个选项后,备份时不会创建一个以时间戳命名的目录
· --compress:将备份数据进行压缩,在使用备份数据前需要使用--decompress解压(使用xtrabackup8默认的压缩格式ZSTD进行测试,压缩前后大小比率为5:1)

· --compress-threads=8:启用压缩备份时开启的压缩线程数

· --decompress如果备份通过--compress压缩,在恢复前需要--decompress解压

· --remove-original解压完成后删掉原有的.qp压缩文件

· --stream:使用xbstream或tar流备份,使用此选项时备份数据将以指定流格式输出到标准输出上,通常用它实现本机不落盘的异地备份

· --parallel=4:备份所用的线程数

· --slave-info :主从模式下,可以通过该选项在从库进行备份。备份完成后会创建xtrabackup_slave_info文件用于记录主库的binlog position和GTID信息。这样在使用从库备份进行恢复或者部署新的从库时都可以找到正确的主库position(如果主库非GTID模式并且slave_parallel_workers不为0,则该选项无法使用)
· --safe-slave-backup:从库在备份期间会每隔3秒通过SHOW STATUS LIKE "slave_open_temp_tables"检测一次是否存在临时表(保证数据一致性),没有临时表的话直接备份,如果有打开的临时表就会等待--safe-slave-backup-timeout超时,否则在尝试100次(300s)超时后,stop slave sql_thread再开始备份

· --safe-slave-backup-timeout:默认300秒,每3s进行一次重试检查

· --incremental:增量备份,但是进行恢复的时候只能恢复到备份那一刻,不够灵活,所以一般不推荐

· --incremental-basedir:指定增量备份所依赖的上一次备份

· --use-memory:指定恢复数据时使用的内存大小


四、Xtrabackup备份说明

在使用xtrabackup进行备份的过程中会输出很多信息,比如当前正在复制哪张表、备份完成等信息。备份期间如果有新数据产生会被记录在一个innobackup_log文件中,所以xtrabackup备份完成后的数据是接近备份完成那一刻而不是备份起始那一刻的

在指定的备份目录中除了MySQL数据文件还会创建以下关键文件:

· xtrabackup_binlog_info该文件在prepare后会产生,记录了备份时binlog的Position和GTID信息,主要用于主从部署

· xtrabackup_slave_info如果是通过从库进行备份就应该关注该文件,它记录了从库已经应用到的日志位置点,如果通过从库备份而使用xtrabackup_binlog_info,则看到的是从库自己的binlog position信息,而非主库的

· xtrabackup_binlog_pos_innodb在prepare了日志产生该文件,它也是用于记录position信息,但是经过实际测试发现在部分场景下会丢失一个事务(主要是MyISAM引擎下发生)

#如果是对开启了GTID的从库进行备份,将提示扩展新从库的语法
cat xtrabackup_slave_info
SET GLOBAL gtid_purged='xxxxxxxxxxxxxx:n-n'
change master to master_auto_position=1


· xtrabackup_checkpoint:记录用于增量备份的LSN信息,LSN记录了每一次备份时的起始点和结束点,通常上一次的结束点和下一次的起始点是连续的(如果开启了GTID的话会有9的误差)

xtrabackup4.png 


xtrabackup5.png


五、Xtrabackup备份示例

1、使用xtrabackup进行全量备份与恢复

#backup代表开始备份;target-dir指定备份存放路径
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=123456 --backup --target-dir=/data/backup  

#prepare将日志中还未提交的事务应用到备份数据中,确保数据一致性
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=123456 --prepare --target-dir=/data/backup 

#还原备份数据到数据目录
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=123456 --move-back --target-dir=/data/backup


2、使用xtrabackup进行本地+压缩备份与恢复

xtrabackup8以后默认压缩算法由lz4修改为ZSTD,文件后缀为.zst

#压缩备份
xtrabackup --defaults-file=/etc/my.cnf --backup --user=root --password=123456 --compress --compress-threads=8 --target-dir=/data/backup

#使用--decompress解压,--remove-original选项可以自动删除压缩包,没有加该选项的话在执行--copy-back时也不会将压缩包拷贝到数据目录
xtrabackup --decompress --remove-original --target-dir=/data/mysql_backup/ 

#应用日志
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=123456 --prepare --target-dir=/data/backup 

#还原备份数据到数据目录
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=123456 --move-back --target-dir=/data/backup


3、使用xtrabackup进行异地+压缩+流式备份与恢复

xtrabackup8以后默认压缩算法由lz4修改为ZSTD,由于使用了xbstream流备份,需要先解压xbstream文件再解压ZSTD文件,解压后文件后缀为.zst

#xtrabackup 8.0 备份过程
xtrabackup --defaults-file=${MYCNF} --user=${BACKUP_USER} --password=${BACKUP_PASSWORD} --backup --compress --compress-threads=8 --stream=xbstream 2>>"${BACKUP_LOG}" | sshpass -p ${SSH_PASSWORD} ssh -o StrictHostKeyChecking=no root@${REMOTE_BACKUP_HOST}  "cat - >$REMOTE_BACKUP_DIR/${BACKUP_FILE}"

#解压xbstream
xbstream -v -x < /data/backup/full_backup.xb.lz4 -C /data/backup/restore/

#解压lz4
xtrabackup --decompress --target-dir=/data/backup/restore/

#prepare与还原
xtrabackup --prepare --target-dir=/data/backup/restore/
xtrabackup --defaults-file=/etc/my.cnf --move-back --target-dir=/data/backup/restore/
chown -R mysql. /data/your_database_dir


4、使用xtrabackup在从库进行异地流备份(需要先行配置好SSH免密)

xtrabackup --defaults-file=$MYCNF --backup --slave-info --safe-slave-backup --user=$USER --password=$PWD  --stream=xbstream 2>>"$LOGFILE" | lz4 -B4 | ssh $TO_HOST -p24 "cat - >$TO_DIR/$BAKFILE"

#解压lz4,得到xbstream
lz4_decompress mysqlfull_2021_01_21_full.xbstream.lz4 mysqlfull_2021_01_21_full.xbstream

#解压xbstream
xbstream -x < mysqlfull_2021_01_21_full.xbstream  -C /data/mysql_restore/xtrabackup/


· 使用xtrabackup异地备份的同时完成解压

xtrabackup --defaults-file=/etc/my.cnf --backup --user=dba --password=Hzdba666#@888 --host=192.168.38.53 --port=3306  --stream=xbstream |lz4 -B4 |ssh -p24 192.168.38.60 "cat - | lz4 -d -B4 |xbstream -x -C /data/backup"


· 使用xtrabackup备份指定库

# 备份指定库
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=123456 --backup --databases="database1 database2 database3" --target-dir=/data/backup

# 备份指定表
xtrabackup --defaults-file=/etc/my.cnf --user=root --password=123456 --backup --databases="database1.table1 database1.table2" --target-dir=/data/backup


· 使用xtrabackup打包备份

#tar形式备份与解压
xtrabackup --defaults-file=/etc/my.cnf --user=dba --password=123456 --backup --stream=tar --target-dir=/data/backup | gzip > /data/backup/backup.tar.gz 
tar izxvf /data/backup/backup.tar.gz 

#流格式备份与解压
xtrabackup --defaults-file=/etc/my.cnf --user=dba --password=123456 --backup --stream=xbstream --target-dir=/data/backup 1 > /data/backup/backup.xbstream
xbstream -x  < /data/backup/backup.xbstream -C /data/backup  #将流备份文件


· innobackupex加密备份

openssl rand -base64 24  #得到一串加密码
echo -n "pxT5aEDWzasNZw==" > /data/backup/key
innobackupex --default-file=/etc/my.cnf --user=dba --password=123456 --encrypy=AES256 --encrypt-key-file=/data/backup/key #加密备份
xtrabackup --decrypy=AES256 --encrypt-key="pxT5aEDWzasNZw=="  --target-dir=/data/backup/fullback --remove-original#解密,之后再用innobackup apply-log和--copy-back


· innobackupex增量备份与恢复(为了防止某个增量备份异常而影响后续所有增量备份,在实际工作中不建议使用增量备份,而是采用全备+binlog的形式)

· 对全量备份进行增量备份

innobackupex --incremental /data/backup --incremental-basedir=/data/backup/full_backup  #第一次增量备份需要指定完整备份
innobackupex --incremental /data/backup --incremental-basedir=/data/backup/incremental_1  #第二次增量备份时指定上一次增量或者全量目录


· 恢复增量备份

在对增量备份进行恢复时,在对最后一次增量备份进行操作前,需要先对其他所有备份使用--apply-log与--redo-only选项表示只应用redo log日志进行前滚,而不应用undolog回滚。因为有可能一个事件在第一次备份时并没有提交完成而是在第二次备份时才执行完成,所以为了防止事件被错误回滚,将回滚操作放在最后一次增量备份上

innobackupex --apply-log  --redo-only  BASE-DIR   #首先应用完整备份数据 
innobackupex --apply-log  --redo-only  BASE-DIR --incremental-dir=incremental-dir-1  #前滚增量备份
innobackupex --apply-log   BASE-DIR --incremental-dir=incremental-dir-2  #最后一次增量备份不用redo-only
innobackupex --copy-back  BASE-DIR  #使用合并后的完整备份目录进行--copy-back即可
chown -R mysql.mysql /mysqldata


· 最后通过binlog日志恢复未备份的数据,只要在恢复了全量数据后查看下xtrabackup_binlog_info文件就可以得知需要从哪儿开始恢复

cat xtrabackup_binlog_info  #假设这里记录到了binlog.000001的23874这个位置
mysqlbinlog --start-position=23874 binlog.000001 binlog.00002 binlog.00003 | mysql -uroot -p  #将23874之后的数据恢复,也可以先重定向到一个文本中检查后再手动导入


评论