MySQL备份教程(2)物理备份之xtrabackup/innobackupex

Tanglu MySQL 2021-04-03 8459 0

一、物理备份与Xtrabackup介绍

通常将直接复制数据文件作为备份手段的方式称为物理备份,相比逻辑备份而言物理备份有着备份与还原速度更快、备份过程服务器负载更低、备份期间不锁表不用中断业务(MyISAM引擎依然存在FTWRL)等特点。最常用的物理备份方式是使用Percona Xtrabackup,该工具支持全量与增量备份,备份时会通过InnoDB中的checkpoint LSN记录数据位置,然后拷贝redo log和.idb文件,备份期间如果有新数据产生会被记录在一个innobackup_log文件中,所以xtrabackup备份完成后的数据是接近备份完成那一刻而不是备份起始那一刻的。Xtrabackup的缺点是在进行单表备份和恢复时比较麻烦,这种场景建议转为逻辑备份的方式


二、Xtrabackup安装方法

1、Percona官网推荐使用Yum方式安装,只需要配置好仓库地址即可

yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
yum install percona-xtrabackup-24.x86_64  #mysql 8以前都是使用该版本


2、如果是下载的rpm包手动安装,如果出现“ libev.so.4()(64bit) is needed by percona-xtrabackup-2.3.4-1.el7.x86_64”这样的报错,只需要配置好EPEL的yum源,再安装libev即可,如图:

xtrabackup2.png


3、安装好Xtrabackup后会提供xtrabackup和innobackup两个备份工具。xtrabackup主要针对innodb表来做备份,innobackupex实际是xtrabackup的软连接,其对xtrabackup进行了封装,主要存在目的是为了兼容非innod表备份,而在用innobackup备份innodb表时会自动调用xtrabackup。(xtrabackup在8.0版本已经不再支持innobackup)

xtrabackup3.png


三、xtrabackup\innobackupex常用选项

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

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

· --no-timestamp使用这个选项后,备份时不会创建一个以时间戳命名的目录
· --compress压缩备份数据,可以达到好几十倍的压缩率。恢复时需在apply-log之前增加--decompress解压步骤

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

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

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

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

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

· --slave-info :在从库进行备份时加上该参数后会在备份目录下生成xtrabackup_slave_info文件,该文件记录了主库的binlog position和GTID信息而非进行备份的从库的信息(线上实测发现在GTID模式下xtrabackup_slave_info记录的是从库的position,而非主库,传统模式下则是正常的,需要进一步排查)。这样在使用从库备份进行恢复或者部署新的从库时都可以找到正确的主库position。如果主库使用的传统复制模式并且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备份与还原教程

备份过程中会输出很多信息,比如当前正在复制哪张表、备份完成等信息。备份期间如果有新数据产生会被记录在一个innobackup_log文件中,所以xtrabackup备份完成后的数据是接近备份完成那一刻而不是备份起始那一刻的。在指定的备份目录中除了MySQL数据文件还会创建以下关键文件:

· xtrabackup_binlog_info:记录备份时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


1、xtrabackup备份方式

· 使用xtrabackup全量备份

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


· 使用xtrabackup在从库进行异地流备份,注意SSH免密一定要先配置好

/bin/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压缩备份,恢复先需要先解压

xtrabackup --defaults-file=${MYCNF} --backup  --user=dba --password=${PWD}  --compress --compress-threads=8 --target-dir=/data/mysql_backup/mysql_backup_`date +%F`_compress/ >> ${LOGFILE} 2>&1
xtrabackup --decompress --remove-original --target-dir=/data/mysql_backup/mysql_backup_`date +%F`_compress/  #先解压


· 使用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  #将流备份文件


2、xtrabackup还原步骤

xtrabackup --defaults-file=/etc/my3333.cnf --prepare --target-dir=/data/restore_mysql/  #还原前先应用日志
xtrabackup --defaults-file=/etc/my3333.cnf --move-back --target-dir=/data/restore_mysql/  


五、innobackupex备份与还原教程

1、innobackupex备份命令示例

· 使用innobackupex全量备份

innobackupex --defaults-file=/etc/my.cnf --user=root --password='123456'  /data/backup/


· 使用innobackupex备份指定库,需要注意的是MySQL系统库也要一同备份,否则还原会出问题

innobackupex --defaults-file=/etc/my.cnf --user=root --password='123456'  --databases="db1 db2" /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


2、innobackupex数据还原步骤

· apply-log:应用日志。因为备份过程中会将redo log中的更新也进行记录,里面包含尚未提交的事务。为避免数据不一致,在进行数据恢复前需要将这些未提交的事务进行回滚

innobackupex --defaults-file=/etc/my.cnf --apply-log  --user-memory=2G /backup/2016-03-29_17-28-37/


· 恢复备份前需要先停止MySQL服务并让数据目录为空

systemctl stop mysqld
rm -rf /var/lib/mysql/*


· --copy-back | --move-back 拷贝数据到datadir,move的方式会更快

innobackupex --defaults-file=/etc/my.cnf --copy-back /data/backup/2016-03-29_17-28-37/


· 修改权限为mysql用户后启动服务

chown -R mysql.mysql /data
mysqld_safe --defaults-file=/etc/my.cnf &

3、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之后的数据恢复,也可以先重定向到一个文本中检查后再手动导入


评论