当前位置: 首页 > news >正文

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-7.fc29.x86_64.rpm
rpm -ivh percona-xtrabackup-24-2.4.12-1.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个工具进程的

  1. innobackupex 在启动 xtrabackup 进程后,会一直等 xtrabackup 备份完 InnoDB 文件,方式就是等待 xtrabackup_suspended_2 这个文件被创建出来;
  2. xtrabackup 在备完 InnoDB 数据后,就在指定目录下创建出这个文件,然后等这个文件被 innobackupex 删除;
  3. innobackupex 检测到文件 xtrabackup_suspended_2 被创建出来后,就继续往下走;
  4. innobackupex 在备份完非 InnoDB 表后,删除 xtrabackup_suspended_2 这个文件,这样就通知 xtrabackup 可以继续了,然后等 xtrabackup_log_copied 被创建;
  5. 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 之前的版本,都是通过对文件的生成的监控来控制整个备份流程的。

  

 

  1. innobackupex 在启动后,会先 fork 一个进程,启动 xtrabackup进程,然后就等待 xtrabackup 备份完 ibd 数据文件;
  2. xtrabackup 在备份 InnoDB 相关数据时,是有2种线程的,1种是 redo 拷贝线程,负责拷贝 redo 文件,1种是 ibd 拷贝线程,负责拷贝 ibd 文件;redo 拷贝线程只有一个,在 ibd 拷贝线程之前启动,在 ibd 线程结束后结束。xtrabackup 进程开始执行后,先启动 redo 拷贝线程,从最新的 checkpoint 点开始顺序拷贝 redo 日志;然后再启动 ibd 数据拷贝线程,在 xtrabackup 拷贝 ibd 过程中,innobackupex 进程一直处于等待状态(等待文件被创建)。
  3. xtrabackup 拷贝完成idb后,通知 innobackupex(通过创建文件),同时自己进入等待(redo 线程仍然继续拷贝);
  4. innobackupex 收到 xtrabackup 通知后,执行FLUSH TABLES WITH READ LOCK (FTWRL),取得一致性位点,然后开始备份非 InnoDB 文件(包括 frm、MYD、MYI、CSV、opt、par等)。拷贝非 InnoDB 文件过程中,因为数据库处于全局只读状态,如果在业务的主库备份的话,要特别小心,非 InnoDB 表(主要是MyISAM)比较多的话整库只读时间就会比较长,这个影响一定要评估到。
  5. 当 innobackupex 拷贝完所有非 InnoDB 表文件后,通知 xtrabackup(通过删文件) ,同时自己进入等待(等待另一个文件被创建);
  6. xtrabackup 收到 innobackupex 备份完非 InnoDB 通知后,就停止 redo 拷贝线程,然后通知 innobackupexredo log 拷贝完成(通过创建文件);
  7. innobackupex 收到 redo 备份完成通知后,就开始解锁,执行 UNLOCK TABLES
  8. 最后 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 否则不会创建文件夹打包,会直接放在这个目录下面。不太适合定期全备。

如此简单 一次全备就完成了

 

需要恢复的话也很简单,要恢复数据首先得对之前的全备做一次 prepare 原因我引用官方文档给出的理由。

Data files are not point-in-time consistent until they’ve been prepared, because they were copied at different times as the program ran, and they might have been changed while this was happening. If you try to start InnoDB with these data files, it will detect corruption and crash itself to prevent you from running on damaged data. The xtrabackup --prepare step makes the files perfectly consistent at a single instant in time, so you can run InnoDB on them.

可以看到在一致性位点未统一的时候启动 MySQL 是会 crash 的。我们通过 redo 和 undo 日志将数据库统一恢复到一致性位点位置。

innobackupex --apply-log /data/backup/backup

之后我们执行

移除datadir:
$ mv /data/mysql_data /data/mysql_data.bk
 
恢复数据
$ innobackupex --copy-back /data/backup/backup/
 
修改新datadir的权限
$ chown mysql:mysql -R /data/mysql_data

就可以将我们备份的数据恢复了。

上面操作执行完成之后,需要重启数据库。

增量恢复比较麻烦,之后我会来补充上,但是原理其实都差不多!

 

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 都在干啥

 

相关文章:

  • 大数据——基础概念
  • 用户数量高达3人的分布式系统
  • 多研究些架构,少谈些框架——一名阿里架构师的笔记
  • 深入浅出Node.js
  • unix下命令窗分屏工具
  • linux防火墙操作随笔记录
  • CF1060E Sergey and Subway(点分治)
  • CentOS 7更改yum源与更新系统
  • Python基本数据类型集合、格式化、函数
  • 印章与合同管理一体化:杜绝实体印章与纸质合同隐患
  • 微软正式发布Azure Functions 2.0
  • 微信小程序所带来的机会
  • CLTPHP5.0发布
  • 支付宝小程序
  • 23、【支付模块开发】——Java对接支付宝步骤(沙箱环境)
  • CSS相对定位
  • Debian下无root权限使用Python访问Oracle
  • extjs4学习之配置
  • ReactNativeweexDeviceOne对比
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • text-decoration与color属性
  • Zepto.js源码学习之二
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 工作手记之html2canvas使用概述
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 京东美团研发面经
  • 前端之React实战:创建跨平台的项目架构
  • 少走弯路,给Java 1~5 年程序员的建议
  • 我感觉这是史上最牛的防sql注入方法类
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 智能网联汽车信息安全
  • 《天龙八部3D》Unity技术方案揭秘
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW
  • (ros//EnvironmentVariables)ros环境变量
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (二十四)Flask之flask-session组件
  • (附源码)python房屋租赁管理系统 毕业设计 745613
  • (附源码)ssm码农论坛 毕业设计 231126
  • (经验分享)作为一名普通本科计算机专业学生,我大学四年到底走了多少弯路
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (十三)Maven插件解析运行机制
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .Net 6.0 处理跨域的方式
  • .net framework4与其client profile版本的区别
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .Net 中Partitioner static与dynamic的性能对比
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)
  • .netcore如何运行环境安装到Linux服务器
  • .net遍历html中全部的中文,ASP.NET中遍历页面的所有button控件
  • ??javascript里的变量问题
  • @ModelAttribute注解使用
  • []C/C++读取串口接收到的数据程序
  • [1]-基于图搜索的路径规划基础