【MySQL】Xtrabackup备份及恢复脚本

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了【MySQL】Xtrabackup备份及恢复脚本相关的知识,希望对你有一定的参考价值。

参考技术A

简介:

此备份脚本的策略是每周日和周三进去全备 其余每天增量备份。

MySQL数据库物理备份

MySQL物理备份

备份的实质:对数据文件 + 配置文件 + 日志文件进行拷贝操作

xtrabackup软件备份介绍

安装xtrabackup软件会产生一个innobackupex 小工具

xtrabackup优缺点:

优点

  1. 备份过程==快速、可靠(因为是物理备份,相当于直接拷贝文件);

  2. 支持增量备份,更为灵活

  3. 备份过程不会打断正在执行的事务;

  4. 能够基于压缩等功能节约磁盘空间和流量;

  5. 自动实现备份检验;

  6. 还原速度快

缺点:

  1. 只能对innodb表增量备份,myisam表增量备份时是全备

  2. innobackupex备份MyISAM表之前要对全库进行加READ LOCK,阻塞myisam表写操作,若备份是在从库上进行的话会影响主从同步,造成延迟。对InnoDB表备份不会阻塞读写

xtrabackup备份原理

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

  2. 物理拷贝innodb的数据文件和系统表空间文件idbdata1(即innodb的共享文件)到对应的以默认时间戳为备份目录的地方

  3. 复制结束后,执行flush table with read lock操作进行全库锁表准备备份非InnoDB文件(非innodb的表锁定后只能读)

  4. 物理复制.frm .myd .myi等非InnoDB引擎文件到备份目录

  5. 查看二进制日志的位置(即备份二进制文件)

  6. 解锁表unlock tables

  7. 停止xtrabackup_log进程

在这里插入图片描述

名称解析:

redo log:事务日志或称redo日志,在mysql中默认以ib_logfile0ib_logfile1名称存在。

  • innodb事务日志包括redo log和undo log。redo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作。
  • 在对innodb引擎表进行数据的增删改时,ib_logfile0ib_logfile1 会发生变化

xtrabackup备份恢复原理

  • 主要是innodb引擎表在备份期间因为不会阻塞,所以他的数据会发生变化
  • 所以主要是分两步:①12:00时拷贝物理文件。②将备份期间产生的日志记录整合到12:00的备份中

在这里插入图片描述

  • 在InnoDB内部会维护一个redo日志文件,我们也可以叫做事务日志文件。事务日志会存储每一个InnoDB表数据的记录修改。当InnoDB启动时,InnoDB会检查数据文件和事务日志,并执行两个步骤:它应用(前滚)已经提交的事务日志到数据文件,并将修改过但没有提交的数据进行回滚操作。
  • xtrabackup在启动时会记住log sequence number(LSN),并且复制所有的数据文件。复制过程需要一些时间,所以这期间如果数据文件有改动,那么将会使数据库处于一个不同的时间点。这时,xtrabackup会运行一个后台进程,用于监视事务日志,并从事务日志复制最新的修改。xtrabackup必须持续的做这个操作,是因为事务日志是会轮转重复的写入,并且事务日志可以被重用。所以xtrabackup自启动开始,就不停的将事务日志中每个数据文件的修改都记录下来。
  • 上面就是xtrabackup的备份过程。接下来是准备(prepare)过程。在这个过程中,xtrabackup使用之前复制的事务日志,对各个数据文件执行灾难恢复(就像MySQL刚启动时要做的一样)。当这个过程结束后,数据库就可以做恢复还原了。
  • 以上的过程在xtrabackup的编译二进制程序中实现。程序innobackupex可以允许我们备份MyISAM表和frm文件从而增加了便捷和功能。Innobackupex会启动xtrabackup,直到xtrabackup复制数据文件后,然后执行FLUSH TABLES WITH READ LOCK来阻止新的写入进来并把MyISAM表数据刷到硬盘上,之后复制MyISAM数据文件,最后释放锁。
  • 备份MyISAM和InnoDB表最终会处于一致,在准备(prepare)过程结束后,InnoDB表数据已经前滚到整个备份结束的点,而不是回滚到xtrabackup刚开始时的点。这个时间点与执行FLUSH TABLES WITH READ LOCK的时间点相同,所以MyISAM表数据与InnoDB表数据是同步的。类似Oracle的recover和restore,InnoDB的prepare过程可以称为recover(恢复),MyISAM的数据复制过程可以称为restore(还原)。
  • Mysql5.7.3以后开启二进制日志需要加上server-id选项,不然报错

xtrabackup备份工具的下载及安装

网站域名:http://www.percona.com

依赖包:https://download.csdn.net/download/qq_46093534/19684742

软件下载:https://download.csdn.net/download/qq_46093534/19684747

安装xtrabackup软件:

第一步:将软件上传至服务器
第二步:先安装依赖库
	# rpm -ivh libev-4.15-3.el7.x86_64.rpm

第二步:使用yum 安装xtrabackup软件(因为还需要其他依赖)
	# yum install -y percona-xtrabackup-24-2.4.7-2.el7.x86_64.rpm

安装完成:
查看生成了哪些文件:
	# rpm -ql percona-xtrabackup
		[root@mysql_01 ~]# rpm -ql percona-xtrabackup-24
			/usr/bin/innobackupex		=>	备份和恢复时使用的命令
			/usr/bin/xbcloud
			/usr/bin/xbcloud_osenv
			/usr/bin/xbcrypt
			/usr/bin/xbstream
			/usr/bin/xtrabackup
			/usr/share/doc/percona-xtrabackup-24-2.4.7
			/usr/share/doc/percona-xtrabackup-24-2.4.7/COPYING
			/usr/share/man/man1/innobackupex.1.gz
			/usr/share/man/man1/xbcrypt.1.gz
			/usr/share/man/man1/xbstream.1.gz
			/usr/share/man/man1/xtrabackup.1.gz

xtrabackup全库备份与恢复

备份核心思路:

① 使用innobackupex对数据库中的所有库进行全量备份,备份完成后,其不能立即进行数据恢复(数据不完整,缺少12:00 ~ 12:30这个过程中的数据)

预备阶段,备份过程中产生的xtrabackup_log应用到全量备份集

③ 模拟故障(删除数据) => rm -rf data/*

④ 动员运维工程师进行全库恢复

⑤ 测试验证

第一步:准备数据,分别准备两种引擎表

mysql> create database db_itheima default charset=utf8;
mysql> use db_itheima;
mysql> create table t1(id int,name varchar(10)) engine=myisam;
mysql> insert into t1 values (1,'吕布');
mysql> create table t2(id int,name varchar(10)) engine=innodb;
mysql> insert into t2 values (1,'貂蝉');

第二步:专门准备一个数据库备份账号,开通相应权限

创建备份用户,并授予相应权限:
	# mysql > grant reload,lock tables,process,replication client on *.* to 'admin'@'localhost' identified by '123';
	# mysql > flush privileges;

	选项说明:
		在数据库中需要以下权限:
			RELOAD和LOCK TABLES权限:为了执行FLUSH TABLES WITH READ LOCK
			REPLICATION CLIENT权限:为了获取binary log位置
			PROCESS权限:显示有关在服务器中执行的线程的信息(即有关会话执行的语句的信息),允许使用SHOW ENGINE

第三步:使用innobackupex工具进行全库备份

命令格式:
	# innobackupex --user=用户 --password=密码 备份目录
		说明:备份目录默认会自动创建,也可以手动创建


演示:
	innobackupex 命令备份:
		# innobackupex -S /mysql_3307/mysql.sock --user=admin --password=123 /full_xtrabackup
			210616 15:38:00 completed OK!
			=>	执行这条命令后会将数据库的物理文件保存以时间戳命名保存到备份目录下
					[root@mysql_01 ~]# ll /full_xtrabackup/
						total 4
						drwxr-x---. 10 root root 4096 Jun 16 15:38 2021-06-16_15-37-58
  • 第一次运行会报错
报错:
IMPORTANT: Please check that the backup run completes successfully.
           At the end of a successful backup run innobackupex
           prints "completed OK!".

210616 15:22:42  version_check Connecting to MySQL server with DSN 'dbi:mysql:;mysql_read_default_group=xtrabackup' as 'admin'  (using password: YES).
Failed to connect to MySQL server: DBI connect(';mysql_read_default_group=xtrabackup','admin',...) failed: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) at - line 1314.
210616 15:22:42 Connecting to MySQL server host: localhost, user: admin, password: set, port: not set, socket: not set
Failed to connect to MySQL server: Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2).

原因:出现以上问题的主要原因在于我们的mysql.sock并不在/var/lib/mysql目录下。为什么其会自动连接/var/lib/mysql目录下的mysql.sock呢?

  • 原因1:可能在/etc目录下还有my.cnf文件,影响了innobackupex的执行。

  • 原因2:innobackupex拥有自己的默认配置,默认读取了/var/lib/mysql/mysql.sock文件

  • 解决方案:

方案1:把你的套接字文件创建一个软链接,放置于/var/lib/mysql/mysql.sock文件中
	# mkdir /var/lib/mysql
	# ln -s /mysql_3307/mysql.sock /var/lib/mysql/mysql.sock


方案2:在innobackupex中添加一个-S选项,执行套接字
	# innobackupex -S /mysql_3307/mysql.sock --user=admin --password=123 /full_xtrabackup

第四步:预备阶段,把备份这段时间内产生的日志整合到全量备份中

增加测试数据内容:
	mysql> insert into t1 values (2,'项羽');	=>	myisam引擎,这时候会阻塞他的写入
	mysql> insert into t2 values (2,'虞姬');	=>	innodb引擎,不会阻塞
			#l 很遗憾,这个实验做不了,因为自己数据没有那么多,一下子就备份完物理文件了,xtrabackup_log在备份完成后进程就停止了,
				增加数据的时候自然就没有写入到xtrabackup_log中。所以恢复的数据自然就没有增加的内容


预备阶段:整合,指定到具体备份时间戳目录下
	# innobackupex --user=admin --password=123 --apply-log /full_xtrabackup/2021-06-16_15-37-58
		210616 15:46:13 completed OK!
		选项说明:
			--apply-log 表示整合日志

第五步:模拟数据库故障

# rm -rf /mysql_3307/data/*
# pkill mysqld

第六步:快速的恢复数据库中的数据

# innobackupex --defaults-file=/mysql_3307/my.cnf --copy-back /full_xtrabackup/2021-06-16_15-37-58

	选项说明:
		--defaults-file:把my.cnf配置文件传递给innobackupex,让其自动识别这个文件中的datadir
		--copy-back:将备份目录的东西恢复到数据目录


如果提示:Original data directory /mysql_3307/data is not empty!
就再次执行rm -rf /mysql_3306/data/*

第七步:恢复数据时,一定要记得更改/mysql_3307/data目录下的文件拥有者以及所属组权限,否则mysql无法启动

# chown -R mysql.mysql /mysql_3307/data

第八步:启动MySQL,测试其是否正常

# service mysql_3307 start
# mysql_3307 -p
# mysql > select*from db_itheima.t1;
	+------+--------+
	| id   | name   |
	+------+--------+
	|    1 | 吕布   |
	+------+--------+

xtrabackup增量备份与恢复

什么是增量?增量一定要有一个前提,必须要先有一个全量。

在这里插入图片描述

① 全量备份

② 把全量备份产生的日志整合到全量备份

③ 进行数据的增删改操作

④ 增量备份

⑤ 把增量备份及增量备份产生的日志文件全部整合到全量备份中

⑥ 模拟故障

⑦ 数据恢复

⑧ 启动数据库,测试验证数据

第一步:准备数据

mysql> create database db_itheima default charset=utf8;
mysql> use db_itheima;
mysql> create table t1(id int,name varchar(10)) engine=myisam;
mysql> insert into t1 values (1,'吕布');
mysql> create table t2(id int,name varchar(10)) engine=innodb;
mysql> insert into t2 values (1,'貂蝉');

第二步:创建一个账号,专门用于备份

创建备份用户,并授予相应权限:
	# mysql > grant reload,lock tables,process,replication client on *.* to 'admin'@'localhost' identified by '123';
	# mysql > flush privileges;

	选项说明:
		在数据库中需要以下权限:
			RELOAD和LOCK TABLES权限:为了执行FLUSH TABLES WITH READ LOCK
			REPLICATION CLIENT权限:为了获取binary log位置
			PROCESS权限:显示有关在服务器中执行的线程的信息(即有关会话执行的语句的信息),允许使用SHOW ENGINE

第三步:全量备份

# innobackupex -S /mysql_3307/mysql.sock --user=admin --password=123 /full_xtrabackup

[root@mysql_01 ~]# ll /full_xtrabackup/
	total 8
	drwxr-x---. 10 root root 4096 Jun 16 15:46 2021-06-16_15-37-58
	drwxr-x---. 10 root root 4096 Jun 16 16:49 2021-06-16_16-49-53	=>	增量的全备

第四步:把全备过程中产生的日志进行整合(特别注意)

  • 增加了–redo-only 选项,表示只应用已提交的事物,不加不能做增量
  • 不同于全备整合全备过程日志,增备全备整合全备日志时,为了将下一个增量备份添加到全备中需要不回滚未提交的事务
# innobackupex --user=admin --password=123 --apply-log --redo-only /full_xtrabackup/2021-06-16_16-49-53/

	选项说明:
	--apply-log:表示整合日志
	--redo-only:表示只应用已经提交的事务,不回滚未提交的事务(12:00 ~ 12:30产生很多事务操作,
				事务处理=>开启事务,成功了提交事务,写入硬盘;失败了回滚事务,不写入硬盘)
	
	注意:如果已经回滚了未提交事务,那么就无法再应用增量备份。

对于增量备份的Prepare阶段,有2个需要注意的地方,一个是提交的事务需要replayed,一个未提交的事务需要rollback。

Preparing an Incremental Backup with innobackupex Preparing incremental backups is a bit different than full ones. This is, perhaps, the stage where more attention is needed:

• First, only the committed transactions must be replayed on each backup. This will merge the base full backup with the incremental ones.

• Then, the uncommitted transaction must be rolled back in order to have a ready-to-use backup.

对于增量备份的Prepare阶段,有2个需要注意的地方,一个是提交的事务需要replayed,一个未提交的事务需要rollback。

If you replay the committed transactions and rollback the uncommitted ones on the base backup, you will not be able to add the incremental ones. If you do this on an incremental one, you won’t be able to add data from that moment and the remaining increments. Having this in mind, the procedure is very straight-forward using the --redo-only option, starting with the base backup:

如果在Prepare阶段replay了已提交的事务以及回滚了未提交的事务,则后续的增量备份无法添加到当前全备。因此在Prepare阶段全备应使用–redo-only选项。

–redo-only should be used when merging all incrementals except the last one. That’s why the previous line doesn’t contain the --redo-only option. Even if the --redo-only was used on the last step, backup would still be consistent but in that case server would perform the rollback phase.

对于存在多次增量的情形,仅仅只有最后一个增量不需要使用–redo-only 选项。如果使用了的话,rollback将由服务器启动的时候来完成。

第五步:修改数据(进行增删改操作,让其产生增量数据)

	# mysql> insert into t1 values (2,'项羽');
	# mysql> insert into t2 values (2,'虞姬');

第六步:做增量备份

  • 全量备份目录和增量备份目录不是在同一个目录下的
# innobackupex -S /mysql_3307/mysql.sock --user=admin --password=123 --incremental /incre_backup --incremental-basedir=/full_xtrabackup/2021-06-16_16-49-53
	选项说明:
		--incremental 增量备份目录,会自动创建
		--incremental-basedir 这个增量是相对于哪个全量的


增量备份目录下:
	[root@mysql_01 ~]# ll /incre_backup/
		total 4
		drwxr-x---. 10 root root 4096 Jun 16 16:56 2021-06-16_16-56-18	=>	增量备份的内容

第七步:把增量备份产生的数据以及日志文件整合到全量备份中

  • 如果怕出错,每次都加–redo-only也可以
# innobackupex --user=admin --password=123 --apply-log /full_xtrabackup/2021-06-16_16-49-53 --incremental-dir=/incre_backup/2021-06-16_16-56-18


说明:
	incremental-dir:整合哪个增量的备份到全量中

1.--redo-only除了最后一个不用加之外,其他的增量应用都要加,最后一个应用的时候可以直接进入回滚未提交事务阶段;如果加了也没事,服务启动的时候会进入recovery过程,来回滚

2.应用增量备份的时候只能按照备份的顺序来应用。如果应用顺序错误,那么备份就不可用。如果无法确定顺序,可以使用xtrabackup-checkpoints来确定顺序。

3.这里测试的是最后一个,所以没加--redo-only 选项,如果不是则应该加上--redo-only

周天做了一个全量,周一、周二、周三、周四、周五、周六全部做增量(即周六增量可不加--redo-only且需得按顺序整合增量到全量中)

到此,增量备份就全部结束了!

第八步:模拟数据库故障

# rm -rf /mysql_3307/data/*
# pkill mysqld

第九步:数据恢复

# innobackupex --defaults-file=/mysql_3307/my.cnf --user=admin --password=123 --copy-back /full_xtrabackup/2021-06-16_16-49-53

选项说明:
		--defaults-file:把my.cnf配置文件传递给innobackupex,让其自动识别这个文件中的datadir
		--copy-back:将整合增量后的全量备份目录的东西恢复到数据目录

如果提示:Original data directory /mysql_3307/data is not empty!
就再次执行rm -rf /mysql_3306/data/*

第十步:更改数据目录权限及测试增量备份是否成功

# chown -R mysql.mysql /mysql_3307/data	

# service mysql_3307 start
# mysql_3307 -p
# mysql > select*from db_itheima.t1;
# mysql > select*from db_itheima.t2;
  • 增量备份完成

在这里插入图片描述

以上是关于【MySQL】Xtrabackup备份及恢复脚本的主要内容,如果未能解决你的问题,请参考以下文章

基于Xtrabackup8的Mysql定时全量,增量备份及恢复实战演练

MySQL数据库物理备份

MySQL数据库物理备份

xtrabackup之Innobackupex增量备份及恢复

Mysql中-Xtrabackup备份和恢复应用

xtrabackup 备份和恢复