Percona-xtrabackup 使用详解与原理
现在有个需求需要对使用 innodb 的数据库进行热备。网上查了很多工具皆推荐 Percona-xtrabackup 于是就仔细了解调研一番。
我们可以前往 https://www.percona.com/downloads/XtraBackup/LATEST/ 下载我们需要的 linux 发行版的对应版本。 这里我下载了最近的稳定版本 2.4.12 rpm 包。
使用 tar -zvf 解压后 得到了好几个 rpm 文件。 安装了 percona-xtrabackup-24-2.4.12-1.el7.x86_64.rpm 并且提示需要下载 libev-4.24-7.fc29.x86_64.rpm 。
可能还需要安装 perl dbd:mysql 和 perl(Digest::MD5) 看自己机器缺什么组件。(PS: 千万别乱删 centos 下的 perl。可能关联非常多的组件!
yum install perl-DBD-mysql
yum install perl-Digest-MD5 rpm -ivh libev-4.24-.fc29.x86_64.rpm
rpm -ivh percona-xtrabackup--2.4.-.el7.x86_64.rpm
https://fedora.pkgs.org/rawhide/fedora-x86_64/libev-4.24-7.fc29.x86_64.rpm.html 下载对应包。
安装了通用版本的 libev-4.24-7.fc29.x86_64.rpm 包之后就算成功安装完成啦!
当我们安装完成之后运行目录如下:
usr
├── bin
│ ├── innobackupex
│ ├── xbcrypt
│ ├── xbstream
│ └── xtrabackup
有四个工具可以给我们直接调用。其中最主要的是 innobackupex
和 xtrabackup
,前者是一个 perl 脚本,后者是 C/C++ 编译的二进制。
下面内容来引用于 rds 内核组文章,由于写得很好原理也很清晰所以直接贴过来做 backup 了。
其中最主要的是
innobackupex
和xtrabackup
,前者是一个 perl 脚本,后者是 C/C++ 编译的二进制。
xtrabackup
是用来备份 InnoDB 表的,不能备份非 InnoDB 表,和 mysqld server 没有交互;innobackupex
脚本用来备份非 InnoDB 表,同时会调用xtrabackup
命令来备份 InnoDB 表,还会和 mysqld server 发送命令进行交互,如加读锁(FTWRL)、获取位点(SHOW SLAVE STATUS)等。简单来说,innobackupex
在xtrabackup
之上做了一层封装。一般情况下,我们是希望能备份 MyISAM 表的,虽然我们可能自己不用 MyISAM 表,但是 mysql 库下的系统表是 MyISAM 的,因此备份基本都通过
innobackupex
命令进行;另外一个原因是我们可能需要保存位点信息。另外2个工具相对小众些,
xbcrypt
是加解密用的;xbstream
类似于tar,是 Percona 自己实现的一种支持并发写的流文件格式。两都在备份和解压时都会用到(如果备份用了加密和并发)。本文的介绍的主角是
innobackupex
和xtrabackup
。原理
通信方式
2个工具之间的交互和协调是通过控制文件的创建和删除来实现的,主要文件有:
- xtrabackup_suspended_1
- xtrabackup_suspended_2
- xtrabackup_log_copied
举个栗子,我们来看备份时 xtrabackup_suspended_2 是怎么来协调2个工具进程的
innobackupex
在启动xtrabackup
进程后,会一直等xtrabackup
备份完 InnoDB 文件,方式就是等待 xtrabackup_suspended_2 这个文件被创建出来;xtrabackup
在备完 InnoDB 数据后,就在指定目录下创建出这个文件,然后等这个文件被innobackupex
删除;innobackupex
检测到文件 xtrabackup_suspended_2 被创建出来后,就继续往下走;innobackupex
在备份完非 InnoDB 表后,删除 xtrabackup_suspended_2 这个文件,这样就通知xtrabackup
可以继续了,然后等 xtrabackup_log_copied 被创建;xtrabackup
检测到 xtrabackup_suspended_2 文件删除后,就可以继续往下了。是不是感觉有点不可思议,通过文件是否存在来控制进程,这种方式非常的不靠谱,因为非常容易被外部干扰,比如文件被别人误删掉,或者2个正在跑的备份控制文件误放在同一个目录下,就等着备份乱掉吧,但是 Percona 就是这么干的。
之所以这么搞,估计主要是因为 perl 和 C 二进制2个进程,没有既好用又方便的通信方式,搞个协议啥的太麻烦了。但是官方也觉得这种方式不靠谱,11年就搞了个 blueprint 要用C重写
innobackupex
,终于在2.3 版本实现了,innobackupex
功能全部集成到xtrabackup
里面,只有一个 binary,另外为了使用上的兼容考虑,innobackupex
作为xtrabackup
的一个软链。对于二次开发来说,2.3 摆脱了之前2个进程协作的负担,架构上明显要好于之前版本。考虑到 perl + C 这种架构的长期存在,大多数读者朋友也基本用的2.3之前版本,本文的介绍也是基于老的架构(2.2版本),但是原理和2.3是一样的,只是实现上的差别。
可以看到在 2.3 之前的版本,都是通过对文件的生成的监控来控制整个备份流程的。
innobackupex
在启动后,会先 fork 一个进程,启动xtrabackup
进程,然后就等待xtrabackup
备份完 ibd 数据文件;xtrabackup
在备份 InnoDB 相关数据时,是有2种线程的,1种是 redo 拷贝线程,负责拷贝 redo 文件,1种是 ibd 拷贝线程,负责拷贝 ibd 文件;redo 拷贝线程只有一个,在 ibd 拷贝线程之前启动,在 ibd 线程结束后结束。xtrabackup
进程开始执行后,先启动 redo 拷贝线程,从最新的 checkpoint 点开始顺序拷贝 redo 日志;然后再启动 ibd 数据拷贝线程,在xtrabackup
拷贝 ibd 过程中,innobackupex
进程一直处于等待状态(等待文件被创建)。xtrabackup
拷贝完成idb后,通知innobackupex
(通过创建文件),同时自己进入等待(redo 线程仍然继续拷贝);innobackupex
收到xtrabackup
通知后,执行FLUSH TABLES WITH READ LOCK
(FTWRL),取得一致性位点,然后开始备份非 InnoDB 文件(包括 frm、MYD、MYI、CSV、opt、par等)。拷贝非 InnoDB 文件过程中,因为数据库处于全局只读状态,如果在业务的主库备份的话,要特别小心,非 InnoDB 表(主要是MyISAM)比较多的话整库只读时间就会比较长,这个影响一定要评估到。- 当
innobackupex
拷贝完所有非 InnoDB 表文件后,通知xtrabackup
(通过删文件) ,同时自己进入等待(等待另一个文件被创建);xtrabackup
收到innobackupex
备份完非 InnoDB 通知后,就停止 redo 拷贝线程,然后通知innobackupex
redo log 拷贝完成(通过创建文件);innobackupex
收到 redo 备份完成通知后,就开始解锁,执行UNLOCK TABLES
;- 最后
innobackupex
和xtrabackup
进程各自完成收尾工作,如资源的释放、写备份元数据信息等,innobackupex
等待xtrabackup
子进程结束后退出。在上面描述的文件拷贝,都是备份进程直接通过操作系统读取数据文件的,只在执行 SQL 命令时和数据库有交互,基本不影响数据库的运行,在备份非 InnoDB 时会有一段时间只读(如果没有MyISAM表的话,只读时间在几秒左右),在备份 InnoDB 数据文件时,对数据库完全没有影响,是真正的热备。
InnoDB 和非 InnoDB 文件的备份都是通过拷贝文件来做的,但是实现的方式不同,前者是以page为粒度做的(
xtrabackup
),后者是 cp 或者 tar 命令(innobackupex
),xtrabackup
在读取每个page时会校验 checksum 值,保证数据块是一致的,而innobackupex
在 cp MyISAM 文件时已经做了flush(FTWRL),磁盘上的文件也是完整的,所以最终备份集里的数据文件都是写入完整的。
以上就是 xtrabakcup 工具工作的原理。
下面我们来实际操作一把:
1. 首先去想要存放备份的地方建个文件夹
2. 进行一次全备
innobackupex -uxbackup -pbackup123 /data/backup/backup # 最好不要加 --no-timestamp 否则不会创建文件夹打包,会直接放在这个目录下面。不太适合定期全备。
当备份完成之后,我们不能直接使用这些备份进行恢复,我们还需要进行一步 preparing 操作以对其时间点
在使用xtrabackup——backup选项进行备份之后,首先需要准备它以便恢复。数据文件在准备好之前不是时间点一致的,因为它们是在程序运行的不同时间复制的,并且在这一过程中它们可能已经被更改了。如果您试图用这些数据文件启动InnoDB,它会检测到损坏并崩溃,以防止您在损坏的数据上运行。xtrabackup—prepare步骤使文件在某个时刻内完全一致,因此您可以在这些文件上运行InnoDB。
xtrabackup --prepare --target-dir=/data/backups/
使用上面命令对备份完成的副本进行立即 prepare 即可,prepare 之后就可以用这个副本进行恢复了。
如此简单 一次全备就完成了
之后我们执行
移除datadir:
$ mv /data/mysql_data /data/mysql_data.bk 恢复数据
$ innobackupex --copy-back /data/backup/backup/ 修改新datadir的权限
$ chown mysql:mysql -R /data/mysql_data
就可以将我们备份的数据恢复了。
我们再来看看局部备份:
增量备份我们需要数据库设置了 innodb_file_per_table 开启,让 pxb 能拿到对应库的结构才可以。
这里直接贴一个我平时备份用的脚本
#!/usr/bin/env bash
# 备份 mysql
targetDir=/data1/mysql_backup/
innobackupex --lock-wait-timeout=10 --include='^cms_db' -uxxx -pxxx $targetDir
filename=`ls -ltr $targetDir | tail -n 1 | awk '{print $9}'`
innobackupex --apply-log --export $targetDir$filename
这里会把工作做到 preparing 结束
之后恢复需要参考
https://www.percona.com/doc/percona-xtrabackup/2.4/innobackupex/restoring_individual_tables_ibk.html
按照单个表的规则来进行恢复
Importing tables
To import a table to other server, first create a new table with the same structure as the one that will be imported at that server:
OTHERSERVER|mysql> CREATE TABLE mytable (...) ENGINE=InnoDB;then discard its tablespace:
OTHERSERVER|mysql> ALTER TABLE mydatabase.mytable DISCARD TABLESPACE;Next, copy
mytable.ibd
andmytable.exp
( ormytable.cfg
if importing to MySQL 5.6) files to database’s home, and import its tablespace:OTHERSERVER|mysql> ALTER TABLE mydatabase.mytable IMPORT TABLESPACE;Set the owner and group of the files:
$ chown -R mysql:mysql /datadir/db_name/table_name.*After running this command, data in the imported table will be available.
即可。
Reference:
http://mysql.taobao.org/monthly/2016/03/07/ 阿里云 rds 内核组 Percona-xtrabackup 文章
https://www.percona.com/doc/percona-xtrabackup/2.4/backup_scenarios/full_backup.html full backup 官方文档
https://www.aliyun.com/jiaocheng/1106116.html Percona XtraBackup 备份和还原数据库
http://www.ttlsa.com/mysql/the-database-part-of-backup-using-percona-xtrabackup/ 使用Percona Xtrabackup对数据库进行部分备份
https://www.linuxidc.com/Linux/2017-03/142380.htm Percona XtraBackup 实现全备&增量备份与恢复
https://www.cnblogs.com/xinysu/p/6555082.html 说说 redo undo 都在干啥
Percona-xtrabackup 使用详解与原理的更多相关文章
- 线段树详解 (原理,实现与应用)(转载自:http://blog.csdn.net/zearot/article/details/48299459)
原文地址:http://blog.csdn.net/zearot/article/details/48299459(如有侵权,请联系博主,立即删除.) 线段树详解 By 岩之痕 目录: 一:综述 ...
- 丰富图文详解B-树原理,从此面试再也不慌
本文始发于个人公众号:TechFlow,原创不易,求个关注 本篇原计划在上周五发布,由于太过硬核所以才拖到了这周五.我相信大家应该能从标题当中体会到这个硬核. 周五的专题是大数据和分布式,我最初的打算 ...
- P2P技术详解(一):NAT详解——详细原理、P2P简介
1. IPv4协议和NAT的由来 今天,无数快乐的互联网用户在尽情享受Internet带来的乐趣.他们浏览新闻,搜索资料,下载软件,广交新朋,分享信息,甚至于足不出户获取一切日用所需.企业利用互联网发 ...
- ThreadLocal类详解:原理、源码、用法
以下是本文目录: 1.从数据库连接探究 ThreadLocal 2.剖析 ThreadLocal 源码 3. ThreadLocal 应用场景 4. 通过面试题理解 ThreadLocal 1.从数据 ...
- ThreadLocal用法详解和原理
一.用法 ThreadLocal用于保存某个线程共享变量:对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量. 1.Thr ...
- 详解Zookeeper原理与应用场景
Zookeeper 分布式协调服务 应用之处:发布.订阅,命名服务,分布式协调和分布式锁 对比 Chubby: Chubby 被定义为 分布式的锁服务 为分布式系统提供 松耦合.粗粒度 的分布式锁功能 ...
- ThreadLocal用法详解和原理(转)
本文转自https://www.cnblogs.com/coshaho/p/5127135.html 感谢作者 一.用法 ThreadLocal用于保存某个线程共享变量:对于同一个static Thr ...
- HTTP详解工作原理
1. HTTP简介 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议.它可以使浏览器更加高效,使网络传输减少. ...
- C++ new/delete详解及原理
学了冯诺依曼体系结构,我们知道: 硬件决定软件行为,数据都是围绕内存流动的. 可想而知,内存是多么重要.当然,我们这里说的内存是虚拟内存(详情看Linxu壹之型). 1.C/C++内存布局 2.C语言 ...
随机推荐
- centos7下安装docker(17.1docker监控---sysdig)
sysdig是一个轻量级的系统监控工具,同时原生支持容器.通过sysdig我们可以近距离观察linux操作系统和容器的行为 Linux上有很多常用的监控工具,比如;strace,tcpdump,hto ...
- 转://Linux Multipath多路径配置与使用案例
在Linux平台一部分存储产品使用操作系统自带的多路径软件,包括最常见的HP和IBM的部分存储产品,在Linux自带的多路径软件叫做multipath,这篇文章以HP EVA系列存储在Linux平台的 ...
- 无备份时用dbms_repair恢复坏块的方法
份的情况下可以直接使用备份来恢复. 对于通过备份恢复,Oracel为我们提供了很多种方式,冷备,基于用户管理方式,RMAN方式等等. 对于这几种方式我们需要实现基于数据库以及文件级别的恢复.RMAN同 ...
- Python分析微信好友性别比例和省份城市分布比例
如需转发请注明:小婷儿的博客:https://www.cnblogs.com/xxtalhr/p/10642241.html 一.安装模块 pip install itchat pip install ...
- mongo中游标
1.手动循环访问游标 mongo中我们常用的查询方式db.collection.find()方法其实返回的就是游标,只不过我们并未给返回的游标分配变量,我们所看到的的查询数据也就是游标自动迭代得出的( ...
- 【thinkPHP框架】Failed opening required 'header.php' include_path='.;c:\php5\pear 终级解决方案
ThinkPHP框架中的某一个php页面,想要去引入其他php页面,结果反复报错,无解. 各种百度,有说是文件权限不够的,也有说配置不对的,反正一个都没有解决这个问题,依然无解. 最终,找到了办法,似 ...
- vue项目使用echarts按需引入实现地图动态显示效果时,报错:TypeError: Cannot read property 'dataToPoint' of undefined
vue项目使用echarts按需引入实现地图动态显示效果时,报错:TypeError: Cannot read property 'dataToPoint' of undefined 借鉴了该大神的文 ...
- eclipse不能运行Struts2项目
刚接触Struts2项目,本想写个HelloWorld上手,谁知道光eclipse配置tomcat就鼓捣一晚上,查阅各种资料. 项目刚开始报错: "java.lang.ClassNotFou ...
- nodejs简单模仿web.net web api
最近用了asp.net web api + EF开发一个项目,但是移植到linux时遇到问题(mono只支持EF6.0,但是mysql驱动不支持EF6.0).所以决定换个思路,用nodejs实现res ...
- python代码风格指南:pep8 中文版
本文档所提供的编码规范,适用于主要的Python发行版中组成标准库的Python代码.请参阅PEP关于Python的C实现的C编码风格指南的描述. 本文档和PEP257(文档字符串规范)改编自Guid ...