备份是数据安全的最后一道防线。对于任何数据丢失的场景,备份虽然不一定能恢复到最新的数据(取决于备份周期),但至少可以将损失降低到***。衡量备份恢复的重要指标有两个:恢复点目标(RPO)和恢复时间目标(RTO)。前者侧重于能恢复多远,后者侧重于恢复需要多长时间。本文主要讨论MySQL备份方案,重点介绍几种备份方式的原理,包括文件系统快照(LVM)、逻辑备份工具Mysqldump、Mydumper、物理备份工具Xtrabackup,并将详细讲解几种方案的优缺点,以及可能出现的问题。冷备份最简单的备份方法是关闭MySQL服务器,然后将data目录下的所有文件复制保存。当需要恢复时,将该目录复制到要恢复的机器上。这种方法确实方便,但是在生产环境中基本没用。因为需要所有机器都提供服务,甚至Slave有时也需要提供只读服务,所以关闭MySQL停止备份是不现实的。与冷备份相对应的一个概念是热备份。所谓热备份就是在不影响MySQL对外服务的情况下进行备份。热备份是本文的重点。快照备份首先要介绍的热备份是快照备份,指的是通过文件系统支持的快照功能来备份数据库。备份的原理是将所有的数据库文件放在同一个分区中,然后对该分区进行快照工作。对于Linux,需要通过LVM(LogicalVolumeManager)来实现。LVM使用copy-on-write技术创建快照,比如某个时刻的整个卷的逻辑副本,类似于数据库中innodb存储引擎的MVCC,只不过LVM快照是文件系统级别的,而MVCC是数据库层面的,只支持innodb存储引擎。LVM有一个快照保留区。如果原始卷数据发生变化,LVM保证在写入任何更改之前将受影响的块复制到快照保留区。简单的说,所有在快照点开头一致的旧数据都保留在快照区中。对于不经常更新的数据库,快照也会非常小。对于MySQL,为了使用快照备份,需要将数据文件和日志文件放在一个逻辑卷中,然后用快照备份该卷。由于快照备份只能在本地进行,如果本地磁盘损坏,快照也会损坏。快照备份更倾向于防止误操作。它可以快速将数据库恢复到快照生成的时间点,然后结合二进制日志恢复到指定的时间点。基本原理如下图所示:逻辑备份、冷备份和快照备份由于各自的劣势在生产环境中很少使用,更多的是MySQL自带的逻辑备份和物理备份工具。本节主要讲逻辑备份。MySQL官方提供了Mysqldump这个逻辑备份工具虽然够好,但是存在单线程备份慢的问题。社区提供了一个比较优秀的逻辑备份工具mydumper,它的优势主要体现在多线程备份,备份速度更快。MysqldumpMysqldump用于备份。有两个关键参数不得不提一下:--single-transaction:在开始备份之前,执行starttransaction命令以获得一致的备份。该参数只对innodb存储引擎有效。--master-data=2:主要用来记录一致备份的位置。要理解Mysqldump的工作原理,必须区别对待事务表(innodb)和非事务表(如myisam),因为备份过程与此密切相关。而且,到目前为止,我们还无法避免myisam表,即使我们所有的业务表都是innodb,因为mysql库中的系统表仍然使用myisam表。备份的基本流程如下:1.调用FTWRL(flushtableswithreadlock),全局禁止读写2.开启快照读取获取此时的快照(仅对innodb表有效)3.备份非-innodb表数据(*.frm,*.myi,*.myd等)4.非innodb表备份完成后,释放FTWRL锁5.一张一张备份innodb表数据6.备份做完了。整个过程可以参考我同事的一张图,但是他的图只考虑了innodb表的备份。其实在执行unlocktables之前,已经备份了非innodb表,下面的t1,t2,t3本质上都是innodb表,5.6的mysqldump使用savepoint机制释放了mdllockon每备份一张表就备份一张表,避免长时间锁定一张表。你可能会有疑问,为什么在备份innodb表之前先释放锁呢?这其实是利用了innodb引擎的MVCC机制。启用快照读取后,可以得到当时一致的数据,无论需要备份多长时间,直到整个事务结束(commit)。MydumperMydumper的原理与Mysqldump的原理类似,最大的不同是引入了多线程备份,每个备份线程备份一部分表,当然并发粒度可以达到行级来实现多线程备份的目的。这里最后要解决的问题是如何保证备份的一致性。其实关键就在FTWRL。对于非innodb表,在释放锁之前需要备份表。对于InnoDB表,需要保证多个线程都能获取一致性点。这个动作也必须在持有全局锁的情况下完成,因为此时数据库没有读写,可以保证点的一致性。所以基本流程如下:与逻辑备份相比,物理备份(Xtrabackup)是通过查询来提取数据中的所有记录。物理备份比较直接,复制数据库文件和日志完成备份,所以速度会更快。当然,开源的Mydumper和官方流行的备份工具(5.7.11的mysqlpump)都支持多线程备份,速度差距可能会进一步缩小。至少从目前的生产环境来看,物理备份的使用还是比较多的。由于Xtrabackup支持备份innodb表,所以我们在实际生产环境中使用的工具是innobackupex,它是对xtrabackup的一层封装。innobackupex脚本用于备份非InnoDB表,同时调用xtrabackup命令备份InnoDB表。innobackupex的基本流程如下:1.启动redolog复制线程,从最新的checkpoint开始依次复制redolog;2.启动idb文件复制线程,复制innodb表的数据3.idb文件复制完成,调用FTWRL获取一致性点4.备份非innodb表(系统表)和frm文件5.由于没有此时有新的事务提交,等待redo日志复制完成后6.最新的redolog复制完成后,此时相当于innodb表和非innodb表的数据。7、获取binlog位置,此时数据库的状态是一致的。8.释放锁,备份结束。Xtrabackup的改进从前面介绍的逻辑备份和物理备份来看,无论是哪种备份工具,要想获得一致性点,都强烈依赖于FTWRL。这个锁是非常有杀伤力的,因为在持有锁期间,整个数据库本质上是无法对外提供写服务的。另外,由于FTWRL需要关表,如果有大查询,会导致FTWRL等待,导致DML阻塞时间变长。即使是备库,也有SQL线程从主库复制更新,在应用全局锁时,会造成主备库的延迟。从前面的分析来看,FTWRL的锁持有时间主要和非innodb表的数据量有关。如果非innodb表数据量大,备份慢,锁持有时间会很长。即使都是innodb表,也会因为mysql库系统表的存在,而被锁定一段时间。为了解决这个问题,Percona改进了Mysql的Server层,引入了BACKUPLOCK。具体使用“LOCKTABLESFORBACKUP”命令备份非innodb表数据;使用“LOCKBINLOGFORBACKUP”获取一致性位置,最大限度减少数据库备份对服务造成的损害。下面看看使用这两种锁和FTWRL的区别:LOCKTABLESFORBACKUP功能:备份数据1.禁止非innodb表更新2.禁止所有表ddl优化点:1.不会被大查询阻塞(closetable)2.非常重要的一点是innodb表的读取和更新不会被阻塞。对于所有业务表都是innodb的情况,在备份过程中DML是完全不会损坏的。UNLOCKTABLESLOCKBINLOGFORBACKUP功能:获取一致性点。一、站点更新禁止操作优化点:1、允许DDl和更新,直到binlog写完。UNLOCKBINLOG以上就是本文的全部内容,希望对大家的学习有所帮助。
