mysql备份恢复的原理_MariaDB/MySQL备份和恢复(三):xtrabackup用法和原理详述

xtrabackup是percona团队研发的备份工具,比MySQL官方的ibbackup的功能还要多。支持myisam温全备、innodb热全备和温增备,还可以实现innodb的定时点恢复,而且备份和恢复的速度都较快。在目前MySQL的备份实现上,考虑价格、速度、安全、一致性等角度,xtrabackup是非常合适的工具。

MariaDB也可以使用percona xtrabackup进行备份,不过MariaDB基于percona xtrabackup开发了它自己的备份工具:MariaDB Backup。它基于xtrabackup开发,所以所用方法基本和xtrabackup相同,只是有些自己的特性。详细内容见MariaDB Backup官方手册:

1.安装xtrabackup

因为只是一个备份工具,所以没必要编译安装,直接下载它的rpm包即可。但是该rpm包依赖于libev.so.4,该依赖包可以在epel源中找到。

这里安装的是目前最新版的xtrabackup-24-2.4.11。

cat <>/etc/yum.repos.d/percona.repo

[percona]

name=Percona

baseurl= https://mirrors.tuna.tsinghua.edu.cn/percona/release/\$releasever/RPMS/\$basearch

enabled = 1gpgcheck= 0[epel]

name=epelrepo

baseurl=https://mirrors.aliyun.com/epel/\$releasever/\$basearch

gpgcheck=0enable=1eof

[root@node1 ~]# yum list all| grep xtraback -i

Repository epel is listedmore than once inthe configuration

holland-xtrabackup.noarch 1.0.14-3.el6 epel

percona-xtrabackup.x86_64 2.3.10-1.el6 percona

percona-xtrabackup-20.x86_64 2.0.8-587.rhel6 percona

percona-xtrabackup-20-debuginfo.x86_64 2.0.8-587.rhel6 percona

percona-xtrabackup-20-test.x86_64 2.0.8-587.rhel6 percona

percona-xtrabackup-21.x86_64 2.1.9-746.rhel6 percona

percona-xtrabackup-21-debuginfo.x86_64 2.1.9-746.rhel6 percona

percona-xtrabackup-22.x86_64 2.2.13-1.el6 percona

percona-xtrabackup-22-debuginfo.x86_64 2.2.13-1.el6 percona

percona-xtrabackup-24.x86_64 2.4.11-1.el6 percona

percona-xtrabackup-24-debuginfo.x86_64 2.4.11-1.el6 percona

percona-xtrabackup-debuginfo.x86_64 2.3.10-1.el6 percona

percona-xtrabackup-test.x86_64 2.3.10-1.el6 percona

percona-xtrabackup-test-21.x86_64 2.1.9-746.rhel6 percona

percona-xtrabackup-test-22.x86_64 2.2.13-1.el6 percona

percona-xtrabackup-test-24.x86_64 2.4.11-1.el6 percona

[root@node1~]# yum -y install percona-xtrabackup-24

装完xtrabackup后,生成以下几个工具。

[root@node1 ~]# rpm -ql percona-xtrabackup-24 | grep bin | xargs ls -hl

lrwxrwxrwx1 root root 10 May 8 19:19 /usr/bin/innobackupex ->xtrabackup-rwxr-xr-x 1 root root 3.5M Apr 19 01:11 /usr/bin/xbcloud-rwxr-xr-x 1 root root 3.0K Apr 19 01:04 /usr/bin/xbcloud_osenv-rwxr-xr-x 1 root root 3.5M Apr 19 01:11 /usr/bin/xbcrypt-rwxr-xr-x 1 root root 3.5M Apr 19 01:11 /usr/bin/xbstream-rwxr-xr-x 1 root root 21M Apr 19 01:11 /usr/bin/xtrabackup

xbcloud和xbcloud_osenv是xtrabackup新的高级特性:云备份;

xbcrypt也是新的特性,加密备份集;

xbstream是xtrabackup的流数据功能,通过流数据功能,可将备份内容打包并传给管道后的压缩工具进行压缩;

xtrabackup是主程序;

innobackupex在以前是一个perl脚本,会调用xtrabackup这个二进制工具,从xtrabackup 2.3开始,该工具使用C语言进行了重写,当前它是xtabackup二进制工具的一个软连接,但是实际的使用方法却不同,并且在以后的版本中会删除该工具。

在本文中,会分别对两个主程序innobackupex和xtrabackup的备份恢复方法进行详细的说明,还会在说明过程中尽可能的解释它们是如何工作的,另外还会介绍它们的一些特殊功能的选项,如流备份选项。

2.备份锁

percona Server 5.6+ 支持一种新锁——backup lock(备份锁),这种锁是percona对MySQL的补充,专门为备份而设计。这种锁在percona Server 5.6+ 有,MariaDB中也有,但是Oracle的MySQL中没有,至少MySQL 5.7中没有。

这种锁用在备份的时候替代 flush tables with read lock 获取全局锁,是一种轻量级的全局锁。它有两种类型的锁:备份表锁和二进制日志锁。为此新增了3种语法:

lock tables for backup # 申请备份表锁

lock binlog for backup # 申请二进制日志锁

unlock binlog # 释放二进制日志锁

备份表锁在全局范围内只对非innodb表加锁,所以持有该锁后无法修改非innodb表,但却不影响innodb表的DML。当然,因为是全局锁,所以也会阻塞DDL操作。

二进制日志锁在全局范围内锁定二进制日志,所以会阻塞其他会话修改二进制日志。这样可以保证能够获取到二进制日志中一致性的位置坐标。

3.xtrabackup备份原理说明

不管是使用innobackupex还是xtrabackup工具进行备份和恢复,都有3个步骤:备份(backup)、准备(prepare)、恢复(copy back)。

注意,xtrabackup备份过程中,先备份innodb表,再备份非innodb表。

3.1 备份过程(backup阶段)

(1).在启动xtrabackup时记下LSN并将redo log拷贝到备份目标目录下的xtrabackup_logfile文件中。由于拷贝需要一定时间,如果在拷贝时间段内有日志写入,将导致拷贝的日志和MySQL的redo log不一致,所以xtrabackup还有一个后台进程监控着mysql的redo log,每秒监控一次,当MySQL的redo log有变化,该监控进程会立即将变化的内容写入到xtrabackup_logfile文件,这样就能保证拷贝走的redo log中记录了一切变化。但是这也是有风险的,因为redo是轮训式循环写入的,如果某一时刻有非常大量的日志写到redo log中,使得还没开始复制的日志就被新日志覆盖了,这样会日志丢失,并报错。

(2).拷贝完初始版的redo log后,xtrabackup开始拷贝innodb表的数据文件(即表空间文件.ibd文件和ibdata1)。注意,此时不拷贝innodb的frm文件。

(3).当innodb相关表的数据文件拷贝完成后,xtrabackup开始准备拷贝非innodb的文件。但在拷贝它们之前,要先对非innodb表进行加锁防止拷贝时有语句修改这些类型的表数据。

对于不支持backup lock的版本,只能通过flush tables with read lock来获取全局读锁,但这样也同样会锁住innodb表,杀伤力太大。所以使用xtrabackup备份Oracle的MySQL,实质上只能实现innodb表的部分时间热备、部分时间温备。

对于支持backup lock的版本,xtrabackup通过lock tables for backup获取轻量级的backup locks来替代flush tables with read lock,因为它只锁定非innodb表,所以由此实现了innodb表的真正热备。

(4).当获取到非innodb表的锁以后,开始拷贝非innodb表的数据和.frm文件。当这些拷贝完成之后,继续拷贝其他存储引擎类型的文件。(实际上,拷贝非innodb表的数据是在获取backup locks(如果支持)后自动进行的,它们属于同一个过程)

(5).当拷贝阶段完成后,就到了备份的收尾阶段。包括获取二进制日志中一致性位置的坐标点、结束redo log的监控和拷贝、释放锁等。

对于不支持backup lock的版本,收尾阶段的过程是这样的:获取二进制日志的一致性坐标点、结束redo log的监控和拷贝、释放锁。

对于支持backup lock的版本,收尾阶段的过程是这样的:先通过lock binlog for bakcup来获取二进制日志锁,然后结束redo log的监控和拷贝,再unlock tables释放表锁,随后获取二进制日志的一致性位置坐标点,最后unlock binlog释放二进制日志锁。

(6).如果一切都OK,xtrabackup将以状态码0退出。

所以,对是否支持backup lock的版本,xtrabackup备份的时的行为是不一样的。

3430821852a03fc39c336b5d47856390.png

backup阶段的过程具体如下图所示:

c6242ca772bf36800e8a1c5e06dfcbd1.png

FTWRL:flush table with read lock;

eaaf9c61d6bcdc78b25553f8a290187c.png

3.2 准备过程(prepare阶段)

由于备份的时候拷贝走的数据文件可能是不一致的,比如监控着MySQL的redo log中在拷贝过程完成后又新的事务提交了,而拷贝走的数据是未提交状态的,那么就需要对该事务前滚;如果监控到的日志中有事务未提交,那么该事务就需要回滚。

但是如果只备份了myisam表或其他非事务表数据,因为备份阶段直接锁定了这些表,所以不会有不一致的状态。

xtrabackup有一个"准备"的阶段。这个阶段的实质就是对备份的innodb数据应用redo log,该回滚的回滚,该前滚的前滚,最终保证xtrabackup_logfile中记录的redo log已经全部应用到备份数据页上,并且实现了一致性。当应用结束后,会重写"xtrabackup_logfile"再次保证该redo log和备份的数据是对应的。

准备过程不需要连接数据库,该过程可以在任意装了xtrabackup软件的机器上进行,之所能实现是因为xtrabackup软件的内部嵌入了一个简化的innodb存储引擎,可以通过它完成日志的应用。

3.3 恢复过程(copy back阶段)

xtrabackup的恢复过程实质是将备份的数据文件和结构定义等文件拷贝回MySQL的datadir。同样可以拷贝到任意机器上。

要求恢复之前MySQL必须是停止运行状态,且datadir是空目录,除非恢复的操作是导入表的操作。具体见后文对应的内容。

4.准备实验环境

创建测试数据库backuptest,并创建myisam表和innodb表,此处简单的使用数值辅助表并分别插入1亿条数据。

DROP DATABASE IF EXISTS backuptest;

CREATE DATABASE backuptest;

USE backuptest;

# 创建myisam类型的数值辅助表和对应插入数据的存储过程

CREATE TABLE num_isam(n INT NOT NULL PRIMARY KEY)ENGINE=MYISAM;

DELIMITER $$

DROP PROCEDURE IF EXISTS proc_num1$$

CREATE PROCEDURE proc_num1(num INT)

BEGIN

DECLARE rn INT DEFAULT1;

TRUNCATE TABLE backuptest.num_isam;

INSERT INTO backuptest.num_isam VALUES(1);dd: WHILE rn*2

BEGIN

INSERT INTO backuptest.num_isam SELECT rn+n FROM backuptest.num_isam;

SET rn= rn*2;

END;

END WHILEdd;

INSERT INTO backuptest.num_isam SELECT n+rn FROM num_isam WHERE n+rn <=num;

END;$$

DELIMITER ;

# 创建innodb类型的数值辅助表和对应插入数据的存储过程

CREATE TABLE num_innodb(n INT NOT NULL PRIMARY KEY)ENGINE=INNODB;

DELIMITER $$

DROP PROCEDURE IF EXISTS proc_num2$$

CREATE PROCEDURE proc_num2(num INT)

BEGIN

DECLARE rn INT DEFAULT1;

TRUNCATE TABLE backuptest.num_innodb;

INSERT INTO backuptest.num_innodb VALUES(1);dd: WHILE rn*2

BEGIN

INSERT INTO backuptest.num_innodb SELECT rn+n FROM backuptest.num_innodb;

SET rn= rn*2;

END;

END WHILEdd;

INSERT INTO backuptest.num_innodb SELECT n+rn FROM backuptest.num_innodb WHERE n+rn <=num;

END;$$

DELIMITER ;

# 分别向两个数值辅助表中插入1亿条数据,

CALL proc_num1(100000000);

CALL proc_num2(100000000);

5.innobackupex工具

5.1 innobackupex实现全备份和恢复的过程

(1). 全备

除了给定连接MySQL服务器的连接参数,只需再给定一个目录即可,该目录是备份的目标位置。默认xtrabackup连接数据库的时候从配置文件中去读取和备份相关的配置,可以使用选项--defaluts-file指定连接时的参数配置文件,但如果指定该选项,该选项只能放在第一个选项位置。

innobackupex --user=root --password=123456 /bakdir/

默认备份的路径是指定路径/bakdir下的一个以时间为时间戳的目录。

[root@xuexi bakdir]# du -sh /bakdir/2017-04-02_07-09-47/*4.0K /bakdir/2017-04-02_07-09-47/backup-my.cnf

4.0G /bakdir/2017-04-02_07-09-47/backuptest

589M /bakdir/2017-04-02_07-09-47/ibdata1

1.8M /bakdir/2017-04-02_07-09-47/mysql

8.0K /bakdir/2017-04-02_07-09-47/Performance

636K /bakdir/2017-04-02_07-09-47/performance_schema

1008K /bakdir/2017-04-02_07-09-47/world

4.0K /bakdir/2017-04-02_07-09-47/xtrabackup_binlog_info

4.0K /bakdir/2017-04-02_07-09-47/xtrabackup_checkpoints

4.0K /bakdir/2017-04-02_07-09-47/xtrabackup_info

4.0K /bakdir/2017-04-02_07-09-47/xtrabackup_logfile

查看该文件目录中文件和大小,可以看出xtrabackup的行为就是复制了目标数据库的相关文件,并新建了几个文件。

其中:

backup-my.cnf是拷贝过来的配置文件。里面只包含[mysqld]配置片段和备份有关的选项。

xtrabackup_binlog_info中记录的是当前使用的二进制日志文件。

[root@xuexi bakdir]# cat 2017-04-02_07-09-47/xtrabackup_binlog_info

mysql-bin.000001 120

xtrabackup_checkpoints中记录了备份的类型是全备还是增备,还有备份的起始、终止LSN号。

[root@xuexi bakdir]# cat 2017-04-02_07-09-47/xtrabackup_checkpoints

backup_type =full-backuped

from_lsn = 0

to_lsn = 7533359841

last_lsn = 7533359841

compact = 0

recover_binlog_info = 0

xtrabackup_info中记录的是备份过程中的一些信息。

[root@xuexi bakdir]# cat 2017-04-02_07-09-47/xtrabackup_info

uuid = 66f34974-1730-11e7-9d09-000c299af3f3

name =

tool_name = innobackupex

tool_command = --user=root --password=... /bakdir/

tool_version = 2.4.6

ibbackup_version = 2.4.6

server_version = 5.6.35-log

start_time = 2017-04-02 07:09:47

end_time = 2017-04-02 07:10:31

lock_time = 0

binlog_pos = filename 'mysql-bin.000001', position '120'

innodb_from_lsn = 0

innodb_to_lsn = 7533359841

partial = N # N表示未启用该方面的功能,如此处表示不是备份部分数据库或表

incremental = N

format = file

compact = N

compressed = N

encrypted = N

xtrabackup_logfile是复制和监控后写的redo日志。该日志是备份后下一个操作"准备"的关键。只有通过它才能实现数据一致性。

(2). 全备的准备过程

在全备份完成之后,备份的数据中如果有innodb数据,则还不能用来恢复。因为从xtrabackup开始备份的时候就监控着MySQL的redo log,在拷贝的innodb数据文件中很可能还有未提交的事务,并且拷贝完innodb数据之后还可能提交了事务或者开启了新的事务等等。总之,全备之后的状态不一定是一致的。但是如果只备份了myisam表或其他非事务表数据,因为备份阶段直接锁定了这些表,所以不会有不一致的状态。

xtrabackup有一个"准备"的阶段。这个阶段的实质就是对备份的innodb数据应用redo log,该回滚的回滚,该前滚的前滚,最终保证xtrabackup_logfile中记录的redo log已经全部应用到备份数据页上,并且实现了一致性。当应用结束后,会重写"xtrabackup_logfile"再次保证该redo log和备份的数据是对应的。

例如,备份的innodb数据文件中存在未提交的事务,但是在监控到的日志中进行了提交,那么就需要对该事务前滚;如果监控到的日志中有事务未提交,那么该事务就需要回滚。

准备阶段使用的模式选项是"--apply-log"。准备阶段不会连接MySQL,所以不用指定连接选项如--user等。

[root@xuexi bakdir]# innobackupex --apply-log /bakdir/2017-04-02_07-09-47/

在准备成功时,会在频幕上输出如下提示内容:

InnoDB: FTS optimize thread exiting.

InnoDB: Starting shutdown...

InnoDB: Shutdown completed; log sequence number7533367063

170402 12:11:23 completed OK!

在准备阶段,有一个内存使用量选项"--use-memory",该选项默认值为100M,值越大准备的过程越快。当然,将该值加大的前提是服务器内存够用。

(3). 全备份的恢复过程

恢复的阶段就是向MySQL的datadir拷贝。全备份的恢复要求MySQL必须处于stop状态,并且datadir必须为空哪怕是和MySQL无关的文件也不能存在,它不会去覆盖datadir中已存在的内容。否则会提示如下错误:

innobackupex version 2.4.6 based on MySQL server 5.7.13 Linux (x86_64) (revision id: 8ec05b7)

Original data directory/mydata/data is not empty!

停止mysql并清空datadir。

service mysqld stoprm -rf /mydata/data/*

恢复时使用的模式是"--copy-back",选项后指定要恢复的源备份目录。恢复时因为不需要连接数据库,所以不用指定连接选项,如--user等。

[root@xuexi bakdir]# innobackupex --copy-back /bakdir/2017-04-02_07-09-47/

170402 12:36:09 completed OK!

拷贝完成后,MySQL的datadir的文件的所有者和属组是innobackupex的调用者,所以需要改回mysql.mysql。

[root@xuexi bakdir]# ll /mydata/data/total712736drwxr-x--- 2 root root 4096 Apr 2 12:36backuptest-rw-r----- 1 root root 616562688 Apr 2 12:35ibdata1-rw-r----- 1 root root 50331648 Apr 2 12:35ib_logfile0-rw-r----- 1 root root 50331648 Apr 2 12:35ib_logfile1-rw-r----- 1 root root 12582912 Apr 2 12:36ibtmp1

drwxr-x--- 2 root root 4096 Apr 2 12:36mysql

drwxr-x--- 2 root root 4096 Apr 2 12:35Performance

drwxr-x--- 2 root root 4096 Apr 2 12:36performance_schema

drwxr-x--- 2 root root 4096 Apr 2 12:35world-rw-r----- 1 root root 23 Apr 2 12:35xtrabackup_binlog_pos_innodb-rw-r----- 1 root root 494 Apr 2 12:35xtrabackup_info

[root@xuexi bakdir]#chown -R mysql.mysql /mydata/data/*

完成这些之后,就可以启动MySQL服务器了。可以进入mysql测试backuptest数据库中的数据是否完整。

5.2 innobackupex实现增量备份和恢复的过程

增量备份依赖于全备份。xtrabackup实现增量备份的原理是通过比较全备份的终点LSN和当前的LSN,增备时将从终点LSN开始一直备份到当前的LSN。在备份时也有redo log的监控线程,对于增备过程中导致LSN增长的操作也会写入到日志中。

增备的实现依赖于LSN,所以只对innodb有效,对myisam表使用增备时,背后进行的是全备。

(1). 要进行增备,首先要有全备文件。这里重新进行一次全备。

innobackupex --user=root --password=123456 /bakdir/

全备完成后,在/bakdir目录下生成的全备目录是2017-04-02_13-26-35。

[root@xuexi ~]# ls /bakdir/2017-04-02_13-26-35/backup-my.cnf ibdata1 Performance secure_dir xtrabackup_binlog_info xtrabackup_info

backuptest mysql performance_schema world xtrabackup_checkpoints xtrabackup_logfile

查看xtrabackup_checkpoints可以得知相关的LSN。

[root@xuexi ~]# cat /bakdir/2017-04-02_13-26-35/xtrabackup_checkpoints

backup_type= full-backuped

from_lsn= 0to_lsn= 7533367093last_lsn= 7533367093compact= 0recover_binlog_info= 0

注意:要实现增备,这一次的全备一定不能进行"准备"操作,原因稍后给出。

(2). 进行第一次增备。

假设对示例数据可backuptest中的num_innodb表进行了truncate操作。

mysql> truncate backuptest.num_innodb;

然后再增备。增备时使用"--incremental"选项表示增量备份,增量备份时需要通过"--incremental-basedir=fullback_PATH"指定基于哪个备份集备份,因为是第一次增备,所以要基于完全备份增量集。

[root@xuexi ~]# innobackupex --user=root --password=123456 --incremental /bakdir/ --incremental-basedir=/bakdir/2017-04-02_13-26-35/

增备完成后,生成的增备集为/bakdir/2017-04-02_13-39-05/,查看其中的xtrabackup_checkpoints,可以看到备份的起始LSN是上次全备完成后的LSN。

[root@xuexi ~]# cat /bakdir/2017-04-02_13-39-05/xtrabackup_checkpoints

backup_type=incremental

from_lsn= 7533367093to_lsn= 7533372535last_lsn= 7533372535compact= 0recover_binlog_info= 0

默认情况下,增备的起始LSN是自动获取的,但是在某些情况下无法获取,还有些情况下无法获取到将要增备的basedir。xtrabackup提供的选项"--incremental-lsn=N"可以显式指定增备的起始LSN,显式指定LSN时,可以无需提供增备的basedir。

例如,如果获取到了上次全备的终止LSN为7533367093,可以如下方式增备:

innobackupex --user=root --password=123456 --incremental /bakdir/ --incremental-lsn=7533367093

这样增备后也在/bakdir中生成一个时间戳目录/bakdir/2017-04-02_13-50-33。查看LSN信息:

[root@xuexi ~]# cat /bakdir/2017-04-02_13-50-33/xtrabackup_checkpoints

backup_type=incremental

from_lsn= 7533367093to_lsn= 7533372535last_lsn= 7533372535compact= 0recover_binlog_info= 0

由此可知和指定--incremental-basedir进行增备是一样的。

(3). 进行第二次增备。

假设在第一次增备后,向上次truncate的表backuptest.num_innodb表中插入的100W条记录。

mysql> call backuptest.proc_num2(1000000);

mysql> select count(*) from backuptest.num_innodb;+----------+

| count(*) |

+----------+

| 1000000 |

+----------+

然后进行增备。这次增备是基于第一次增备的(当然也可以基于全备进行备份,这样实现的是差异备份)。

[root@xuexi ~]# innobackupex --user=root --password=123456 --incremental /bakdir/ --incremental-basedir=/bakdir/2017-04-02_13-39-05/

这次增备完成后生成的备份集为/bakdir/2017-04-02_14-03-51/。查看LSN信息:

[root@xuexi ~]# cat /bakdir/2017-04-02_14-03-51/xtrabackup_checkpoints

backup_type=incremental

from_lsn= 7533372535to_lsn= 7585150275last_lsn= 7585150275compact= 0recover_binlog_info= 0

(4). 增备的准备过程

增备的准备过程和全备的准备过程有点不一样,不到最后恢复的时候不能进行任何"准备"过程。

增备过程中的每一次备份行为都会监控MySQL的redo log,写入到xtrabackup_logfile的日志中可能会有未提交的事务,但是到后面增备的时候进行了提交,也就是说提交过程记录到了增备时监控的日志xtrabackup_logfile中。如果在增备前进行了"准备",那么该事务就会被回滚,后面增备中的提交就丢失了,由此会造成数据丢失。

要保证将所有的备份集进行整合,需要使用在每个备份集的"准备"过程中使用"--redo-only"选项,这样应用日志时会"直线向前"直到最后一个备份集。它的本质是向全备集中不断的追加应用增备中的日志。但是,最后一个增备集需要作为备份集整合的终点,所以它不能使用"--redo-only"选项。整合完成之后,原来的全备就已经完整了,这时再对追加完成的全备集进行一次"准备"即可用于后面的恢复。

所以,如果全备为A,3次增备分别为B/C/D,如果只想恢复到C,那么从A开始整合到C结束即可。

因为在每一个增备的"准备"过程中都需要向整合的开始备份集中追加应用日志,所以每一次增备的"准备"都需要指定整合的开始备份集目录作为basedir。例如指定全备份作为整合的初始备份集。

从以上实验过程中,得到的全备集是2017-04-02_13-26-35,第一次和第二次增备集分别是2017-04-02_13-26-35、2017-04-02_14-03-51。下面是它们的"准备"过程。

# 对整合的开始备份集——全备集应用日志,并指定"--redo-only"表示开始进入日志追加

innobackupex--apply-log --redo-only /bakdir/2017-04-02_13-26-35# 对第一个增备集进行"准备",将其追加到全备集中

innobackupex--apply-log --redo-only /bakdir/2017-04-02_13-26-35 --incremental-dir=/bakdir/2017-04-02_13-39-05# 对第二个增备集进行"准备",将其追加到全备集中,但是不再应用"--redo-only",表示整合的结束点

innobackupex--apply-log /bakdir/2017-04-02_13-26-35 --incremental-dir=/bakdir/2017-04-02_14-03-51# 对整合完成的全备集进行一次整体的"准备"innobackupex--apply-log /bakdir/2017-04-02_13-26-35

当所有的备份集整合完毕后,就像是一个完整的全备集,全备中的LSN会更新到整合的结束点。如下:

[root@xuexi data]# cat /bakdir/2017-04-02_13-26-35/xtrabackup_checkpoints

backup_type= full-prepared

from_lsn= 0to_lsn= 7585150275#整合完成后全备中的LSN

last_lsn= 7585150275compact= 0recover_binlog_info= 0[root@xuexi data]#cat /bakdir/2017-04-02_14-03-51/xtrabackup_checkpoints

backup_type=incremental

from_lsn= 7533372535to_lsn= 7585150275#整合的结束备份集中的LSN

last_lsn= 7585150275compact= 0recover_binlog_info= 0

如果不小心整合的顺序错误了,那么整合的备份集将是无效的,需要重新整合。

(5). 增备的恢复过程

因为整合结束后就等价于一个全备集,所以可以直接进行恢复。

恢复过程同样需要保证MySQL的datadir是空的,且MySQL服务器是stop的。

service mysqld stoprm -rf /mydata/data/*innobackupex --copy-back /bakdir/2017-04-02_13-26-35

chown -R mysql.mysql /mydata/data/*

然后重启MySQL,进入查看可知num_innodb的数据为100W行记录,即恢复成功。

mysql> select count(*) from backuptest.num_innodb;+----------+

| count(*) |

+----------+

| 1000000 |

+----------+

5.3 innobackupex实现导出和导入单张表的过程

默认情况下,InnoDB表不能通过直接复制表文件的方式在mysql服务器之间进行移植,即便使用了innodb_file_per_table选项。而使用Xtrabackup工具可以实现此种功能,不过只能"导出"具有.ibd文件的表,也就是说导出表的mysql服务器启用了innodb_file_per_table选项,而且要导出的表还是在启用该选项之后才创建的。

导入表的是,要求导入表的服务器版本是MySQL 5.6+,且启用了innodb_file_per_table选项。

(1). 导出表

导出表是在"准备"的过程中进行的,不是在备份的时候导出。对于一个已经备份好的备份集,使用"--apply-log"和"--export"选项即可导出备份集中的表。

假如以全备份集/bakdir/2017-04-02_17-41-38为例,要导出其中的表。

innobackupex --apply-log --export /bakdir/2017-04-02_17-41-38

在导出过程中,会看到如下信息:

xtrabackup: export metadata of table 'backuptest/num_innodb' to file `./backuptest/num_innodb.exp` (1 indexes)

xtrabackup: name=PRIMARY, id.low=144, page=3

它说明了创建了一个.exp文件。

查看备份集目录下的backuptest目录,会发现多出了2个文件:.cfg和.exp,再加上.ibd文件,这3个文件是后续导入表时所需的文件。

-rw-r--r-- 1 root root 349 Apr 2 18:15num_innodb.cfg-rw-r----- 1 root root 16K Apr 2 18:15num_innodb.exp-rw-r----- 1 root root 8.4K Apr 2 17:41num_innodb.frm-rw-r----- 1 root root 31M Apr 2 17:41 num_innodb.ibd

其中.cfg文件是一种特殊的innodb数据字典文件,它和exp文件的作用是差不多的,只不过后者还支持在xtradb中导入,严格地讲,要将导出的表导入到MySQL5.6或者percona server 5.6中,".cfg"文件完全可以不需要,但是如果有该文件的话,会进行架构验证。

(2). 导入表

要在mysql服务器上导入来自于其它服务器的某innodb表,需要先在当前服务器上创建一个跟原表表结构一致的表,而后才能实现将表导入:

mysql> CREATE TABLE tabletest (...) ENGINE=InnoDB;

然后将此表的表空间:

mysql> ALTER TABLE mydatabase.tabletest DISCARD TABLESPACE;

接下来,将来自于"导出"表的的.ibd和.exp文件复制到当前服务器的数据目录,如果导入目标服务器是MySQL 5.6+,也可以复制.cfg文件。然后使用如下命令将其“导入”:

mysql> ALTER TABLE mydatabase.tabletest IMPORT TABLESPACE;

5.4 innobackupex实现部分备份和恢复的过程

xtrabackup支持部分备份,意味着可以指定备份哪个数据库或者哪个表。

部分备份只有一点需要注意:在恢复的时候不要通过"--copy-back"的方式拷贝回datadir,而是应该使用导入表的方式。尽管使用拷贝的方式有时候是可行的,但是很多情况下会出现数据库不一致的状态。

(1). 备份

创建部分备份有三种方式:

通过"--include"选项可以指定正则来匹配要备份的表,这种方式要使用完整对象引用格式,即db_name.tab_name的方式。

将要备份的表分行枚举到一个文件中,通过"--tables-file"指定该文件。

或者使用"--databases"指定要备份的数据库或表,指定备份的表时要使用完整对象引用格式,多个元素使用空格分开。

使用前两种部分备份方式,只能备份innodb表,不会备份任何myisam,即使指定了也不会备份。而且要备份的表必须有独立的表空间文件,也就是说必须开启了innodb_file_per_table,更精确的说,要备份的表是在开启了innodb_file_per_table选项之后才创建的。第三种备份方式可以备份myisam表。

例如 --include='^back.*[.]num_*' ,将备份back字母开头的数据库中num开头的表,其中"[.]"的中括号不能少,因为正则中"."有特殊意义,所以使用中括号来枚举以实现对象的完整引用。

innobackupex --user=root --password=123456 --include='^back*[.]num_*' /bakdir/

使用"--include"和"--tables-file"备份后,会生成一个时间戳目录,目录中只有和要备份的表有关的文件。

[root@xuexi data]# ls /bakdir/2017-04-02_17-35-46/backup-my.cnf ibdata1 xtrabackup_binlog_info xtrabackup_checkpoints xtrabackup_info xtrabackup_logfile

如果使用的是--databases选项,则会生成一个时间戳目录,里面有备份的数据库代表的目录,如果只备份了某个表,则该数据库目录中只有该表相关的文件。

innobackupex --user=root --password=123456 --databases='mysql.user backuptest' /bakdir/

上面只备份mysql.user表和backuptest数据库,在生成的时间戳目录中将有两个mysql目录和backuptest目录。

[root@xuexi data]# ls /bakdir/2017-04-02_17-41-38/backup-my.cnf backuptest ibdata1 mysql xtrabackup_binlog_info xtrabackup_checkpoints xtrabackup_info xtrabackup_logfile

[root@xuexi data]#ls /bakdir/2017-04-02_17-41-38/backuptest/db.opt num_innodb.frm num_innodb.ibd num_isam.frm num_isam.MYD num_isam.MYI

[root@xuexi data]#ls /bakdir/2017-04-02_17-41-38/mysql/user.frm user.MYD user.MYI

(2). 部分备份的准备和恢复过程

部分备份的准备和恢复过程分别是导出表和导入表的过程。见上文。

5.5 innobackupex实现定时点恢复

xtrabackup本身无法实现定时点恢复,只能通过恢复备份后通过二进制日志实现。实现方法和一般定时点恢复是一样的。见:

5.6 流备份和远程备份

xtrabackup支持备份流,当前可用的流类型只有tar和xtrabackup自带的xbstream,通过流可以将它们传递给其他程序进行相关的操作,如压缩。但是不建议在备份的同时进行压缩,因为压缩会占用极大的cpu资源,使得备份时间延长很多,温备的过程也就延长了。

另外,MySQL的数据文件压缩比非常大,所以建议备份后在空闲的时候进行压缩。

xtrabackup还支持远程备份,只需使用"--remote-host"指定远程的主机名即可,指定方式和ssh指定的方式一样。如--remote-host=root@192.168.100.18。

使用流备份的方法如下:

# 使用tar流

innobackupex--user=root --password=123456 --stream=tar /bakdir/ >/tmp/a.tar# 使用tar流的同时交给gzip压缩

innobackupex--user=root --password=123456 --stream=tar /bakdir/ | gzip >/tmp/a.tar.gz

# 使用tar流备份到远程主机中并归档

innobackupex--user=root --password=123456 --stream=tar /bakdir/ | ssh root@192.168.100.10 "cat - > /tmp/`date +%F_%H-%M-%S`.tar"# 使用tar流备份到原远程主机中并解包

innobackupex--user=root --password=123456 --stream=tar /bakdir/ | ssh root@192.168.100.10 "cat - | tar -x -C /tmp/"# 使用xtrabackup自带的xbstream流

innobackupex--user=root --password=123456 --stream=xbstream /bakdir/ >/tmp/b.xbs

# 解压xbstream流

innobackupex--user=root --password=123456 --stream=xbstream /bakdir/ | ssh root@192.168.100.10 "cat - | xbstream -x -C /tmp/"# 使用xbstream流的同时进行压缩,使用"--compress"选项

innobackupex--user=root --password=123456 --stream=xbstream --compress /bakdir/ > /bakdir/backup.xbs

注意,如果在解压备份的.tar.gz时出错,可能在解压的时候需要使用-i选项。如tar -xif /tmp/b.tar/gz。

5.7 加速备份

当备份到本地的时候,可以使用"--rsync"选项,该选项用于在flush tables with read lock后调用rsync替代cp进程复制非Innodb数据和.frm文件,加快复制速度。

但要注意,因为支持备份锁的版本在获取到backup locks的时候会自动复制非Innodb数据和.frm文件,所以"--rsync"选项是无效的。

另外,该选项不能和"--stream"选项和"--remote-host"选项同时使用。

6.xtrabackup工具

xtrabackup工具是C语言编写的工具,在innobackupex使用C重写之后,innobackupex是该工具的一个软链接。但是它不能实现innobackupex的所有功能,例如xtrabackup工具没有恢复功能,而innobackupex有"--copy-back"选项来恢复。

xtrabackup工具有两种常用运行模式:"--backup"和"--prepare"。还有两个比较少用的模式:"--stats"和"--print-param"。

由于前文对innobackupex的介绍非常详细,xtrabackup在功能实现上和它是一样的。所以下面将简单介绍。

6.1 xtrabackup实现全备

(1).备份过程

和innobackupex备份过程不同的是,xtrabackup的备份路径是由"--target-dir"选项严格指定的,如果指定的目录不存在,它备份的时候不会在target-dir目录中再创建时间戳子目录。

[root@xuexi data]# xtrabackup --backup --user=root --password=123456 --datadir=/mydata/data --target-dir=/bakdir/fullback

[root@xuexi data]#ls /bakdir/fullback

backup-my.cnf ibdata1 Performance secure_dir xtrabackup_binlog_info xtrabackup_info

backuptest mysql performance_schema world xtrabackup_checkpoints xtrabackup_logfile

(2).准备过程

xtrabackup --prepare --target-dir=/bakdir/fullback

(3).恢复过程

xtrabackup自身不能恢复,只能通过拷贝备份集的方式来恢复。例如使用rsync或者cp等。

另外,恢复时也一样要求MySQL是stop状态,datadir是空目录。并且拷贝完成后要修改datadir中文件的所有者和属组为mysql用户和组。

service mysqld stoprm -rf /mydata/data/*rsync -azP /bakdir/fullback/* /mydata/data

chown -R mysql.mysql /mydata/data/*

6.2 xtrabackup实现增备

(1).首先进行全备

xtrabackup --backup --user=root --password=123456 --datadir=/mydata/data --target-dir=/bakdir/base_full

(2).进行第一次增备

xtrabackup --backup --user=root --password=123456 --target-dir=/bakdir/incr_bak1 --incremental-basedir=/bakdir/base_full --datadir=/mydata/data/

同样也可以在增备时使用"--incremental-lsn"来指定从哪个lsn开始增量备份,这和innobackupex是一样的。

(3).进行第二次增备

xtrabackup --backup --user=root --password=123456 --target-dir=/bakdir/incr_bak2 --incremental-basedir=/bakdir/incr_bak1 --datadir=/mydata/data/

(4).准备过程

准备过程和innobackupex是一样的,使用"--apply-log-only"来直线向前地应用redo log,同样,在最后一个增备集的准备过程中不能使用"--apply-log-only"选项。

xtrabackup --prepare --apply-log-only --target-dir=/bakdir/base_full

xtrabackup--prepare --apply-log-only --target-dir=/bakdir/base_full --incremental-dir=/bakdir/incr_bak1

xtrabackup--prepare --target-dir=/bakdir/base_full --incremental-dir=/bakdir/incr_bak2

(5).恢复阶段

恢复阶段即拷贝阶段,和前面全备的恢复阶段是一样的,要求MySQL停止运行,datadir是空目录,拷贝全备目录到datadir,修改datadir的所有者和属组。

6.3 xtrabackup实现部分备份

xtrabackup部分备份和innobackupex不太一样,innobackupex的部分备份实质上是在已经备份好的备份集上导出导入表,而xtrabackup直接在备份过程中筛选要备份的目标,它不建立在已有的备份集上。

(1).备份过程

xtrabackup使用"--tables"选项对应innobackupex的"--include"选项,它们是一样的,都是正则匹配完整对象引用名称。

使用"--tables-file"选项指定枚举要备份表的列表,每行一个表,表名需要使用完整对象引用名称。和innobackupex一样的。

使用"--databases"和"--databases-file"指定要单独备份的数据库或表,后者可以枚举出要备份的列表。这两个选项不能使用通配符和正则匹配。

例如:

xtrabackup --backup --user=root --password=123456 --target-dir=/bakdir/part_bak1 --datadir=/mydata/data/ --tables="^back*[.]num_*"

(2).准备过程

xtrabackup的部分备份的准备要比innobackupex方便的多,直接对备份集进行"--prepare"即可。

xtrabackup --prepare --target-dir=/bakdir/part_bak1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值