xtrabackup全备与增备
目录
1.3.1 下载percona-xtrabackup的rpm包:(本次使用). 2
1.3.2 下载
libev-4.15-7.el7.x86_64.rpm:(本次使用). 3
3.3.2 将第一次增备加载至全备中(mysql启动状态执行). 5
3.3.3 将第二次增备份同样加载至全备中(mysql启动状态执行). 6
--defaults-file=[MY.CNF]:... 8
1. 环境介绍
1.1 测试环境:
OS:CentOS Linux release 7.6.1810 (Core) IP地址:1.1.1.10/11 VMware
DB:MySQL 8.0.23 (rpm安装,默认配置)
Xtrabackup:percona-xtrabackup-80-8.0.23-16.1.el7.x86_64.rpm
提示:
xtrabackup版本依赖于mysql版本
1.2 xtrabackup简介
Percona-xtrabackup是 Percona公司开发的,对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工具InnoDB
Hotbackup的一个很好的替代品。
Xtrabackup有两个主要的工具:xtrabackup、innobackupex
Ø xtrabackup只能备份InnoDB和XtraDB两种数据表,而不能备份MyISAM数据表
Ø innobackupex-1.5.1则封装了xtrabackup,是一个脚本封装,所以能同时备份处理innodb和myisam,但在处理myisam时需要加一个读锁
1.3 xtrabacku及依赖下载:
1.3.1 下载percona-xtrabackup的rpm包:(本次使用)
wget https://downloads.percona.com/downloads/Percona-XtraBackup-LATEST/Percona-XtraBackup-8.0.23-16/binary/redhat/7/x86_64/percona-xtrabackup-80-8.0.23-16.1.el7.x86_64.rpm
percona-xtrabackup-80-8.0.23-16.1.el7.x86_64.rpm
安装后有xtrabackup、xbcloud、xbstream、xbcrypt、xbcloud_osenv、xbrlapi)
1.3.2 下载
libev-4.15-7.el7.x86_64.rpm:(本次使用)
wget http://mirror.centos.org/centos/7/extras/x86_64/Packages/libev-4.15-7.el7.x86_64.rpm
1.3.3 下载qpress(db解压依赖软件)
wget https://repo.percona.com/yum/release/7/RPMS/x86_64/qpress-11-1.el7.x86_64.rpm
1.4 安装xtrabackup
yum -y install libev-4.15-7.el7.x86_64.rpm qpress-11-1.el7.x86_64.rpm
percona-xtrabackup-80-8.0.23-16.1.el7.x86_64.rpm
安装后有xtrabackup、xbcloud、xbstream、xbcrypt、xbcloud_osenv、xbrlapi命令
2. 备份数据库
2.1 创建备份用户:
CREATE USER 'xbak_user'@'localhost'
IDENTIFIED BY 'Passw0rd#123';
GRANT BACKUP_ADMIN, PROCESS, RELOAD, LOCK
TABLES, REPLICATION CLIENT ON *.* TO 'xbak_user'@'localhost';
GRANT SELECT ON
performance_schema.log_status TO 'xbak_user'@'localhost';
FLUSH PRIVILEGES;
2.2 全备
mkdir -p
/home/mysql-bak/{full_back,increment}
xtrabackup
--user=root --password=Passw0rd#123 --backup --compress --compress-threads=4
--target-dir=/home/mysql-bak/full_increment_back/full-202109021544
--backup:表示该操作为备份操作
--compress:压缩备份文件
--compress-threads=4:用4个线程并行压缩
--target-dir:指定备份文件的存放路径
--user:备份使用的数据库用户
--password:该用户的密码
--socket:指定socket启动文件路径(可选)
2.3 基于全备的增量备份
xtrabackup --user=root --password=Passw0rd#123
--backup --compress --compress-threads=4
--target-dir=/home/mysql-bak/full_increment_back/inc-202109021551
--incremental-basedir=/home/mysql-bak/full_increment_back/full-202109021544
--incremental-basedir:表示在某某备份的基础上进行增量备份
2.4 在上一次增备的基上进行增量备份
xtrabackup --user=root --password=Passw0rd#123
--backup --compress --compress-threads=4
--target-dir=/home/mysql-bak/full_increment_back/inc-202109021555
--incremental-basedir=/home/mysql-bak/full_increment_back/inc-202109021551
3. 恢复数据库
3.1 解压
xtrabackup
--decompress --remove-original
--target-dir=/home/mysql-bak/full_increment_back/full-202109021544
--remove-original:表示解压后删除 .qp 的压缩文件,只保留解压后的文件
xtrabackup
--decompress --remove-original
--target-dir=/home/mysql-bak/full_increment_back/inc-202109021551
xtrabackup
--decompress --remove-original --target-dir=/home/mysql-bak/full_increment_back/inc-202109021555
3.2 全备恢复
3.2.1 关闭mysql
systemctl stop
mysqld
3.2.2 临时备份(很重要)
对当前数据目录进行临时备份,恢复成功后,该临时备份可删除。
cp -r /var/lib/mysql
/opt/backup
3.2.3 清空mysql的数据目录
rm -rf
/var/lib/mysql/*
3.2.4 用全备恢复数据库
xtrabackup
--copy-back --target-dir=/home/mysql-bak/full_back
--copy-back:将备份的数据copy至数据目录下(数据目录请查看参数文件my.cnf)
3.2.5 重新授权
恢复完成后,所有恢复的文件属主属组是当前用户,需要修改为mysql数据库读写用户
chown -R
mysql.mysql /var/lib/mysql
3.2.6 启动mysql
systemctl start
mysqld
3.3 全备+增量
恢复
提示:
在执行1、2、3步前,最好将备份都保留一份到其他目录(这样如果恢复不成功,还可以再重新操作)。因为还原过程中用到的备份文件在下次还原使用时会报错,报错如下:
xtrabackup: error: xtrabackup_logfile was
already used to '--prepare'.
3.3.1 预恢复全量备份(mysql启动状态执行)
xtrabackup --user=root --password=Passw0rd#123
--prepare --apply-log-only
--target-dir=/home/mysql-bak/full_increment_back/full-202109021544
--prepare:表示还原,即恢复
--apply-log-only:表示不回滚事务,因为后面有基于全备的增量备份,所以不需要回滚,如果没有增量备份则去掉该参数
3.3.2 将第一次增备加载至全备中(mysql启动状态执行)
xtrabackup --user=root --password=Passw0rd#123
--prepare --apply-log-only
--target-dir=/home/mysql-bak/full_increment_back/full-202109021544
--incremental-dir=/home/mysql-bak/full_increment_back/inc-202109021551
3.3.3 将第二次增备份同样加载至全备中(mysql启动状态执行)
xtrabackup --user=root --password=Passw0rd#123
--prepare --target-dir=/home/mysql-bak/full_increment_back/full-202109021544
--incremental-dir=/home/mysql-bak/full_increment_back/inc-202109021555
注意:
如果这是最后一次恢复,则需要回滚,即将未结束的事务回滚,去掉--apply-log-only参数
恢复阶段:可以将全备理解成一个集合,所有增备都需要汇总到这个集合(全备),才能进行完整的恢复操作
3.3.4 关闭mysql服务
systemctl
stop mysqld
3.3.5备份当前数据目录
在恢复失败后,可以用来还原到当前状态。临时目录,在恢复成功之后删除即可
cp
-r /var/lib/mysql /opt/backup
3.3.6 清空mysql的数据目录
rm
-rf /var/lib/mysql/*
3.3.7 恢复数据库
xtrabackup --copy-back --target-dir=/home/mysql-bak/full_back
--copy-back:将备份的数据copy至数据目录下(数据目录请查看my.cnf)
3.3.8 数据目录授权
chown -R mysql.mysql /mysql/data
3.3.9 启动mysql
systemctl start mysqld
4. 用法及相关参数介绍
用法:
Usage: [xtrabackup
[--defaults-file=#] --backup | xtrabackup [--defaults-file=#] --prepare]
[OPTIONS]
参数:
--target-dir:
destination directory,备份的目标目录。
如果目录不存在,xtrabackup将创建它。
如果目录确实存在且为空,则xtrabackup将成功;xtrabackup不会覆盖现有的文件;会在操作系统层面报错,文件存在。
--backup:
take backup to target-dir,执行备份到备份目录。
--prepare:
prepare a backup for starting mysql server
on the backup,为启动备份上的mysql服务器准备一个备份。(类似innobackupex --apply-log)
--apply-log-only:
此项较为重要。主要应用与增备,在常规备份中,执行两种操作以使数据库保持一致:从日志文件对数据文件重播已提交的事务,回滚未提交的事务。在准备备份时,必须跳过未提交事务的回滚,因为在备份时未提交的事务可能正在进行中,它们很可能在下一次增量备份中提交。您应该使用—apply-log-only选项来防止回滚阶段。
警告:如果您不使用—apply-log-only选项来防止回滚阶段,那么您的增量备份将是无用的。事务回滚后,无法应用进一步的增量备份。
--compress:
压缩,该选项告诉xtrabackup使用指定的压缩算法压缩所有输出数据,包括事务日志文件和元数据文件。目前唯一支持的算法是quicklz。与--compress-threads配合使用。
--compact:
通过跳过二级索引页创建一个紧凑的备份。
--compress-threads:
此选项指定xtrabackup用于并行数据压缩的工作线程数量。该选项默认为1。并行压缩(压缩线程)可以与并行文件复制(并行)一起使用。例如,--parallel=4 --compress
--compress-threads=2将创建4个I/O线程,读取数据并将其传输到2个压缩线程。
--copy-back:
将先前备份目录中的所有文件复制到其原始位置。除非指定强制非空目录选项,否则此选项不会复制现有文件。与MariaDB的Mariabackup的一项copy-back类似,做的时候确保datadir目录为空,你可以把原目录改个名字,再创建一个新的目录。
--databases:
此选项指定应该备份的数据库和表的列表,它支持database_name.table_name,比如只想备份test库下的su表,--databases=test.su。
--databases-exclude:
排除基于名称的数据库,基本语法与--databases相同,不想备份的数据库或表。注意点!此选项优先级高于 --databases。
--galera-info:
该选项创建xtrabackup_galera_info文件,该文件包含备份时的本地节点状态。选项应该在执行Percona XtraDB集群备份时使用。
--incremental:
该选项告诉xtrabackup创建增量备份。它被传递给xtrabackup子进程。指定此选项后,还可以指定--incremental-lsn或--incremental-basedir。如果两个选项都没有提供,则默认情况下将option——incremental-basedir传递给xtrabackup,设置为备份基本目录中的第一个时间戳备份目录。与原来旧版本--incremental类似。
--slave-info:
此选项在备份复制从属服务器时非常有用。它打印主服务器的二进制日志位置。它还将此信息作为更改主命令写入xtrabackup_slave_info文件。可以通过在这个备份上启动一个从服务器并发出一个CHANGE master命令来设置这个主服务器的新从服务器,该命令的二进制日志位置保存在xtrabackup_slave_info文件中。
--parallel=#:
指定备份时拷贝多个数据文件并发的进程数,默认值为1。
--defaults-file=[MY.CNF]:
唯一从给定文件读取默认选项,必须是个真实文件,必须在命令行第一个选项位置指定。
5. xtrabackup备份脚本
#!/bin/sh
#=========================================================================
## 备份工具:
## percona-xtrabackup-80-8.0.23-16
##
## 备份策略:
## (1)、全量备份
## 每周三周六01:00进行全量备份一次;
## 00 01 * * 3,6 /home/mysql-bak/mysql_backup.sh
inc >/dev/null 2>&1
## (2)、增量备份
## 每周一、二、四、五、日 01:00增量备份一次;
## 00 01 * * 0-2,4-5 /home/mysql-bak/mysql_backup.sh
inc >/dev/null 2>&1
##
#=========================================================================
# PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin
# 用户名
DB_USER="xbak_user"
# 密码
DB_PASS="Passw0rd#123"
# 端口
DB_PORT=13306
# socket文件
DB_SOCK="/tmp/mysql.sock"
## DB备份基路径
BACKUP_BASE_DIR="/home/mysql-bak/full_increment_back"
## 增量备份时,用到的基准目录列表文件
## 内容格式:基准目录|本次备份目录|备份类型【full|inc】
INC_BASE_LIST="${BACKUP_BASE_DIR}/incremental_basedir_list.txt"
## 备份工具路径
XTRABACKUP_PATH="/usr/bin/xtrabackup"
## MySQL配置路径
MYSQL_CNF_PATH="/etc/my.cnf"
## 线程数
THREAD_CNT=6
#=========================================================================
function print_help_info()
{
echo
"--------------------------------------------------------------"
echo "Usage: $0 full |
inc | help"
echo
"--------------------------------------------------------------"
echo ""
exit 1
}
[[ $# -lt 1 ]] && print_help_info
[[ -d ${BACKUP_BASE_DIR} ]] || mkdir -p ${BACKUP_BASE_DIR}
## 目录名默认精确到分钟,为避免意外情况,导致备份任务失败,可以精确到秒
CURRENT_BAK_PATH="${BACKUP_BASE_DIR}/"`date +%F_%H-%M-%S`
[[ -d ${CURRENT_BAK_PATH} ]] &&
CURRENT_BAK_PATH="${BACKUP_BASE_DIR}/"`date +%F_%H-%M-%S`
#=========================================================================
## 全量备份
if [[ "$1" == "full" ]]; then
${XTRABACKUP_PATH} --backup
--compress --compress-threads=4 --user=${DB_USER} --password=${DB_PASS}
--port=13306 --socket=/tmp/mysql.sock --target-dir=${CURRENT_BAK_PATH}
echo
"NULL|${CURRENT_BAK_PATH}|full" >> ${INC_BASE_LIST}
## 增量备份
elif [[ "$1" == "inc" ]]; then
## 基准目录列表文件不存在或者为空的情况,需要做一次全量备份
if [[ ! -f ${INC_BASE_LIST} || `sed '/^$/d'
${INC_BASE_LIST} | wc -l` -eq 0 ]]; then
${XTRABACKUP_PATH}
--backup --compress --compress-threads=4 --user=${DB_USER}
--password=${DB_PASS} --port=13306 --socket=/tmp/mysql.sock
--target-dir=${CURRENT_BAK_PATH}
echo
"NULL|${CURRENT_BAK_PATH}|full" >> ${INC_BASE_LIST}
## 不存在任何目录的情况,需要做一次全量备份,以避免增量备份失败
elif [[ `find
${BACKUP_BASE_DIR} -maxdepth 1 -type d | wc -l` -eq 1 ]]; then
${XTRABACKUP_PATH}
--backup --compress --compress-threads=4 --user=${DB_USER}
--password=${DB_PASS} --port=13306 --socket=/tmp/mysql.sock
--target-dir=${CURRENT_BAK_PATH}
echo
"NULL|${CURRENT_BAK_PATH}|full" >> ${INC_BASE_LIST}
## 在上一次备份的基础上,进行增量备份
else
PREV_BACKUP_DIR=`sed
'/^$/d' ${INC_BASE_LIST} | tail -1 | awk -F '|' '{print $2}'`
## 上次的备份目录不存在或者目录为空的情况,以避免人为删除的可能性【针对部分恶意删除的情况,目前还没有较好的检查方法】
if [[ ! -d
${PREV_BACKUP_DIR} || -z `ls ${PREV_BACKUP_DIR}` ]]; then
${XTRABACKUP_PATH}
--backup --compress --compress-threads=4 --user=${DB_USER}
--password=${DB_PASS} --port=13306 --socket=/tmp/mysql.sock
--target-dir=${CURRENT_BAK_PATH}
echo
"NULL|${CURRENT_BAK_PATH}|full" >> ${INC_BASE_LIST}
else
${XTRABACKUP_PATH}
--backup --compress --compress-threads=4 --user=${DB_USER} --password=${DB_PASS}
--port=13306 --socket=/tmp/mysql.sock --parallel=${THREAD_CNT} --no-timestamp
--target-dir=${CURRENT_BAK_PATH} --incremental-basedir=${PREV_BACKUP_DIR}
echo
"${PREV_BACKUP_DIR}|${CURRENT_BAK_PATH}|inc" >>
${INC_BASE_LIST}
fi
fi
elif [[ "$1" == "help" ]]; then
print_help_info
else
print_help_info
fi
## 删除30天前的数据备份
rm -rf ${BACKUP_BASE_DIR}/`date -d '30 days ago' +'%F'`_*
sed -i "/`date -d '30 days ago' +'%F'`/d"
${INC_BASE_LIST}
#=========================================================================
##The End




