xtrabackup物理备份

1.xtrabackup介绍

mysqldump备份方式是采用逻辑备份,其最大的缺陷就是备份和恢复速度都慢,对于一个小于50G的 数据库而言,这个速度还是能接受的,但如果数据库非常大,那再使用mysqldump备份就不太适合了。

这时就 需要一种好用又高效的工具,xtrabackup就是其中一款,号称免费版的InnoDB HotBackup。Xtrabackup实现是 物理备份,而且是物理热备 目前主流的有两个工具可以实现物理热备:ibbackup和xtrabackup;ibbackup是商 业软件,需要授权,非常昂贵。

而xtrabackup功能比ibbackup还要强大,但却是开源的。

备份命令介绍

Xtrabackup安装完成后有4个可执行文件:

  1. xtrabackup 是专门用来备份InnoDB表的,和mysql server没有交互;

  2. innobackupex 是一个封装xtrabackup的Perl脚本,支持同时备份innodb和myisam,但在对myisam备份时需要加一个全局的读锁。

  3. xbcrypt 加密解密备份工具

  4. xbstream 流传打包传输工具,类似tar

Xtrabackup中主要包含两个工具:

​ xtrabackup:是用于热备份innodb, xtradb表中数据的工具,支持在线热备 份,可以在不加锁的情况下备份Innodb数据表,不过此工具不能操作Myisam引擎表;

​ innobackupex:是将 xtrabackup进行封装的perl脚本,能同时处理Innodb和Myisam,但在处理Myisam时需要加一个读锁。由于操Myisam时需要加读锁,这会堵塞线上服务的写操作,而Innodb没有这样的限制,所以数据库中Innodb表类 型所占的比例越大,则越有利。

percona-backupxtra对InonoDB会进行增量备份,面对MyISAM的数据进持完全备份。

1 xtrabackup只能备份innodb和xtradb两种引擎的表,而不能备份myisam引擎的表;

2 innobackupex是一个封装了xtrabackup的Perl脚本,支持同时备份innodb和myisam,但在对myisam备份时需要加一个全局的读锁。还有就是myisam不支持增量备份。

所以总的来说,常用的还是innobackupex

物理备份恢复流程

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

xtrabackup在innodb表备份恢复的流程

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

备份原理

824fb193d6ebdb651b515298d8fb538f1603429914947

  1. 首先会启动一个xtrabackup_log后台检测的进程,实时检测mysql redo的变化,一旦发现redo有新的日志写入,立刻将日志写入到日志文件xtrabackup_log中

  2. 复制innodb的数据文件和系统表空间文件idbdata1到对应的以默认时间戳为备份目录的地方

  3. 复制结束后,执行flush table with read lock操作

  4. 复制.frm .myd .myi文件

  5. 并且在这一时刻获得binary log 的位置

  6. 将表进行解锁unlock tables

  7. 停止xtrabackup_log进程

xtrabackup备份优点

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

功能:

  • 在不暂停数据库的情况下创建热InnoDB备份
  • MySQL 进行增量备份
  • 将压缩的MySQL备份流式传输到另一台服务器
  • 在线在MySQL服务器之间移动表
  • 轻松创建新的MySQL复制副本
  • 在不增加服务器负载的情况下备份MySQL

2.xtrabackup安装

配置好yum源,包括epel源

下载地址:https://www.percona.com/downloads/Percona-XtraBackup-2.4/LATEST/

官方文档地址:https://www.percona.com/doc/percona-xtrabackup/2.4/index.html#

#安装依赖
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL libev

方法一:通过配置yum repository安装

官方文档地址:https://www.percona.com/doc/percona-xtrabackup/2.4/installation/yum_repo.html#installing-percona-xtrabackup-from-percona-yum-repository

#配置repository
yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm

#查看
[root@localhost ~]# yum list | grep percona | grep xtrabackup
percona-xtrabackup.x86_64                  2.3.10-1.el7               percona-release-x86_64
percona-xtrabackup-22.x86_64               2.2.13-1.el7               percona-release-x86_64
percona-xtrabackup-22-debuginfo.x86_64     2.2.13-1.el7               percona-release-x86_64
percona-xtrabackup-24.x86_64               2.4.23-1.el7               percona-release-x86_64
percona-xtrabackup-24-debuginfo.x86_64     2.4.23-1.el7               percona-release-x86_64
percona-xtrabackup-80.x86_64               8.0.25-17.1.el7            percona-release-x86_64
percona-xtrabackup-80-debuginfo.x86_64     8.0.25-17.1.el7            percona-release-x86_64
percona-xtrabackup-debuginfo.x86_64        2.3.10-1.el7               percona-release-x86_64
percona-xtrabackup-test.x86_64             2.3.10-1.el7               percona-release-x86_64
percona-xtrabackup-test-22.x86_64          2.2.13-1.el7               percona-release-x86_64
percona-xtrabackup-test-24.x86_64          2.4.23-1.el7               percona-release-x86_64
percona-xtrabackup-test-80.x86_64          8.0.25-17.1.el7            percona-release-x86_64

#启用仓库
[root@localhost ~]# percona-release enable-only tools release
* Disabling all Percona Repositories
* Enabling the Percona Tools repository
<*> All done!


#安装
yum install percona-xtrabackup-24

方法二:通过rpm包安装

根据下载地址,选择版本下载链接

https://www.percona.com/downloads/Percona-XtraBackup-2.4/LATEST/

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

#安装
yum localinstall percona-xtrabackup-24-2.4.4-1.el7.x86_64.rpm

卸载

yum remove percona-xtrabackup-24

3.备份和恢复使用

文档:https://www.percona.com/doc/percona-xtrabackup/2.4/index.html#prerequisites

innobackupex文档:https://www.percona.com/doc/percona-xtrabackup/2.4/howtos/recipes_ibkx_local.html

3.1备份所需要的的最小权限

备份数据库的用户需要具有相应权限,如果要使用一个最小权限的用户进行备份,则可基于如下 命令创建此类用户:

#创建用户
mysql> create user 'bkpuser'@'localhost' identified by '123456';
#回收用户所有权限
mysql> revoke all privileges,grant option from 'bkpuser'@'localhost';
#授权有关备份的相应权限
mysql> grant reload,lock tables,replication client, process on *.* to 'bkpuser'@'localhost'; 
mysql> flush privileges; 

3.2全备

语法:

#创建备份文件存放目录
mkdir -p /backup/mysqlbackup/{full,inc}
#full:全备存放的目录;inc:增量备份存放的目录 

innobackupex --defaults-file=/data/mysql/mysql3306/my3306.cnf --user=root --password=123456  --socket=/data/mysql/mysql3306/mysql.sock --no-timestamp /backup/mysqlbackup/full/all_3306_`date +%Y%m%d`

......
210819 01:37:16 [00]        ...done
xtrabackup: Transaction log of lsn (5592292) to (5592301) was copied.
210819 01:37:16 completed OK!

注:--defaults-file=/etc/my.cnf 指定mysql的配置文件my.cfg,如果指定则必须是第一个参数。/path/to/BACKUP-DIR/指定备份所存放的目标目录,备份过程会创建一个以当时备份时间命名的目录存放备份 文件。

备份选项:

--user指定连接数据库的用户名
--password指定连接数据库的密码
-defaults-file指定数据库的配置文件,innobackupex要从其中获取datadir等信息
--database指定要备份 的数据库,这里指定的数据库只对MyISAM表有效,对于InnoDB 数据来说都是全备(所有数据库中的 InnoDB数据都进行了备份,不是只备份指定的数据库,恢复时也一样);
--no-timestamp 不使用时间戳作为备份目录名
/backup/mysqlbackup/full是备份文件的存放位置。

备份产生文件说明

[root@localhost ~]# ll /backup/mysqlbackup/full/all_3306_20210819/
total 12340
-rw-r-----. 1 root root      426 Aug 19 01:37 backup-my.cnf
-rw-r-----. 1 root root      389 Aug 19 01:37 ib_buffer_pool
-rw-r-----. 1 root root 12582912 Aug 19 01:37 ibdata1
drwxr-x---. 2 root root     4096 Aug 19 01:37 mysql
drwxr-x---. 2 root root     8192 Aug 19 01:37 performance_schema
drwxr-x---. 2 root root     8192 Aug 19 01:37 sys
drwxr-x---. 2 root root       48 Aug 19 01:37 test
-rw-r-----. 1 root root       63 Aug 19 01:37 xtrabackup_binlog_info
-rw-r-----. 1 root root      113 Aug 19 01:37 xtrabackup_checkpoints
-rw-r-----. 1 root root      673 Aug 19 01:37 xtrabackup_info
-rw-r-----. 1 root root     2560 Aug 19 01:37 xtrabackup_logfile
**各文件说明:**
(1)xtrabackup_checkpoints ——备份类型(如完全或增量)、备份状态(如是否已经为prepared 状态)和LSN(日志序列号)范围信息; 每个InnoDB页(通常为16k大小)都会包含一个日志序列号,即LSN。LSN是 整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的。
(2)xtrabackup_binlog_info —— mysql服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事 件的位置。
(3)xtrabackup_binlog_pos_innodb ——二进制日志文件及用于InnoDB或XtraDB表的二进制日志文件的当前 position。
(4)xtrabackup_binary ——备份中用到的xtrabackup的可执行文件;
(5)backup-my.cnf ——备份命令用到的配置选项信息;

3.3还原完全备份

准备(prepare)一个完全备份 一般情况下,在备份完成后,数据尚且不能用于恢复操作, 因为备份的数据中可能会包含尚未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文 件仍处理不一致状态。

“准备”的主要作用正是通过回滚未提交的事务及同步已经提交的事务至数据文件也使得 数据文件处于一致性状态。在准备(prepare)过程结束后,InnoDB表数据已经前滚到整个备份结束的点,而 不是回滚到xtrabackup刚开始时的点。

语法:

innobackupex --apply-log [--use-memory=B] 全备的basedir

在实现“准备”的过程中,innobackupex通常还可以使用--use-memory选项来指定其可以使用的内存的大小,默 认通常为100M。

如果有足够的内存可用,可以多划分一些内存给prepare的过程,以提高其完成速度。

innobackupex --apply-log /backup/mysqlbackup/full/all_3306_20210819/

......
InnoDB: Starting shutdown...
InnoDB: Shutdown completed; log sequence number 5592616
210819 01:42:44 completed OK!

3.4恢复备份

innobackupex命令的--copy-back选项用于执行恢复操作,其通过复制所有数据相关的文件至mysql服务器 DATADIR目录中来执行恢复过程。innobackupex通过backup-my.cnf来获取DATADIR目录的相关信息。

#将完全还原的备份拷贝到要恢复的basedir目录
#当然也可以手动cp到指定的basedir目录
innobackupex --defaults-file=/data/mysql/mysql3306/my3306.cnf --copy-back /backup/mysqlbackup/full/all_3306_20210819/

#恢复权限
chown -R mysql.mysql /data/mysql/mysql3306/data/

4.增量备份

一般备份binlog即可,很少使用xtrabackup的增量备份

  • 增量备份的方式,是基于上一次全备的基础进行增量
  • 增量备份无法单独恢复,必须基于上次的全备或者增量
  • 所有增量必须按顺序合并到全备中

官方文档:https://www.percona.com/doc/percona-xtrabackup/2.4/howtos/recipes_ibkx_inc.html

语法:

增量;

innobackupex --incremental /path/to/inc/dir \
  --incremental-basedir=$FULLBACKUP --user=USER --password=PASSWORD
innobackupex --user=root --password=123456 --no-timestamp --incremental /backup/mysqlbackup/inc/all_inc1_3306_`date +%Y%m%d` --incremental-basedir=/backup/mysqlbackup/full   &>/tmp/inc1.log

--incremental 接生成的增量文件位置
--incremental-lsn 或 --incremental-basedir 都可以
--incremental-basedir 默认传递给 xtrabackup,

--incremental-dir=name 在那个目录基础上增量

可以省略--incremental

恢复语法:

innobackupex --apply-log --redo-only $FULLBACKUP
 --incremental-dir=$INCREMENTALBACKUP
 --use-memory=1G --user=DVADER --password=D4RKS1D3

4.1增量备份和恢复示例

增量备份也可以备份binlog来实现

案例:

每周23:00进行备份,周日进行全备,其余每天增量

结果在周三增量后的一段时间,库被删了

1.删除之前的备份,并在周日进行了一次全备
innobackupex --defaults-file=/data/mysql/mysql3306/my3306.cnf --user=root --password=123456  --socket=/data/mysql/mysql3306/mysql.sock --no-timestamp /backup/mysqlbackup/full/full_3306

2.创建一些表和数据,模拟周一数据的变化
	create database test;
	use test;
	create table t1(id int);
	insert into t1 values(1),(2),(3);
	commit;

3.周一进行第一次增量备份
innobackupex --user=root --password=123456 --socket=/data/mysql/mysql3306/mysql.sock --no-timestamp --incremental  --incremental-basedir=/backup/mysqlbackup/full/full_3306  /backup/mysqlbackup/inc/inc1_3306 &>/tmp/inc1.log

4.模拟周二的数据变化
	create table t2 (id int);
	insert into t2 values(1),(2),(3);
	commit;
	
5.周二增量备份
innobackupex --user=root --password=123456 --socket=/data/mysql/mysql3306/mysql.sock --no-timestamp --incremental /backup/mysqlbackup/inc/inc2_3306 --incremental-basedir=/backup/mysqlbackup/inc/inc1_3306  &>/tmp/inc2.log

6.周三误删数据库
	create table t3 (id int);
	insert into t3 values(1),(2),(3);
	commit;
	drop database test;

注:第二次增量备份--incremental-basedir指向上一次增量备份文件的位置。

恢复思路:

1.先停相关业务和自动备份脚本

2.检查备份,包括:周日的full、周一inc1、周三的inc2、周三的完整二进制日志

3.整理备份,截取关键二进制日志(周三的inc2到删库之间的binlog)

4.在测试库进行备份恢复和日志恢复

5.进行测试,无误后开启业务(或是将部分数据恢复到正式库)

恢复过程

1.检查备份
 cat inc2_3306/xtrabackup_binlog_info
 
mysql-bin.000001        2757    cc3b4aab-00b4-11ec-9113-000c290c7222:1-13
#在16上

SET @@SESSION.GTID_NEXT= 'cc3b4aab-00b4-11ec-9113-000c290c7222:16'
drop database test 

#16删库所以我们需要的是13-15
cc3b4aab-00b4-11ec-9113-000c290c7222:13-15

2.备份整理(apply-log)+合并备份(full+inc1+inc2)
(1)	整理全备,还原完全备份
#准备增量备份与完整备份有点不同,必须在每个备份上重放已提交的事务,,注意加上-redo-only
# innobackupex --apply-log --redo-only /backup/mysqlbackup/full/full_3306/ --user=root --password=123456  --socket=/data/mysql/mysql3306/mysql.sock


(2) 合并inc1到full中
# innobackupex --apply-log --redo-only /backup/mysqlbackup/full/full_3306/ --incremental-dir=/backup/mysqlbackup/inc/inc1_3306/ --user=root --password=123456  --socket=/data/mysql/mysql3306/mysql.sock

(3)合并inc2到full中
# innobackupex --apply-log --redo-only /backup/mysqlbackup/full/full_3306/ --incremental-dir=/backup/mysqlbackup/inc/inc2_3306/ --user=root --password=123456  --socket=/data/mysql/mysql3306/mysql.sock



3.截取周二23点增量到周三drop之前的binlog(如果是gtid就截取gtid,一样的,本质都是截取binlog)

#如果是gtid
#如果要跳过某些gtid不截取需要使用参数--exclude-gtids=''
#mysqlbinlog --skip-gtids --include-gtids='cc3b4aab-00b4-11ec-9113-000c290c7222:13-16' /data/mysql/mysql3306/logs/mysql-bin.000001 >/backup/mysqlbackup/binlog.sql


4.进行恢复
#删除datadir的文件后在把full的拷贝过来
#或者谨慎起见,将full的data拷贝到新建的目录中,然后将mysql配置文件的datadir=新建目录的路径
rm -rf /data/mysql/mysql3306/data/*
cp -ar /backup/mysqlbackup/full/full_3306/* /data/mysql/mysql3306/data/

chown -R mysql.mysql /data/mysql/mysql3306/data/

systemctl restart mysqld

#source截取的sql,验证
mysql -S /data/mysql/mysql3306/mysql.sock -uroot -p123456

#test库回来了
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
5 rows in set (0.00 sec)

#周二增量之前的都回来了
mysql> use test
Database changed
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t1             |
| t2             |
+----------------+
2 rows in set (0.00 sec)

mysql> select * from t1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

mysql> select * from t2;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

#恢复周二到周三删库之间的数据
mysql> set sql_log_bin=0;
mysql> source /backup/mysqlbackup/binlog.sql
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t1             |
| t2             |
| t3             |
+----------------+
3 rows in set (0.00 sec)

mysql> select * from t3;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
+------+
3 rows in set (0.00 sec)

4.2恢复单个表(表空间迁移)

有时候备份很大,而只误删了某个表,这个表可能只有几M

要快速恢复表,最简单的还是表空间迁移

#假如迁移test表
#原库上
1.确保test表更新刷新到磁盘,加锁阻止写操作
	flush table test for export;
2.在数据目录拷贝表文件(.ibd、.cfg、.cfp)到目标数据目录
	cp test.* .../root/
3.解锁表
	unlock tables;
	
#目标库上
1.拷贝表结构
CREATE TABLE `test` (
  `id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

2.建表后将产生两个文件(.frm 和 .ibd),需要删除独立表空间文件( .ibd 文件),以便从 database1复制表空间过来
alter table test discard tablespace;

3.复制拷贝过来的文件(.ibd和.cf*),.frm一定要用库自己的,更改权限
cp -ar /root/test.ibd .../mysql/data/test/
cp -ar /root/test.cfg .../mysql/data/test/
chown mysql:mysql test.*

4.导入表空间
alter table test import tablespace;

关于xtrabackup2.4和8.0

由于MySQL 8.0数据目录,以及redo格式的种种变化,新的Xtrabackup for MySQL 8.0,仅仅提供给MySQL 8.0(以及Percona自己基于MySQL 8.0改的Percona Server)

对于5.x版本,依然需要使用XtraBackup 2.4来备份,当然,也宣告着,很多MySQL自动化备份脚本需要改的地方更多了.

2.4对应5.*之前版本

8.0对应mysql8.*版本

多个版本不能同时存在,用yum同时安装的话会有冲突

Error: percona-xtrabackup-80 conflicts with percona-xtrabackup-24-2.4.4-1.el6.x86_64
posted @ 2021-08-20 10:51  EverEternity  阅读(370)  评论(0编辑  收藏  举报