Xtrabackup概述
Xtrabackup是由percona开源的免费数据库热备份软件,它能对InnoDB数据库和XtraDB存储引擎的数据库非阻塞地备份(对于MyISAM的备份同样需要加表锁);mysqldump备份方式是采用的逻辑备份,其最大的缺陷是备份和恢复速度较慢,如果数据库大于50G,mysqldump备份就不太适合。
Xtrabackup优点
1)备份速度快,物理备份可靠
2)备份过程不会打断正在执行的事务(无需锁表)
3)能够基于压缩等功能节约磁盘空间和流量
4)自动备份校验
5)还原速度快
6)可以流传将备份传输到另外一台机器上
Xtrabackup原理
Xtrabackup安装后有4个可执行文件,其中2个比较重要的备份工具是innobackupex、xtrabackup
1)xtrabackup 是专门用来备份InnoDB表的,不能备份非Innodb表,和mysql server没有交互;
2)innobackupex 是一个脚本,用来备份非InnoDB表,同时会调用xtrabackup命令来备份InnoDB表,还会和mysql server交互,比如锁表、获取位置点等。简单地说,就是在xtrabackup基础上做了一层封装;
3)xbcrypt 加密解密备份工具。
4)xbstream 流传打包传输工具,类似tar。

1)在使用InnoDB引擎表内部会维护一个redo日志文件,我们也可以叫做事务日志文件。事务日志会存储每一个InnoDB表数据的记录修改
2)xtrabackup在启动时会记住log sequence number(LSN)日志序列号,即当前的redo记录的位置,并且复制所有数据文件。
3)复制过程需要一些时间,所以这期间如果数据文件LSN有改动,它会运行一个后台进程,用于监控事务日志,并不停地将事务日志中每个数据文件的修改都记下来。
Xtrabackup流程图
(1)innobackupex启动后,会先fork一个进程,用于启动xtrabackup,然后等待xtrabackup备份ibd数据文件;
(2)xtrabackup在备份innoDB数据,有2种线程:redo拷贝线程和ibd数据拷贝线程。xtrabackup进程开始执行后,会启动一个redo拷贝的线程,用于从最新的checkpoint点开始顺序拷贝redo.log;再启动ibd数据拷贝线程,进行拷贝ibd数据。这里是先启动redo拷贝线程的。在此阶段,innobackupex进行处于等待状态(等待文件被创建)
(4)xtrabackup拷贝完成ibd数据文件后,会通知innobackupex(通过创建文件),同时xtrabackup进入等待状态(redo线程依旧在拷贝redo.log)
(5)innobackupex收到xtrabackup通知后哦,执行FLUSH TABLES WITH READ LOCK(FTWRL),取得一致性位点,然后开始备份非InnoDB文件(如frm、MYD、MYI、CSV、opt、par等格式的文件),在拷贝非InnoDB文件的过程当中,数据库处于全局只读状态。
(6)当innobackup拷贝完所有的非InnoDB文件后,会通知xtrabackup,通知完成后,进入等待状态;
(7)xtrabackup收到innobackupex备份完成的通知后,会停止redo拷贝线程,然后通知innobackupex,redo.log文件拷贝完成;
(8)innobackupex收到redo.log备份完成后,就进行解锁操作,执行:UNLOCK TABLES;
(9)最后innbackupex和xtrabackup进程各自释放资源,写备份元数据信息等,innobackupex等xtrabackup子进程结束后退出。
上述在上面描述的文件拷贝,都是备份进程直接通过操作系统读取数据文件的,只在执行SQL命令时和数据库有交互,基本不影响数据库的运行,在备份非 InnoDB 时会有一段时间只读(如果没有MyISAM表的话,只读时间在几秒左右),在备份InnoDB数据文件时,对数据库完全没有影响,是真正的热备。
InnoDB 和非 InnoDB 文件的备份都是通过拷贝文件来做的,但是实现的方式不同,前者是以page为粒度做的(xtrabackup),后者是 cp 或者 tar 命令(innobackupex),xtrabackup 在读取每个page时会校验 checksum 值,保证数据块是一致的,而 innobackupex 在 cp MyISAM 文件时已经做了flush(FTWRL),磁盘上的文件也是完整的,所以最终备份集里的数据文件都是写入完整的。
扩展理解
数据存放于row中,row存在于page中,page存于extent中,所以我们备份extent中的page(page是innodb引擎的最小物理存储分配单位),即可备份出对应的数据。
innodb逻辑存储结构图

xtrabackup增备
每个Page都有自己的LSN号码,LSN是一个全局递增的号码,每次对page中的记录进行修改时,都会产生新的LSN号码。
假设,我们第一次备份的数据如下,所有数据由如下6个page组成,下图中的黄色方块代表page,黄色方块右上角的号码代表当前page的LSN,从下图可看出,目前最大的LSN号码为5。

假设备份完成后,我们修改了数据,而这次修改的数据存在于上图中的page C与page E中,所以上图中的pageC与pageE的LSN就变成6

如果此时要做增量备份,我们只需要备份出自上次备份以后变化的数据即可,找到LSN大于5的Page,即上图中的pageC与pageE,即可得出变化的增量数据,得出上图中的增量page后,再将增量page覆盖到上次的备份中,即可得到最新的数据。
参考:
percona提供的mysql数据库备份工具,惟一开源的能够对innodb和xtradb数据库进行热备的工具手册
https://www.percona.com/doc/percona-xtrabackup/LATEST/index.html
附:
yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL //安装依赖包
yum install cmake gcc gcc-c++ libaio libaio-devel automake autoconf bzr bison libtool ncurses-devel zlib-devel libgcrypt-devel perl-ExtUtils-MakeMaker perl-DBD-MySQL.* perl-Time-HiRes -y
[root@LHRDB bin]# xtrabackup2414 --version
xtrabackup2414: error while loading shared libraries: libgcrypt.so.20: cannot open shared object file: No such file or directory
[root@LHRDB bin]# yum list installed|grep libgcrypt
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
libgcrypt.x86_64 1.4.5-11.el6_4 @anaconda-RedHatEnterpriseLinux-201311111358.x86_64/6.5
查看服务器上的libgcrypt版本,发现是xtrabackup版本下载错误,下载对应的libgcrypt的版本的包就可以了.
percona-xtrabackup-2.4.14-Linux-x86_64.libgcrypt145.tar.gz
RHEL6.5:
tar -xvf Percona-XtraBackup-2.2.10-re623acb-el6-x86_64-bundle.tar
yum install perl-DBD-MySQL
rpm -ivh percona-xtrabackup-2.2.10-1.el6.x86_64.rpm
注意:XtraBackup-2.2.10不支持MySQL5.7
RHEL6.5:
tar -zxvf percona-xtrabackup-2.4.14-Linux-x86_64.libgcrypt183.tar.gz
mv percona-xtrabackup-2.4.14-Linux-x86_64 /usr/local/percona-xtrabackup-2.4.14-Linux-x86_64
ln -s /usr/local/percona-xtrabackup-2.4.14-Linux-x86_64 /usr/local/xtrabackup-2.4.14
ln -s /usr/local/percona-xtrabackup-2.4.14-Linux-x86_64/bin/innobackupex /usr/bin/innobackupex2414
ln -s /usr/local/percona-xtrabackup-2.4.14-Linux-x86_64/bin/xtrabackup /usr/bin/xtrabackup2414
innobackupex --version
xtrabackup --version
innobackupex --help
备份与恢复
建库:
create database ceshi;
建表1:
create table ceshi.users (id int primary key auto_increment,name varchar(20) not null unique,password varchar(100) not null,address varchar(200)) ENGINE=MyISAM;
添数据:
insert into ceshi.users (id,name,password,address) values (1,'zhang','1234',null),(2,'wang','4321','湖北武汉'), (3,'li','5678','北京海淀');
建库:
create database ceshi2;
建表1=2:
create table ceshi2.articles (id int primary key auto_increment,content longtext not null) ENGINE=InnoDB;
添数据:
insert into ceshi2.articles (id,content) values (11,'hahahahahaha'),(12,'xixixixixix'),(13,'aiaiaiaia'),(14,'hohoahaoaooo');
---完全备份恢复
innobackupex2414 --defaults-file=/etc/my.cnf --host=192.168.59.159 --user=root --password=lhr --socket=/var/lib/mysql57/mysql5719/mysql.sock --port=3306 --target-dir=/backup/mysql5719_3306/full/ --backup
innobackupex2414 --prepare --target-dir=/backup/mysql5719_3306/full/
innobackupex2414 --copy-back --target-dir=/backup/mysql5719_3306/full/ --datadir=/var/lib/mysql57/mysql5719/data
chown -R mysql:mysql /var/lib/mysql57/mysql5719/data
--- 增量备份恢复
insert into ceshi.users (id,name,password,address) values (4,'zhang','1234',null),(5,'wang','4321','湖北武汉'), (6,'li','5678','北京海淀');
insert into ceshi2.articles (id,content) values (21,'hahahahahaha'),(22,'xixixixixix'),(23,'aiaiaiaia'),(24,'hohoahaoaooo');
--一级增量
innobackupex2414 --backup --target-dir=/backup/mysql5719_3306/inc1 --incremental-basedir=/backup/mysql5719_3306/full/
innobackupex2414 --prepare --apply-log-only --target-dir=/backup/mysql5719_3306/full/
innobackupex2414 --prepare --apply-log-only --target-dir=/backup/mysql5719_3306/full/ --incremental-dir=/backup/mysql5719_3306/inc1
innobackupex2414 --copy-back --target-dir=/backup/mysql5719_3306/full/ --datadir=/var/lib/mysql57/mysql5719/data
chown -R mysql:mysql /var/lib/mysql57/mysql5719/data
--二级增量
innobackupex2414 --backup --target-dir=/backup/mysql5719_3306/inc1 --incremental-basedir=/backup/mysql5719_3306/full/
innobackupex2414 --backup --target-dir=/backup/mysql5719_3306/inc2 --incremental-basedir=/backup/mysql5719_3306/inc1
innobackupex2414 --prepare --apply-log-only --target-dir=/backup/mysql5719_3306/full/
innobackupex2414 --prepare --apply-log-only --target-dir=/backup/mysql5719_3306/full/ --incremental-dir=/backup/mysql5719_3306/inc1
innobackupex2414 --prepare --apply-log-only --target-dir=/backup/mysql5719_3306/full/ --incremental-dir=/backup/mysql5719_3306/inc2
innobackupex2414 --copy-back --target-dir=/backup/mysql5719_3306/full/ --datadir=/var/lib/mysql57/mysql5719/data
chown -R mysql:mysql /var/lib/mysql57/mysql5719/data

