MySQL之(2)数据备份与还原

xtrabackup 备份工具

xtrabackup 工具介绍

官网:www.percona.com

Xtrabackup备份工具:
percona提供的mysql数据库备份工具,惟一开源的能够对innodb和xtradb数据库进行热备的工具

手册:https://www.percona.com/doc/percona-xtrabackup/LATEST/index.html
下载: https://www.percona.com/downloads/

xtrabackup 特点:

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

范例: 最新版本下载安装:

https://www.percona.com/downloads/

[root@localhost ~]# ll
total 7820
-rw-------. 1 root root    1242 Apr  5 18:03 anaconda-ks.cfg
-rw-r--r--  1 root root    7786 Jul 30  2020 hellodb_innodb.sql
-rw-r--r--  1 root root 7992904 Mar 23 04:00 percona-xtrabackup-24-2.4.22-1.el7.x86_64.rpm

[root@localhost ~]# yum install -y percona-xtrabackup-24-2.4.22-1.el7.x86_64.rpm 
xtrabackup 用法

xtrabackup工具备份和还原,需要三步实现

  1. 备份:对数据库做完全或增量备份
  2. 预准备: 还原前,先对备份的数据,整理至一个临时目录
  3. 还原:将整理好的数据,复制回数据库目录中

xtrabackup 选项参考:

https://www.percona.com/doc/percona-xtrabackup/LATEST/genindex.html

备份:

innobackupex [option] BACKUP-ROOT-DIR

选项说明:

--user:#该选项表示备份账号
--password:#该选项表示备份的密码
--host:#该选项表示备份数据库的地址
--databases:#该选项接受的参数为数据库名,如果要指定多个数据库,彼此间需要以空格隔开;
如:"xtra_test dba_test",同时,在指定某数据库时,也可以只指定其中的某张表。
如:"mydatabase.mytable"。该选项对innodb引擎表无效,还是会备份所有innodb表
--defaults-file:#该选项指定从哪个文件读取MySQL配置,必须放在命令行第一个选项位置
--incremental:#该选项表示创建一个增量备份,需要指定--incremental-basedir
--incremental-basedir:#该选项指定为前一次全备份或增量备份的目录,与--incremental同时使用
--incremental-dir:#该选项表示还原时增量备份的目录
--include=name:#指定表名,格式:databasename.tablename

Prepare预准备

innobackupex --apply-log [option] BACKUP-DIR

选项说明:

--apply-log:#一般情况下,在备份完成后,数据尚且不能用于恢复操作,因为备份的数据中可能会包含尚
未提交的事务或已经提交但尚未同步至数据文件中的事务。因此,此时数据文件仍处理不一致状态。此选项作
用是通过回滚未提交的事务及同步已经提交的事务至数据文件使数据文件处于一致性状态
--use-memory:#和--apply-log选项一起使用,当prepare 备份时,做crash recovery分配的内存大
小,单位字节,也可1MB,1M,1G,1GB等,推荐1G
--export:#表示开启可导出单独的表之后再导入其他Mysql中
--redo-only:#此选项在prepare base full backup,往其中合并增量备份时候使用,但不包括对最后
一个增量备份的合并

还原:

innobackupex --copy-back [选项] BACKUP-DIR
innobackupex --move-back [选项] [--defaults-group=GROUP-NAME] BACKUP-DIR

选项说明:

--copy-back:#做数据恢复时将备份数据文件拷贝到MySQL服务器的datadir
--move-back:#这个选项与--copy-back相似,唯一的区别是它不拷贝文件,而是移动文件到目的地。这
个选项移除backup文件,用时候必须小心。使用场景:没有足够的磁盘空间同事保留数据文件和Backup副本
--force-non-empty-directories #指定该参数时候,使得innobackupex --copy-back或--moveback
选项转移文件到非空目录,已存在的文件不会被覆盖。如果--copy-back和--move-back文件需要从备
份目录拷贝一个在datadir已经存在的文件,会报错失败

还原注意事项:

1. datadir 目录必须为空。除非指定innobackupex --force-non-empty-directorires选项指定,否则--
copy-back选项不会覆盖
2. 在restore之前,必须shutdown MySQL实例,不能将一个运行中的实例restore到datadir目录中
3. 由于文件属性会被保留,大部分情况下需要在启动实例之前将文件的属主改为mysql,这些文件将
属于创建备份的用户, 执行chown -R mysql:mysql /data/mysql,以上需要在用户调用
innobackupex之前完成

案例:利用 xtrabackup 实现完全备份及还原

# 安装xtrabackup
[root@localhost ~]# ll
total 13452
-rw-------. 1 root root     1793 Sep  4  2020 anaconda-ks.cfg
-rw-r--r--. 1 root root    21352 Apr 13 14:43 data.img
-rw-r--r--. 1 root root     3020 Apr 13 10:40 httpds2.sh
-rw-r--r--. 1 root root 13738948 Mar 16 23:26 percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm

[root@localhost ~]# yum install -y percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm

# 在原主机做完全备份到/mysql/backup,登陆mysql有密码的需要写上
[root@localhost ~]# mkdir /mysql/backup -p
[root@localhost ~]# xtrabackup -uroot -p123456 --backup --target-dir=/mysql/backup/base

# 制作数据用于实现备份还原
mysql> source hellodb_innodb.sql

# 目标主机无需创建/mysql/backup目录,直接复制目录本身
[root@localhost ~]# scp -r /mysql/backup/ 172.31.0.18:/root

在目标主机上还原
# 安装软件mysql-8.0
[root@sz-kx-centos8 ~]# yum install -y mysql-server

1)预准备:确保数据一致,提交完成的事务,回滚未完成的事务
[root@sz-kx-centos8 ~]# yum install -y percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm

[root@sz-kx-centos8 ~]# xtrabackup --prepare --target-dir=/root/backup/base

2)复制到数据库目录
注意:数据库目录必须为空,MySQL服务不能启动
[root@sz-kx-centos8 ~]# xtrabackup --copy-back --target-dir=/root/backup/base

3)还原属性
[root@sz-kx-centos8 ~]# chown -R mysql.mysql /var/lib/mysql

4)启动服务
[root@sz-kx-centos8 ~]# systemctl start mysqld

# 登陆查看数据是否是原主机拷贝过来的
[root@sz-kx-centos8 ~]# mysql -uroot -p123456

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| hellodb            |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use hellodb;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-------------------+
| Tables_in_hellodb |
+-------------------+
| classes           |
| coc               |
| courses           |
| scores            |
| students          |
| teachers          |
| toc               |
+-------------------+
7 rows in set (0.01 sec)

案例:利用xtrabackup完全,增量备份及还原

案例: 利用xtrabackup8.0 完全,增量备份及还原MySQL8.0

# 安装xtrabackup
[root@localhost ~]# ll
total 13452
-rw-------. 1 root root     1793 Sep  4  2020 anaconda-ks.cfg
-rw-r--r--. 1 root root    21352 Apr 13 14:43 data.img
-rw-r--r--. 1 root root     3020 Apr 13 10:40 httpds2.sh
-rw-r--r--. 1 root root 13738948 Mar 16 23:26 percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm

[root@localhost ~]# yum install -y percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm

# 在原主机做完全备份到/mysql/backup,登陆mysql有密码的需要写上
[root@localhost ~]# mkdir /mysql/backup -p
1)完全备份
[root@localhost ~]# xtrabackup -uroot -p123456 --backup --target-dir=/mysql/backup/base

2)第一次修改数据
mysql> insert teachers (name,age,gender)values('bob',23,'F');
Query OK, 1 row affected (0.00 sec)

mysql> insert teachers (name,age,gender)values('monk',19,'F');
Query OK, 1 row affected (0.00 sec)

3)第一次增量备份
[root@localhost ~]# xtrabackup -uroot -p123456 --backup --target-dir=/mysql/backup/inc1 --incremental-basedir=/mysql/backup/base

4)第二次修改数据
mysql> insert teachers (name,age,gender)values('aa',22,'M');
Query OK, 1 row affected (0.00 sec)

mysql> insert teachers (name,age,gender)values('BB',18,'F');
Query OK, 1 row affected (0.00 sec)

5)第二次增量
[root@localhost ~]# xtrabackup -uroot -p123456 --backup --target-dir=/mysql/backup/inc2 --incremental-basedir=/mysql/backup/inc1

# 目标主机创建目录存数据
[root@sz-kx-centos8 ~]# mkdir -p /data/mysql/backup

[root@localhost ~]# scp -r /mysql/backup/* 172.31.0.18:/data/mysql/backup
#备份过程生成三个备份目录
/backup/{base,inc1,inc2}

2还原过程
1)预准备完成备份,此选项--apply-log-only 阻止回滚未完成的事务
#安装软件xtrabackup
[root@sz-kx-centos8 ~]# yum install -y percona-xtrabackup-80-8.0.23-16.1.el8.x86_64.rpm

[root@sz-kx-centos8 ~]# xtrabackup --prepare --apply-log-only --target-dir=/data/mysql/backup/base

2)合并第1次增量备份到完全备份
[root@sz-kx-centos8 ~]# xtrabackup --prepare --apply-log-only --target-dir=/data/mysql/backup/base --incremental-dir=/data/mysql/backup/inc1

3)合并第2次增量备份到完全备份:最后一次还原不需要加选项--apply-log-only
[root@sz-kx-centos8 ~]# xtrabackup --prepare --apply-log-only --target-dir=/data/mysql/backup/base --incremental-dir=/data/mysql/backup/inc2

4)复制到数据库目录,注意数据库目录必须为空,MySQL服务不能启动
[root@sz-kx-centos8 ~]# xtrabackup --copy-back --target-dir=/data/mysql/backup/base

5)还原属性:
[root@sz-kx-centos8 ~]# chown -R mysql.mysql /var/lib/mysql

6)启动服务:
[root@sz-kx-centos8 ~]# systemctl start mysqld

验证数据正确性
mysql> select * from teachers;
+-----+---------------+-----+--------+
| TID | Name          | Age | Gender |
+-----+---------------+-----+--------+
|   1 | Song Jiang    |  45 | M      |
|   2 | Zhang Sanfeng |  94 | M      |
|   3 | Miejue Shitai |  77 | F      |
|   4 | Lin Chaoying  |  93 | F      |
|   5 | bob           |  23 | F      |
|   6 | monk          |  19 | F      |
|   7 | aa            |  22 | M      |
|   8 | BB            |  18 | F      |
+-----+---------------+-----+--------+
8 rows in set (0.00 sec)

案例:xtrabackup单表导出和导入

#导出
1 单表备份
innobackupex -uroot -p123456 --include='hellodb.students' /backup
2备份表结构
mysql -e 'show create table hellodb.students' > student.sql
3删除表
mysql -e 'drop table hellodb.students'
#导出
4 innobackupex --apply-log --export /backups/2021-05-18_15-03-23/
5 创建表
mysql>CREATE TABLE `students` (
`StuID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(50) NOT NULL,
`Age` tinyint(3) unsigned NOT NULL,
`Gender` enum('F','M') NOT NULL,
`ClassID` tinyint(3) unsigned DEFAULT NULL,
`TeacherID` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`StuID`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8
6 删除表空间
alter table students discard tablespace;
7 cp /backups/2021-05-18_15-03-23/hellodb/students.{cfg,exp,ibd} /var/lib/mysql/hellodb/
8 chown -R mysql.mysql /var/lib/mysql/hellodb/
9 mysql>alter table students import tablespace;

案例:xtrabackup增量备份

1).备份
首先全量备份一次
innobackupex --user=数据库账号 --password='数据库密码' /xtrabackup/
假设全量生成的备份包为2021-5-0

第一次增量备份
innobackupex --user=数据库账号 --password='数据库密码' --incremental /xtrabackup/ --incremental-basedir=/xtrabackup/2021-5-0/ #(基于全量的包)
假设第一次增量生成的包为 2021-5-1 

第二次增量备份
innobackupex --user=数据库账号 --password='数据库密码' --incremental /xtrabackup/ --incremental-basedir=/xtrabackup/2021-5-1/ #(基于第一次增量包)
假设第二次增量生成的包为 2021-5-2

第三次增量备份
innobackupex --user=数据库账号 --password='数据库密码' --incremental /xtrabackup/ --incremental-basedir=/xtrabackup/2021-5-2/ #(基于第二次增量包)
假设第三次增量生成的包为 2021-5-3

....................以此类推..........

2). 恢复
首先回滚备份包
1. 先回滚全量的包
innobackupex --apply-log --redo-only /xtrabackup/2021-5-0
2. 回滚第一次增量包
innobackupex --apply-log --redo-only /xtrabackup/2021-5-0 --incremental-dir=/xtrabackup/2021-5-1
3. 回滚第二次增量包
innobackupex --apply-log --redo-only /xtrabackup/2021-5-0 --incremental-dir=/xtrabackup/2021-5-2
4. 回滚第三次增量包
innobackupex --apply-log --redo-only /xtrabackup/2021-5-0 --incremental-dir=/xtrabackup/2021-5-3

备注:此时回滚的所有增量数据都到了第一次备份的全量包里  这时数据还没有到达库指定目录
接下来我们进行恢复。
恢复回滚好的 第一次全量包

5. innobackupex --copy-back /xtrabackup/2021-5-0

案例:xtrabackup差异备份

1.备份
首先进行一次完全备份
innobackupex --user=数据库账号 --password='数据库密码' /xtrabackup
假设完全备份的包是2021-5-0
进行第一次差异备份
innobackupex --user=数据库账号 --password='数据库密码' --incremental /xtrabackup --incremental-basedir=/xtrabackup/2021-5-0
假设第一次差异备份包是2021-5-1
进行第二次差异备份
innobackupex --user=数据库账号 --password='数据库密码' --incremental /xtrabackup --incremental-basedir=/xtrabackup/2021-5-1  #还是基于第一次的全备
假设第二次差异备份的包是2021-5-2
进行第三次差异备份
innobackupex --user=数据库账号 --password='数据库密码' --incremental /xtrabackup --incremental-basedir=/xtrabackup/2021-5-1  #还是基于第一次的全备
假设第三次差异备份的包是2021-5-3
进行第四次差异备份
innobackupex --user=数据库账号 --password='数据库密码' --incremental /xtrabackup --incremental-basedir=/xtrabackup/2021-5-1  #还是基于第一次的全备
假设第四次差异备份的包是2021-5-4
.................以此类推......................

2.恢复
假设恢复到第三次差异备份的数据
我们回滚时候只需要回 '滚完全备份包' 和 '第三次差异包' 备份即可。
1. 回滚
回滚全量备份包
innobackupex --apply-log --redo-only /xtrabackup/2021-5-0
回滚第三次差异备份包
innobackupex --apply-log --redo-only /xtrabackup/2021-5-0--incremental-dir=/xtrabackup/2021-5-3
2.进行恢复
恢复回滚好的 第一次全量包
innobackupex --copy-back /xtrabackup/2021-5-0

案例:脚本

基础配置脚本文件/root/mysql.sh

#! /bin/bash
# Date: 2021-05-18
# Authro: xuanlv

HOSTNAME="localhost"
USERNAME="root"
PASSWORD="123456"
MYSQL=/usr/bin/mysql

DATAMYSQL=/var/lib/mysql
DATE=`date +%Y%m-%V`
BACKUPDIR=/mysql/data
SETMYSQL=/etc/my.cnf
SOCK=/var/lib/mysql/mysql.sock
INNOBACKUPEX=/usr/bin/innobackupex
[ ! -d $BACKUPDIR ] && mkdir $BACKUPDIR -p

全量备份脚本文件

#! /bin/bash
# Date: 2021-05-18
# Authro: xuanlv

source /root/mysql.sh
[ ! -d $BACKUPDIR/$DATE/back ] && mkdir -p $BACKUPDIR/$DATE/back && chmod -R 777 $BACKUPDIR/$DATE/back
$INNOBACKUPEX --defaults-file=$SETMYSQL --user=$USERNAME --password=$PASSWORD --socket=$SOCK --no-timestamp $BACKUPDIR/$DATE/back

增量备份脚本文件

#! /bin/bash
# Date: 2021-05-18
# Authro: xuanlv

source /root/mysql.sh
I=0

[ ! -d $BACKUPDIR/$DATE/back ] && exit

for file in $( ls $BACKUPDIR/$DATE )
do
  let "U=(++I)";
done
if [ $U -eq 1 ];then
  BASEDIR=back
else
  BASEDIR=$[U-1]"_inc"
fi
NEWDIR=${U}"_inc"
$INNOBACKUPEX --defaults-file=$SETMYSQL --user=$USER --password=$PASSWORD --socket=$SOCK --no-timestamp --incremental-basedir=$BACKUPDIR/$DATE/$BASEDIR --incremental $BACKUPDIR/$DATE/$NEWDIR

差异备份脚本文件

#! /bin/bash
# Date: 2021-05-18
# Authro: xuanlv

source /root/mysql.sh
I=0

[ ! -d $BACKUPDIR/$DATE/back ] && exit

for file in $( ls $BACKUPDIR/$DATE )
do
  let "U=(++I)";
done

NEWDIR=${U}"_inc"
$INNOBACKUPEX --defaults-file=$SETMYSQL --user=$USER --password=$PASSWORD --socket=$SOCK --no-timestamp --incremental-basedir=$BACKUPDIR/$DATE/back --incremental $BACKUPDIR/$DATE/$NEWDIR

原文地址:https://www.cnblogs.com/xuanlv-0413/p/14782940.html