1、XtraBackup 简介

Xtrabackup是一个对InnoDB做数据备份的工具、支持在线热备份 (备份时不影响数据读写)、是商业备份工具InnoDB Hotbackup的一个很好的替代品
它能对InnoDB和XtraDB存储引擎的数据库非阻塞地备份 (对于MyISAM的备份同样需要加表锁)、XtraBackup支持所有的Percona Server、MySQL、MariaDB和Drizzle

两个主要的工具

  • xtrabackup
  • innobackupex

xtrabackup: 只能备份InnoDB 和XtraDB两种数据表 (C、C++)
innobackupex: 则封装了xtrabackup、同时可以备份MyISAM 数据表 (perl语言)

版本变化

MySQL 8.0之前: 2.4.x 版本
MySQL 8.0之后: 8.0 版本

Xtrabackup 特点

备份过程快速、可靠
备份过程不会打断正在执行的事务
能够基于压缩等功能节约磁盘空间和流量
自动实现备份检验
还原速度快

XtraBackup 备份方式

物理备份
对于非Innodb表 (比如 myisam)、锁表cp数据文件、属于一种温备份
对于Innodb的表 (支持事务的)、不锁表、拷贝数据页、最终以数据文件的方式保存下来、把一部分 redo 和 undo一并备走、属于热备方式

面试题: XtraBackup 在 InnoDB 表备份恢复的流程

0、xbk备份执行的瞬间,立即触发ckpt,已提交的数据脏页,从内存刷写到磁盘,并记录此时的LSN号
1、备份时,拷贝磁盘数据页,并且记录备份过程中产生的redo和undo一起拷贝走,也就是checkpoint LSN之后的日志
2、在恢复之前,模拟Innodb”自动故障恢复”的过程,将redo (前滚) 与undo (回滚) 进行应用
3、恢复过程是cp 备份到原来数据目录下

2、安装 XtraBackup

官网: https://www.percona.com
下载: https://www.percona.com/downloads/
文档: https://www.percona.com/doc/percona-xtrabackup/LATEST/index.html
image.png

2.4 版本

二进制安装

  1. wget https://downloads.percona.com/downloads/Percona-XtraBackup-2.4/Percona-XtraBackup-2.4.21/binary/tarball/percona-xtrabackup-2.4.21-Linux-x86_64.glibc2.12.tar.gz
  2. tar xvf percona-xtrabackup-2.4.21-Linux-x86_64.glibc2.12.tar.gz

rpm包安装

#下载rpm包
wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.12/binary/redhat/7/x86_64/percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm

#安装
yum -y install percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm

#检查命令
which xtrabackup
which innobackupex

#卸载
yum -y remove percona-xtrabackup-24.x86_64

8.0版本

二进制安装

wget https://downloads.percona.com/downloads/Percona-XtraBackup-LATEST/Percona-XtraBackup-8.0.23-16/binary/tarball/percona-xtrabackup-8.0.23-16-Linux-x86_64.glibc2.17.tar.gz

rpm包安装

#下载rpm包
wget https://downloads.percona.com/downloads/Percona-XtraBackup-LATEST/Percona-XtraBackup-8.0.25-17/binary/redhat/7/x86_64/percona-xtrabackup-80-8.0.25-17.1.el7.x86_64.rpm

#安装
yum -y install percona-xtrabackup-80-8.0.25-17.1.el7.x86_64.rpm

#检查命令, 8.0 没有 innobackupex命令
which innobackupex

#卸载
yum -y remove percona-xtrabackup-80.x86_64

3、全备

3.1、全备介绍

拷贝数据库仓库下的数据
InnoDB: 热备、拷贝InnoDB的文件,备份期间截取变化的redo
非InnoDB: 全局锁,拷贝非InnoDB的文件
只能本地备份,本地socket文件连接

3.2、全备

前提条件

准备条件: 具有管理员权限的mysql账号, 配置文件
vim /etc/my.cnf
# 添加
[client]
socket=/tmp/mysql.sock

innobackupex

全备

格式:
innobackupex  --defaults-file=  --host=  --port=  --user=  --password=  --no-timestamp /xxx

#全备
innobackupex --defaults-file=/data/3307/conf/my.cnf --host=127.0.0.1 --port=3307  --user=root --password=123 --no-timestamp /root/full_`date +%F`

10813 16:36:04 completed OK!

准备

作用:
将redo进行重做, 已提交的写到数据文件, 未提交的使用undo回滚掉, 模拟了CSR的过程

准备:
innobackupex --apply-log /root/full_2021-08-13/

210813 16:38:56 completed OK!

恢复

cp -a /data/backup/full/* /data/3307/data/
或者
mv

xtrabackup

全备

格式:
xtrabackup  --defaults-file=  --host=  --port=  --user=  --password=  --no-timestamp  --backup  --target-dir=/xxx

全备:
xtrabackup --defaults-file=/data/3307/conf/my.cnf --host=127.0.0.1 --port=3307  --user=root --password=123 --no-timestamp --backup --target-dir=/root/full_`date +%F`

10813 16:36:04 completed OK!

准备

xtrabackup --prepare --target-dir=/root/full_2021-08-13/

210813 16:38:56 completed OK!

恢复

cp
mv

3.3、全备中重要文件

xtrabackup_binlog_info: 记录的是备份时刻,binlog的文件名字和当时的结束的position、GTID、可以用来作为截取binlog时的起点
xtrabackup_checkpoints: LSN信息
from_lsn = 0: 上次所到达的LSN号 (对于全备就是从0开始、对于增量有别的显示方法)
to_lsn = 160683027: 备份开始时间(ckpt)点数据页的LSN
last_lsn = 160683036: 备份结束后,redo日志最终的LSN
1、备份时刻、立即将已经commit过的、内存中的数据页刷新到磁盘(CKPT). 开始备份数据、数据文件的LSN会停留在to_lsn位置
2、备份时刻有可能会有其他的数据写入、已备走的数据文件就不会再发生变化了
3、在备份过程中、备份软件会一直监控着redo的undo、如果一旦有变化会将日志也一并备走、并记录LSN到last_lsn
从to_lsn —> last_lsn 就是、备份过程中产生的数据变化
xtrabackup_info: 备份信息总览
xtrabackup_logfile: 备份期间产生的redo变化

3.4、故障恢复演示

全备

xtrabackup --defaults-file=/data/3307/conf/my.cnf --host=127.0.0.1 --port=3307  --user=root --password=123 --no-timestamp --backup --target-dir=/root/full_`date +%F`

误操作

/etc/init.d/mysqld stop
rm -rf /data/3307/data/*

准备

xtrabackup --prepare --target-dir=/root/full_2021-08-13/

恢复

#修改数据目录所属组、所有者为mysql
cp -r /root/full_2021-08-13/* /data/3307/data/
chown -R mysql.mysql /data/3307/data/

#启动数据库
/etc/init.d/mysqld start

4、增量备份

4.1、介绍

每次增量一般是将上次备份作为参照物
自取读取上次备份文件中的 cat xtrabackup_checkpoints 中 to_lsn值、与当前checkpoints的lsn对比,备份变化过的数据页(page)
备份期间的新数据变化、通过redo自动备份
恢复数据时、需要把所有所需要的增量备份合并到全备中去、无法通过增量单独恢复数据,依赖于全备

4.2、增量备份过程演练

周日: full + 周一: inc1 + 周二: inc2 + 周三: inc3

备份前数据准备

create database xbk charset utf8mb4;
use xbk
create table full (id int);
insert into full values(1),(2),(3);
commit;

模拟周日23:00全备

innobackupex --user=root --password=123 --no-timestamp /data/backup/full_`date +%F`

模拟周一白天数据变化

use xbk
create table inc1 (id int);
insert into  inc1 values(1),(2),(3);
commit;

模拟周一23:00增量备份

参照物: —incremental-basedir=周日全备路径

innobackupex --user=root --password=123  --no-timestamp   --incremental --incremental-basedir=/data/backup/full_2020-05-12  /data/backup/inc1_`date +%F`

模拟周二白天数据变化

use xbk
create table inc2 (id int);
insert into  inc2 values(1),(2),(3);
commit;

模拟周二23:00增量备份

参照物: —incremental-basedir=周一增量备份路径

innobackupex --user=root --password=123  --no-timestamp   --incremental --incremental-basedir=/data/backup/inc1_2020-05-12  /data/backup/inc2_`date +%F`

模拟周三白天数据变化

use xbk
create table inc3(id int);
insert into  inc3 values(1),(2),(3);
commit;

模拟周三23:00增量备份

参照物: —incremental-basedir=周二增量备份路径

innobackupex --user=root --password=123  --no-timestamp   --incremental --incremental-basedir=/data/backup/inc2_2020-05-12  /data/backup/inc3_`date +%F`

模拟周四白天数据变化

use xbk
create table inc4(id int);
insert into  inc4 values(1),(2),(3);
commit;

补充: 备份巡检

[root@centos7 backup]# cat full_2021-02-25/xtrabackup_checkpoints 
backup_type = full-backuped  # 备份类型: 全备
from_lsn = 0
to_lsn = 82850480
last_lsn = 82850489
compact = 0
recover_binlog_info = 0

[root@centos7 backup]# cat inc1_2021-02-25/xtrabackup_checkpoints 
backup_type = incremental  # 备份类型: 增量备份
from_lsn = 82850480
to_lsn = 82873964
last_lsn = 82873973
compact = 0
recover_binlog_info = 0

inc1 中 from_lsn = 82850480 = full 中 to_lsn = 82850480  的值为合理

周四下午出现数据损坏, 如何恢复到误删除之前?

pkill mysqld
rm -rf /data/3307/data/*

4.3、增量备份恢复

恢复思路

我们有什么?
备份: full + inc1 + inc2 + inc3
binlog: 自全备以来的全量binlog

4.3.1、处理备份

需要将增量备份:inc1、inc2、inc3 按顺序依次合并到全备, 并进行prepare。
—redo-only:
This option should be used when preparing the base full
backup and when merging all incrementals except the last
one. This forces xtrabackup to skip the “rollback” phase
and do a “redo” only. This is necessary if the backup
will have incremental changes applied to it later. See
the xtrabackup documentation for details.

—redo-only:
从官方角度: 基础全备和合并所有增量 (排除最后一个) 都需要此参数
原理角度: 使所有备份合并时, LSN必须是连续的

准备全备 (基备)

注意: 此时需要加入 —redo-only

innobackupex --apply-log --redo-only /data/backup/full_2021-02-25

增量备份inc1合并到全备, 并且prepare

cd /data/backup/
innobackupex  --apply-log  --redo-only  --incremental-dir=inc1_2021-02-25  full_2021-02-25

#检验合并结果,to_lsn,[last_lsn]是相等的,表示备份是正常的
cat full_2021-02-25/xtrabackup_checkpoints | grep to_lsn
cat inc1_2021-02-25/xtrabackup_checkpoints | grep to_lsn

增量备份inc2合并到全备, 并且prepare

cd /data/backup/
innobackupex --apply-log --redo-only   --incremental-dir=inc2_2021-02-25/ full_2021-02-25/

# 检验合并结果
cat full_2021-02-25/xtrabackup_checkpoints | grep to_lsn
cat inc2_2021-02-25/xtrabackup_checkpoints | grep to_lsn

增量备份inc3合并到全备, 并且prepare

最后一次增量恢复, 不加—redo-only

innobackupex --apply-log   --incremental-dir=inc3_2021-02-25/ full_2021-02-25/

#检验合并结果
cat full_2021-02-25/xtrabackup_checkpoints 
cat inc3_2021-02-25/xtrabackup_checkpoints

将合并后全备再次prepare

innobackupex --apply-log  full_2021-02-25

 #检验合并结果
 cat full_2021-02-25/xtrabackup_checkpoints

4.3.2、恢复备份

mysqldump 恢复到备份开始时
XtraBackup 恢复到备份结束时

#恢复数据
innobackupex --copy-back /data/backup/full_2021-02-25

#授权数据目录
chown -R mysql.mysql /data/3307/data/

4.3.3、截取周三增量备份后 到 故障之前所有日志

#起点: inc3 备份完成后的位置点 
cat inc3_2021-02-25/xtrabackup_binlog_info 
mysql-bin.000002    2635    d2de3fa4-7742-11eb-96a1-000c2909345a:1-12

#终点: binlog 结尾
mysqlbinlog --skip-gtids --start-position=2635 /data/3307/binlog/mysql-bin.000002 > bin.sql

4.3.4、启动数据库, 恢复 binlog

#启动数据
/etc/init.d/mysqld start

#导入binlog截取的sql脚本
set sql_log_bin=0;
source /root/bin.sql
set sql_log_bin=1;

4.3.5、xbk恢复完成后, 清空所有日志 (binlog)

reset master;

4.3.6、立即再做个全备

innobackupex --user=root --password=123 --no-timestamp /data/backup/full

5、恢复单库单表

5.1、恢复单库

# 模拟全备
innobackupex --user=root --password=123 --no-timestamp /data/backup/full

# 准备全备 Prepared
innobackupex --apply-log /data/backup/full

# 模拟误删除数据库xbk
drop database xbk;

# 停止mysql服务进行恢复
/etc/init.d/mysqld stop

# 建一个临时目录,用于临时存储其它不需要恢复的库
mkdir -p /data/backup/bak

# 将全备中不需要恢复的库移动到临时目录
cd /data/backup/full
mv performance_schema sys mysql test oldboy world /data/backup/bak

# 将全备中的文件全部拷贝到数据目录下
\cp -a /data/backup/full/* /data/3307/data

# 赋予mysql用户权限
chown -R mysql.mysql /data/3307/data

# 启动mysql服务器,检查数据
/etc/init.d/mysqld start

# 数据恢复正常后,立马进行一个全备 !!!

5.2、恢复单表

# 省略全备、准备全备Prepared、过程

# 模拟误删除inc4表
mysql> use xbk
mysql> show tables;
mysql> drop table inc4;

mysql> create table inc4_bak(id int);
mysql> create table inc4 like inc4_bak;
mysql> alter table inc4 discard tablespace;

cd /data/backup/full/xbk
\cp -a inc4.ibd /data/3307/data/xbk
chown -R mysql.mysql /data/3307/data

mysql> alter table inc4 import  tablespace;

6、补充

xtrabackup 与 innobackupex 命令有略微参数差异, 可以用 xtrabackup —help 与 innobackupex —help 查看
可根据情况压缩、和其它参数