(转)MySQL备份原理详解
MySQL备份原理详解
原文:http://www.cnblogs.com/cchust/p/5452557.html
备份是数据安全的最后一道防线,对于任何数据丢失的场景,备份虽然不一定能恢复百分之百的数据(取决于备份周期),但至少能将损失降到最低。衡量备份恢复有两个重要的指标:恢复点目标(RPO)和恢复时间目标(RTO),前者重点关注能恢复到什么程度,而后者则重点关注恢复需要多长时间。这篇文章主要讨论MySQL的备份方案,重点介绍几种备份方式的原理,包括文件系统快照(LVM),逻辑备份工具Mysqldump,Mydumper,以及物理备份工具Xtrabackup,同时会详细讲解几种方案的优缺点,以及可能遇到的问题。
冷备份
最简单的备份方式就是,关闭MySQL服务器,然后将data目录下面的所有文件进行拷贝保存,需要恢复时,则将目录拷贝到需要恢复的机器即可。这种方式确实方便,但是在生产环境中基本没什么作用。因为所有的机器都是要提供服务的,即使是Slave有时候也需要提供只读服务,所以关闭MySQL停服备份是不现实的。与冷备份相对应的一个概念是热备份,所谓热备份是在不影响MySQL对外服务的情况下,进行备份,热备份是这篇文章讨论的重点。
快照备份
首先要介绍的热备份是快照备份,快照备份是指通过文件系统支持的快照功能对数据库进行备份。备份的原理是将所有的数据库文件放在同一分区中,然后对该分区执行快照工作,对于Linux而言,需要通过LVM(Logical Volumn Manager)来实现。LVM使用写时复制(copy-on-write)技术来创建快照,例如,对整个卷的某个瞬间的逻辑副本,类似于数据库中的innodb存储引擎的MVCC,只不过LVM的快照在文件系统层面,而MVCC在数据库层面,而且仅支持innodb存储引擎。LVM有一个快照预留区域,如果原始卷数据有变化时,LVM保证在任何变更写入之前,会复制受影响块到快照预留区域。简单来说,快照区域内保留了快照点开始时的一致的所有old数据。对于更新很少的数据库,快照也会非常小。对于MySQL而言,为了使用快照备份,需要将数据文件,日志文件都放在一个逻辑卷中,然后对该卷快照备份即可。由于快照备份,只能本地,因此,如果本地的磁盘损坏,则快照也就损坏了。快照备份更偏向于对误操作防范,可以将数据库迅速恢复到快照产生的时间点,然后结合二进制日志可以恢复到指定的时间点。基本原理如下图:
逻辑备份
冷备份和快照备份由于其弊端在生产环境中很少使用,使用更多是MySQL自带的逻辑备份和物理备份工具,这节主要讲逻辑备份,MySQL官方提供了Mysqldump逻辑备份工具,虽然已经足够好,但存在单线程备份慢的问题。在社区提供了更优秀的逻辑备份工具mydumper,它的优势主要体现在多线程备份,备份速度更快。
Mysqldump
Mysqldump用于备份,不得不提两个关键的参数:
--single-transaction:在开始备份前,执行start transaction命令,以此来获取一致性备份,该参数仅对innodb存储引擎有效。
--master-data=2:主要用于记录一致性备份的位点。
理解Mysqldump工作原理,一定要将事务表(innodb)和非事务表(比如myisam)区别对待,因为备份的流程与此息息相关。而且,到目前为止,我们也无法规避myisam表,即使我们的所有业务表都是innodb,因为mysql库中系统表仍然采用的myisam表。备份的基本流程如下:
1.调用FTWRL(flush tables with read lock),全局禁止读写
2.开启快照读,获取此时的快照(仅对innodb表起作用)
3.备份非innodb表数据(*.frm,*.myi,*.myd等)
4.非innodb表备份完毕后,释放FTWRL锁
5.逐一备份innodb表数据
6.备份完成。
整个过程,可以参考我同事的一张图,但他的这张图只考虑innodb表的备份情况,实际上在unlock tables执行完毕之前,非innodb表已经备份完毕,后面的t1,t2和t3实质都是innodb表,而且5.6的mysqldump利用保存点机制,每备份完一个表就将一个表上的MDL锁释放,避免对一张表锁更长的时间。这里可以参考我之前的blog:FLUSH TABLE WITH READ LOCK
大家可能有一个疑问,为啥备份innodb表之前,就已经将锁释放掉了,这实际上是利用了innodb引擎的MVCC机制,开启快照读后,就能获取那个时间的一致的数据,无论需要备份多长时间,直到整个事务结束(commit)为止。
Mydumper
Mydumper原理与Mysqldump原理类似,最大的区别是引入了多线程备份,每个备份线程备份一部分表,当然并发粒度可以到行级,达到多线程备份的目的。这里要解决最大一个问题是,如何保证备份的一致性,其实关键还是在于FTWRL。对于非innodb表,在释放锁之前,需要将表备份完成。对于innodb表,需要确保多个线程都能拿到一致性位点,这个动作同样要在持有全局锁期间完成,因为此时数据库没有读写,可以保证位点一致。所以基本流程如下:
物理备份(Xtrabackup)
相对于逻辑备份利用查询提取数据中的所有记录,物理备份更直接,拷贝数据库文件和日志来完成备份,因此速度会更快。当然,无论是开源的Mydumper还是官方最新的备份工具(5.7.11的mysqlpump)都支持了多线程备份,所以速度差异可能会进一步缩小,至少从目前生产环境来看,物理备份使用还是比较多的。由于Xtrabackup支持备份innodb表,实际生产环境中我们使用的工具是innobackupex,它是对xtrabackup的一层封装。innobackupex 脚本用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表,innobackupex的基本流程如下:
1.开启redo日志拷贝线程,从最新的检查点开始顺序拷贝redo日志;
2.开启idb文件拷贝线程,拷贝innodb表的数据
3.idb文件拷贝结束,通知调用FTWRL,获取一致性位点
4.备份非innodb表(系统表)和frm文件
5.由于此时没有新事务提交,等待redo日志拷贝完成
6.最新的redo日志拷贝完成后,相当于此时的innodb表和非innodb表数据都是最新的
7.获取binlog位点,此时数据库的状态是一致的。
8.释放锁,备份结束。
Xtrabackup的改进
从前面介绍的逻辑备份和物理备份来看,无论是哪种备份工具,为了获取一致性位点,都强依赖于FTWRL。这个锁杀伤力非常大,因为持有锁的这段时间,整个数据库实质上不能对外提供写服务的。此外,由于FTWRL需要关闭表,如有大查询,会导致FTWRL等待,进而导致DML堵塞的时间变长。即使是备库,也有SQL线程在复制来源于主库的更新,上全局锁时,会导致主备库延迟。从前面的分析来看,FTWRL这把锁持有的时间主要与非innodb表的数据量有关,如果非innodb表数据量很大,备份很慢,那么持有锁的时间就会很长。即使全部是innodb表,也会因为有mysql库系统表存在,导致会锁一定的时间。为了解决这个问题,Percona公司对Mysql的Server层做了改进,引入了BACKUP LOCK,具体而言,通过"LOCK TABLES FOR BACKUP"命令来备份非innodb表数据;通过"LOCK BINLOG FOR BACKUP"来获取一致性位点,尽量减少因为数据库备份带来的服务受损。我们看看采用这两个锁与FTWRL的区别:
LOCK TABLES FOR BACKUP
作用:备份数据
1.禁止非innodb表更新
2.禁止所有表的ddl
优化点:
1.不会被大查询堵塞(关闭表)
2.不会堵塞innodb表的读取和更新,这点非常重要,对于业务表全部是innodb的情况,则备份过程中DML完全不受损
UNLOCK TABLES
LOCK BINLOG FOR BACKUP
作用:获取一致性位点。
1.禁止对位点更新的操作
优化点:
1.允许DDl和更新,直到写binlog为止。
UNLOCK BINLOG
参考文档
http://mysql.taobao.org/monthly/2016/03/07/
https://www.percona.com/blog/2014/03/11/introducing-backup-locks-percona-server-2/
http://www.wtoutiao.com/p/1cbstSx.html
http://www.wtoutiao.com/p/10cEnZ7.html
http://www.wtoutiao.com/p/125vVWi.html
http://www.wtoutiao.com/p/120AXSH.html
http://www.cnblogs.com/cchust/p/4603599.html
(转)MySQL备份原理详解的更多相关文章
- MySQL备份原理详解
备份是数据安全的最后一道防线,对于任何数据丢失的场景,备份虽然不一定能恢复百分之百的数据(取决于备份周期),但至少能将损失降到最低.衡量备份恢复有两个重要的指标:恢复点目标(RPO)和恢复时间目标(R ...
- mysql备份恢复详解
前言 为什么需要备份数据? 数据的备份类型 MySQL备份数据的方式 备份需要考虑的问题 设计合适的备份策略 实战演练 使用cp进行备份 使用mysqldump+复制BINARY LOG备份 使用lv ...
- Mysql主从复制原理详解
一.为什么要做主从同步 1.读写分离,降低对主数据库的IO消耗 2.避免数据丢失 3.提高业务系统性能 二.主从同步和集群的区别 1.主从同步 一般需要两台及以上数据库服务器即可(一台用于写入数据,一 ...
- MySQL备份参数详解
mysqldump 是采用SQL级别的备份机制,它将数据表导成 SQL 脚本文件,在不同的 MySQL 版本之间升级时相对比较合适,这也是最常用的备份方法. 1. --compatible = nam ...
- 二十二、mysql索引原理详解
背景 使用mysql最多的就是查询,我们迫切的希望mysql能查询的更快一些,我们经常用到的查询有: 按照id查询唯一一条记录 按照某些个字段查询对应的记录 查找某个范围的所有记录(between a ...
- mysql 复制原理详解
http://www.cnblogs.com/kristain/articles/4142970.html
- (4.13)mysql备份原理(转)
关键词:mysqldump原理,--single-transaction,mysql备份原理 转自:https://www.cnblogs.com/cchust/p/5452557.html MySQ ...
- mysql navcat备份使用详解
mysql navcat备份使用详解 点击备份 然后新建备份 然后选择要备份的表 就可以了 以后这个表删除了 内容变更了 都可以点击 还原备份就可以了
- Mysql加锁过程详解(5)-innodb 多版本并发控制原理详解
Mysql加锁过程详解(1)-基本知识 Mysql加锁过程详解(2)-关于mysql 幻读理解 Mysql加锁过程详解(3)-关于mysql 幻读理解 Mysql加锁过程详解(4)-select fo ...
随机推荐
- hdu-1207(规律推导)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1207 思路: 可以按照类似汉诺塔的推导形式来推导, 首先,有四个柱子,a,b,c,d. (1)a的x个 ...
- hdu-1143(简单dp)
题目链接: 思路:利用前一个状态找到本次状态需要的次数,就是递推. 建立一个二维数组dp[i][j] ,i表示行,j表示多余的格子. 可以分为三种状态dp[i][0], dp[i][1] ,dp[i] ...
- git分支删除
1.列出本地分支: git branch 2.删除本地分支: git branch -D BranchName 其中-D也可以是--delete,如: git branch --delete Bran ...
- C++之类和对象课后习题1
建立一个对象数组,内放5个学生的(学号,成绩),设立一个函数max,用指向对象的指针作函数参数,在max函数中找出5个学生的最高成绩者,并输出其学号. #include<iostream> ...
- jquery文件上传控件 WebUploader
WebUploader是百度开源的一个文件上传组件,因为其操作简洁大方,就在项目中使用了,记录一下. 效果是这样子: 这个样子是默认的效果. 这个是选择上传的图片,可以批量,选择后可以删除和添加更 ...
- day3之函数的初始及进阶
函数初始 函数的定义与调用 ''' def 函数名 (参数): 函数体 函数名:设定与变量相同 执行函数: 函数名() ''' 函数的返回值 # 函数返回值 return ''' 1.遇到return ...
- #include 和 #import 的区别, @class 的含义
#import 和 #include 会包含这个类的所有信息,包括实体变量和方法 而#include比起 #import的好处不会引起重复包含 @class是用来做类引用的 @class就是告诉编译 ...
- IDEA14添加SVN
今天升级IDEA14,发现SVN变了,折腾了好一会才搞好.记录一下,希望其他人能少走弯路.主要是IDEA14的svn是用命令行工具进行操作,这样对以后SVN的兼容性也会好很多,这个在他们官方的博客上也 ...
- Android-项目所有文件报红色j,状态栏无法Run 'app'
项目所有文件报红色j,不可用状态 状态栏如下: 无法 Run 'app' 无法 Debug 'app' ........... 以下操作按钮灰色的,无法点击: 解决方案: 只需要:Sync Proje ...
- 关于ListBox的几个问题
Winfrom ListBox绑定数据源list界面不更新问题与绑定数据源不可CRUD问题 场景:获取一个listbox的选中项添加到另一个listbox中 解决方案-1:不要直接绑定DataSour ...