Xtrabackup 是一个对 InnoDB 作数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工具 InnoDB Hotbackup 的一个很好的
替代品。
Xtrabackup有两个主要的工具:xtrabackup、innobackupex
一、xtrabackup只能备份InnoDB和XtraDB两种数据表,而不能备份MyISAM数据表
二、innobackupex 是参考了 InnoDB Hotbackup 的 innoback 脚本修改而来的.innobackupex 是一个 perl 脚本封装,封装了 xtrabackup。主要
是为了方便的同时备份InnoDB和MyISAM引擎的表,但在处理myisam时须要加一个读锁。而且加入了一些使用的选项。如slave-info能够记录备份
恢复后,做为slave须要的一些信息,根据这些信息,能够很方便的利用备份来重作slave。
三、官方文档:http://www.percona.com/doc/percona-xtrabackup/2.1/
在线(热)备份整个库的InnoDB、 XtraDB表
在xtrabackup的上一次整库备份基础上作增量备份(innodb only)
以流的形式产生备份,能够直接保存到远程机器上(本机硬盘空间不足时颇有用)
MySQL数据库自己提供的工具并不支持真正的增量备份,二进制日志恢复是point-in-time(时间点)的恢复而不是增量备份。Xtrabackup工具支持
对InnoDB存储引擎的增量备份,工做原理以下:
(1)首先完成一个彻底备份,并记录下此时检查点的LSN(Log Sequence Number)。
(2)在进程增量备份时,比较表空间中每一个页的LSN是否大于上次备份时的LSN,若是是,则备份该页,同时记录当前检查点的LSN。
首先,在 logfile 中找到并记录最后一个 checkpoint(“last checkpoint LSN”),而后开始从 LSN 的位置开始拷贝 InnoDB 的 logfile 到
xtrabackup_logfile;接着,开始拷贝所有的数据文件.ibd;在拷贝所有数据文件结束以后,才中止拷贝logfile。
由于logfile里面记录所有的数据修改状况,因此,即时在备份过程当中数据文件被修改过了,恢复时仍然可以经过解析xtrabackup_logfile保持数据
的一致。
XtraBackup基于InnoDB的crash-recovery功能。它会复制innodb的data file,因为不锁表,复制出来的数据是不一致的,在恢复的时候使用
crash-recovery,使得数据恢复一致。
InnoDB维护了一个redo log,又称为transaction log,事务日志,它包含了innodb数据的全部改动状况。当InnoDB启动的时候,它会先去检
查data file和transaction log,而且会作二步操做:
XtraBackup在备份的时候, 一页一页地复制innodb的数据,并且不锁定表,与此同时,XtraBackup还有另一个线程监视着transactions log,
一旦log发生变化,就把变化过的log pages复制走。为何要急着复制走呢? 由于transactions log文件大小有限,写满以后,就会从头再开始写,
因此新数据可能会覆盖到旧的数据。
在prepare过程当中,XtraBackup使用复制到的transactions log对备份出来的innodb data file进行crash recovery。
官方原理
在 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的,
InnoDB的prepare过程能够称为 recover(恢复), myisam的数据复制过程能够称为restore(还原)。
Xtrabackup 和 innobackupex 这两个工具都提供了许多前文没有提到的功能特色。手册上有对各个功能都有详细的介绍。简单介绍下,这些工具提供
了如流 (streaming)备份,增量(incremental)备份等,经过复制数据文件,复制日志文件和提交日志到数据文件(前滚)实现了各类复合备份方 式。
XtraBackup以read-write模式打开innodb的数据文件,而后对其进行复制。其实它不会修改此文件。也就是说,运行XtraBackup的用户,必须
对 innodb 的数据文件具备读写权限。之因此采用 read-write 模式是由于 XtraBackup 采用了其内置的 innodb 库来打开文件,而 innodb 库打开文件
的时候就是rw的。
XtraBackup要从文件系统中复制大量的数据,因此它尽量地使用posix_fadvise(),来告诉OS不要缓存读取到的数据,从而提高性能。由于这些
数据不会重用到了,OS却没有这么聪明。若是要缓存一下的话,几个G的数据,会对OS的虚拟内存形成很大的压力,其它进程,好比mysqld颇有可
能被swap出去,这样系统就会受到很大影响了。
在备份 innodb page 的过程当中,XtraBackup 每次读写 1MB 的数据,1MB/16KB=64 个 page。这个不可配置。读 1MB 数据以后,XtraBackup
一页一页地遍历这 1MB 数据,使用 innodb 的 buf_page_is_corrupted()函数检查此页的数据是否正常,若是数据不正常,就从新读取这一页,最多重
新读取10次,若是仍是失败,备份就失败了,退出。在复制transactions log的时候,每次读写512KB的数据。一样不能够配置。
基于以上原理,xtrabackup 备份恢复工具比较适合数据增加型数据库。对于数据增加型的库,因为数据的增加致使数据备份和恢复的空间和时
间上的压力较大。而xtrabackup有增量备份的功能,在短期内能够经过进行增量备份来保证数据的安全性。而长期来看,仍然须要间断性的进行全库
备份。此外,因为xtrabackup对innodb的数据库不进行锁定,所以对要求不影响线上服务的数据备份和恢复较适合。
而对于数据量无明显增加,且更新为主的数据更新型数据库,xtrabackup显得过于复杂。xtrabackup操做反而不如mysqldump的性能高。
我的理解:
一、无需中止数据库进行InnoDB热备,快速、可靠的完成备份
2.备份期间不间断事务处理
3.节省磁盘空间和网络带宽
4.自动对备份文件进行验证
5.快速恢复,保障在线运行时间持久性
官方说明:
1.在不停库的状况下,对InnoDB数据库进行热备
2.增量备份MySQL数据库
3.经过流压缩备份MySQL数据到另一台服务器
4.在线MySQL服务器之间进行表空间迁移
官网下载:https://www.percona.com/downloads/XtraBackup/LATEST/mysql
本文示例安装包下载sql
下载连接:https://pan.baidu.com/s/1C88-Ninf0cTG3ghBWdMPEw 密码:0kp1数据库
安装软件vim
[root@Admin ~]# yum install libev -y [root@Admin ~]# rpm -ivh percona-xtrabackup-24-2.4.7-2.el6.x86_64.rpm
建立测试数据缓存
建库:mysql> create database ceshi; 建表:mysql> create table users (id int primary key auto_increment,name varchar(20) not null unique,password varchar(100) not null,address varchar(200))ENGINE=MyISAM; 添加数据:mysql> insert into users (id,name,password,address) values (1,'zhang','1234',null),(2,'wang','4321','湖北武汉'), (3,'li','5678','北京海淀'); 建库:mysql> create database test2; 建表:mysql> create table articles (id int primary key auto_increment,content longtext not null); 添加数据:mysql> insert into articles (id,content) values (11,'hahahahahaha'),(12,'xixixixixix'),(13,'aiaiaiaia'),(14,'hohoahaoaooo');
建立备份目录:安全
[root@Admin ~]# mkdir -p /backup/{full_data,dk_data,zl_data}
注:full_data 全库备份目录
dk_data 单库备份目录
zl_data 增量备份目录服务器
全库备份(All DB)网络
官方备份用法说明:oracle
$ innobackupex --defaults-file=/tmp/other-my.cnf --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/
官方恢复用法说明:app
用法一:$ innobackupex --apply-log /path/to/BACKUP-DIR
用法二:$ innobackupex --apply-log --use-memory=4G /path/to/BACKUP-DIR
注:--use-memory=4G 该参数在 prepare 的时候使用,控制 prepare 时 innodb 实例使用的内存量
全库备份操做步骤:
第一步:执行备份全库命令
[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 /backup/full_data
注:--defaults-file:默认配置文件的路径,若是不应参数,xtrabackup 将从依次从如下位置查找配置文件/etc/my.cnf、/etc/mysql/my.cnf、/usr/local/etc/my.cnf、 ~/.my.cnf,并读取配置文件中的[mysqld]和[xtrabackup]配置段。[mysqld]中只须要指定datadir、innodb_data_home_dir、innodb_data_file_path、innodb_log_group_home_dir、innodb_log_files_in_group、innodb_log_file_size6个参数便可让xtrabackup正常工做。 --user:受权的数据库用户 --password:数据库用户的密码 --target-dir=name备份文件的存放目录路径(即:/backup/full_data )
第二步:恢复准备:
[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --apply-log /backup/full_data/2018-10-18_20-58-04
第三步:停库:
[root@Admin ~]# /etc/init.d/mysqld stop
第四步:把备份文件拷贝至原数据目录下并受权:
[root@Admin ~]# rm -rf /data/DB/* # 把数据目录删除测试 [root@Admin ~]# cp /backup/full_data/2018-10-18_20-58-04/* /data/DB/ [root@Admin ~]# chown -R mysql. /data/DB/
第五步:重启数据库:
[root@Admin ~]# /etc/init.d/mysqld start
第六步:查看数据:
mysql> show databases; mysql> use ceshi; mysql> show tables; mysql> select * from users;
单库备份跟全库用法是同样的,只不过单库在备份里,要指定要备份的数据库名,即: --databases=LIST
单库备份操做步骤:
全量备份:
[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --database=ceshi /backup/dk_data
注:若是是备份从库的话,须要添加参数:--slave-info,即: [root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --slave-info --database=ceshi /tmp
删除ceshi库,方便后面测试是否恢复成功:
mysql> drop database ceshi;
恢复单库操做步骤:
[root@Admin ~]# /etc/init.d/mysqld stop
[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --apply-log /backup/dk_data/2018-10-18_21-10-51
[root@Admin ~]# cp -ap /backup/dk_data/2018-10-18_21-10-51/ceshi/ /data/DB/
[root@Admin ~]# chown -R mysql. /data/DB/
[root@Admin ~]# /etc/init.d/mysqld start
mysql> show databases; mysql> use ceshi; mysql> show tables; mysql> select * from users; mysql> show create table users\G
单库增量备份操做步骤:
增量的备份:
[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --database=ceshi /backup/dk_data/
mysql> select * from users; mysql> insert into users (id,name,password,address) values (4,'liu','1122',null),(5,'zou','4311','湖南长沙'), (6,'zhou','6789','北京八 宝山'), (7,'ding','7891','深圳西丽');
[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --database=ceshi --incremental --incremental-basedir=/backup/dk_data/2018-10-18_21-33-20 /backup/zl_data
注: --incremental 指备份类型为增量备份,作增量备份以前首先要作一次全量备份,因此 --incremental-basedir=/backup/dk_data/2014-05-30_23-26-22 的目录 就是--incremental-basedir=BASEDIR /backup/zl_data就是 --incremental-basedir=INCREMENTAL-DIR-1 INCREMENTAL-DIR-1是指第一次的增量备份,INCREMENTAL-DIR-2是指第二次的增量备份,以此类推。
增量的恢复:
[root@Admin ~]# /etc/init.d/mysqld stop
[root@Admin ~]# innobackupex --defaluts-file=/etc/my.cnf --user=root --password=123 --apply-log --redo-only /backup/dk_data/2018-10-18_21-33-20
加选项:--apply-log-only做用是:只应用redo log,不对数据的rollback,起到先合并事务日志#
[root@Admin ~]# innobackupex --defaluts-file=/etc/my.cnf --user=root --password=123 --apply-log --red-only /backup/dk_data/2018-10-18_21-33-20 --incremental-dir=/backup/zl_data/2018-10-18_22-17-33
注:其中BASE-DIR是指全备目录,INCREMENTAL-DIR-1是指第一次的增量备份,INCREMENTAL-DIR-2是指第二次的增量备份,以此类推。 BASE-DIR:/backup/dk_data/2014-05-30_11-56-51 INCREMENTAL-DIR-1:/backup/zl_data/2014-05-31_03-01-33 以上语句执行成功以后,最终数据在BASE-DIR(即全备目录)下
[root@Admin ~]# \cp -afp /backup/dk_data/2018-10-18_21-33-20/* /data/DB/
[root@Admin ~]# chown -R mysql. /data/DB/
[root@Admin ~]# /etc/init.d/mysqld start
mysql> show databases; mysql> select * from ceshi.users;
建立测试数据
建库:mysql> create database db01; 建表:mysql> create table db01.t1(id int, name varchar(10)) engine=myisam; 增长数据:mysql> insert into db01.t1 values(1,'mona'); 建表:mysql> create table db01.t2(id int, name varchar(10)) engine=innodb; 增长数据:mysql> insert into db01.t2 values(2,'tom');
查看当前表里的数据
mysql> select * from t1; +------+------+ | id | name | +------+------+ | 1 | mona | +------+------+ 1 row in set (0.02 sec) mysql> select * from t2; +------+------+ | id | name | +------+------+ | 2 | tom | +------+------+ 1 row in set (0.00 sec)
开启二进制日志
[root@Admin ~]# vim /etc/my.cnf log-bin=mysql-bin [root@Admin ~]# /etc/init.d/mysqld restart
备份操做步骤:
一、建立备份目录
[root@Admin ~]# mkdir -p /backup/innobackupex
二、使用innobackupex对数据库作全库备份
[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 /backup/innobackupex/
三、数据库更新
mysql> insert into db01.t1 values(2,'jack'); mysql> insert into db01.t2 values(2,'aaa'); mysql> update db01.t1 set name='harry' where id=1;
查看数据
mysql> select * from t1; +------+-------+ | id | name | +------+-------+ | 1 | harry | | 2 | jack | +------+-------+ 2 rows in set (0.00 sec) mysql> select * from t2; +------+------+ | id | name | +------+------+ | 2 | tom | | 2 | aaa | +------+------+ 2 rows in set (0.00 sec)
四、预备过程
[root@Admin ~]# innobackupex --apply-log /backup/innobackupex/2018-10-19_12-13-06/
五、备份二进制日志
查看备份目录里面的日志文件是从哪里开始记录的,再作相应的备份
[root@Admin ~]# cat /backup/innobackupex/2018-10-19_12-13-06/xtrabackup_binlog_info mysql-bin.000004 1119 [root@Admin ~]# mysqlbinlog --start-position=1119 /data/DB/mysql-bin.000004 > /backup/innobackupex/update.sql 这里备份只是备份改变后的数据就能够了
六、恢复演练
[root@Admin ~]# rm -rf /data/DB/*
[root@Admin ~]# killall -9 mysqld
[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --copy-back /backup/innobackupex/2018-10-19_12-13-06/
[root@Admin ~]# chown mysql. /data/DB/ -R
[root@Admin ~]# /etc/init.d/mysqld start 恢复后能够看见数据库里面的文件是最初始化时候的,也就是备份完成时的内容 mysql> select * from db01.t1; +------+------+ | id | name | +------+------+ | 1 | mona | +------+------+ 1 row in set (0.00 sec) mysql> select * from db01.t2; +------+------+ | id | name | +------+------+ | 2 | tom | +------+------+ 1 row in set (0.00 sec)
能够直接在数据库里面source备份的日志文件(由于备份的日志文件里面是sql语句) mysql> source /backup/innobackupex/update.sql 恢复完成后再次查看数据,能够发现已经恢复到最新状态的数据 mysql> select * from db01.t2; +------+------+ | id | name | +------+------+ | 2 | tom | | 2 | aaa | +------+------+ 2 rows in set (0.00 sec) mysql> select * from db01.t1; +------+-------+ | id | name | +------+-------+ | 1 | harry | | 2 | jack | +------+-------+ 2 rows in set (0.00 sec)