MySQL 备份之 xtrabackup | innobackupex
Xtrabackup 介绍
Xtrabackup 是一个对 InnoDB 做数据备份的工具, 支持在线热备份(备份时不影响数据读写), 是商业备份工具 InnoDB Hotbackup 的一个很好的
替代品.
Xtrabackup 有两个主要的工具: xtrabackup,innobackupex
1,xtrabackup 只能备份 InnoDB 和 XtraDB 两种数据表, 而不能备份 MyISAM 数据表
2,innobackupex 是参考了 InnoDB Hotbackup 的 innoback 脚本修改而来的. innobackupex 是一个 perl 脚本封装, 封装了 xtrabackup. 主要
是为了方便的同时备份 InnoDB 和 MyISAM 引擎的表, 但在处理 myisam 时需要加一个读锁. 并且加入了一些使用的选项. 如 slave-info 可以记录备份
恢复后, 作为 slave 需要的一些信息, 根据这些信息, 可以很方便的利用备份来重做 slave.
3, 官方文档: http://www.percona.com/doc/percona-xtrabackup/2.1/
A,Xtrabackup 是什么?
在线 (热) 备份整个库的 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 保持数据
的一致.
B,Xtrabackup 可以做什么?
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) 备份等, 通过复制数据文件, 复制日志文件和提交日志到数据文件 (前滚) 实现了各种复合备份方 式.
C,Xtrabackup 备份原理
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 的数据. 同样不可以配置.
D,Xtrabackup 实现细节
基于以上原理, xtrabackup 备份恢复工具比较适合数据增长型数据库. 对于数据增长型的库, 由于数据的增长导致数据备份和恢复的空间和时
间上的压力较大. 而 xtrabackup 有增量备份的功能, 在短时间内可以通过进行增量备份来保证数据的安全性. 而长期来看, 仍然需要间断性的进行全库
备份. 此外, 由于 xtrabackup 对 innodb 的数据库不进行锁定, 因此对要求不影响线上服务的数据备份和恢复较适合.
而对于数据量无明显增长, 且更新为主的数据更新型数据库, xtrabackup 显得过于复杂. xtrabackup 操作反而不如 mysqldump 的性能高.
E,Xtrabackup 应用场景
个人理解:
1, 无需停止数据库进行 InnoDB 热备, 快速, 可靠的完成备份
2. 备份期间不间断事务处理
3. 节省磁盘空间和网络带宽
4. 自动对备份文件进行验证
5. 快速恢复, 保障在线运行时间持久性
官方说明:
1. 在不停库的情况下, 对 InnoDB 数据库进行热备
2. 增量备份 MySQL 数据库
3. 通过流压缩备份 MySQL 数据到另外一台服务器
4. 在线 MySQL 服务器之间进行表空间迁移
F,Xtrabackup 优势
Xtrabackup 安装
官网下载:
本文示例安装包下载
下载链接: https://pan.baidu.com/s/1C88-Ninf0cTG3ghBWdMPEw 密码: 0kp1
安装软件
- [root@Admin ~]# yum install libev -y
- [root@Admin ~]# rpm -ivh percona-xtrabackup-24-2.4.7-2.el6.x86_64.rpm
Xtrabackup 实例
创建测试数据
建库: 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)
官方备份用法说明:
$ innobackupex --defaults-file=/tmp/other-my.cnf --user=DBUSER --password=DBUSERPASS /path/to/BACKUP-DIR/
官方恢复用法说明:
用法一:$ 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;
恢复单库操作步骤:
1) 关闭数据库
[root@Admin ~]# /etc/init.d/mysqld stop
2) 恢复日志文件 apply-log
[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --apply-log /backup/dk_data/2018-10-18_21-10-51
3) 把备份文件拷贝至原数据目录下
[root@Admin ~]# cp -ap /backup/dk_data/2018-10-18_21-10-51/ceshi/ /data/DB/
4) 检查数据目录的所有者和权限是否正确
[root@Admin ~]# chown -R MySQL. /data/DB/
5) 重启 MySQL
[root@Admin ~]# /etc/init.d/mysqld start
6) 检查数据
- MySQL> show databases;
- MySQL> use ceshi;
- MySQL> show tables;
- MySQL> select * from users;
- MySQL> show create table users\G
单库增量备份与恢复操作过程
单库增量备份操作步骤:
增量的备份:
1)首先对单库执行一次全备
[root@Admin ~]# innobackupex --defaults-file=/etc/my.cnf --user=root --password=123 --database=ceshi /backup/dk_data/
2)插入数据
- 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','深圳西丽');
3) 对单库进行增量备份
[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 是指第二次的增量备份, 以此类推.
增量的恢复:
1) 关闭数据库
[root@Admin ~]# /etc/init.d/mysqld stop
2) 恢复全备份日志文件(回滚未完成的日志)
[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, 起到先合并事务日志 #
3) 恢复增量备份日志文件
[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(即全备目录)下
4) 恢复增量备份数据文件(拷贝数据)
[root@Admin ~]# \cp -afp /backup/dk_data/2018-10-18_21-33-20/*/data/DB/
5) 授权
[root@Admin ~]# chown -R MySQL. /data/DB/
6) 启动数据库
[root@Admin ~]# /etc/init.d/mysqld start
7) 检查数据
- MySQL> show databases;
- MySQL> select * from ceshi.users;
来源: http://www.bubuko.com/infodetail-2813294.html