备份与恢复
逻辑备份还是物理备份
物理备份
物理备份有如下好处:
- 1.基于文件的物理备份,只需要将需要的文件复制到其他地方即可完成备份。不需要其他额外的工作来生成原始文件。
- 2.物理备份的恢复可能就更简单了,这取决于存储引擎。对于MyISAM,只需要简单地复制文件到目的地即可。对于InnoDB则需要停止数据库,可能还要采取其他一些步骤
- 3.InnoDB和MyISAM的物理备份非常容易跨平台、操作系统和MySQL斑斑额(逻辑导出亦如此。这里特别指出这一点是为了消除大家的打新)
- 4.从物理备份中恢复会更快,因为MySQL服务器不需要执行任何SQL或构建索引。如果有很大的InnoDB表,无法完全缓存到内存中,则物理备份的恢复要快非常多------至少一个数量级。事实上,逻辑备份最可怕的地方就是不确定的还原事件
物理备份也有其缺点,比如:
- 1.InnoDB的原始文件通常要比相应的逻辑备份要大得多。InnoDB的表空间往往包含很多未使用的空间。还有很多空间被用来做存储数据意外的用途(插入缓冲,回滚段等)。
- 2.物理备份不总是可跨平台、操作系统及MySQL版本。文件名大小写敏感和浮点格式可能会遇到麻烦。很可能因浮点格式不同而不能移动文件到另一个系统(虽然主流处理器都使用IEEE浮点格式)
物理备份通常更加简单高效(值得一提的是物理备份会更容易出错;很难相Mysqldump一样简单)尽管如此,对于需要长期保留的备份,或者是满足法律合规要求的备份,尽量不要完全依赖物理备份。至少每隔一段时间还是需要做一次逻辑备份。
除非经过测试,不要假定备份(特别是物理备份)是正常的。对InnoDB来说,这意味着需要启动一个MySQL实例,执行InnoDB恢复操作,然后运行CHECK TABLES。也可以跳过这一操作,仅对文件运行innochecksum,但不建议这样做。对于MyISAM可以运行CHECK TABLES,或者使用mysqlcheck.然后,周期性地使用mysqldump执行逻辑备份。这样做可以获得两种方法的优点,不会使生产服务器在导出时有过度负担。如果能够方便地利用文件系统的快照,也可以生成一个快照,将该快照复制到另外一个服务器上并释放,然后测试原始文件,再执行逻辑备份呢
备份什么?
恢复的需求决定需要备份什么。最简单的策略是只备份数据和表定义,但这是一个最低的要求。在生产环境中恢复数据库一般需要更多的工作。下面是MySQL备份需要考虑的几点:
- 1.非显著数据
不要忘记哪些容易被忽略的数据:例如m二进制日志和InnoDB事务日志。 - 2.代码
现在的MySQL服务器可以存储许多代码,例如触发器和存储过程。如果备份了mysql数据库,那么大部分这类代码也备份了,但入股哦需要还原单个业务数据库会比较麻烦,因为这个数据库中的部分"数据",例如存储过程,实际是存放在mysql数据库中的 - 3.复制配置
如果恢复一个涉及复制关系的服务器,应该备份所有与复制相关的文件,例如二进制日志、中继日志、日志索引文件和.info文件。至少应该包含SHOW MASTER STATUS和/或SHOW SLAVE STATUS的输出。执行FLUSH LOGS也非常有好处,可以让MySQL从一个新的二进制日志开始。从日志文件的开头做基于故障时间点的恢复要比从中间更容易 - 4.服务器配置
假设要从一个实际的灾难中恢复,比如说,地震过后在一个新数据中心构建服务器,如果备份中包含服务器配置,你一定会喜出望外 - 5.选定的操作系统文件
对于服务器配置来说,备份中对生产服务器至关重要的任何外部配置,都十分重要。在UNIX服务器上,这可能包括cron任务、用户和组的配置、管理脚本,以及sudo规则
这些建议在许多场景下会被当作"备份一切"。然而,如果有大量的数据,这样做的开销将非常高,如何做备份,需要更加明智的考虑。特别是,可能需要在不同备份中备份不同的数据。例如,可以单独地备份数据、二进制日志和操作系统及系统配置
增量备份和差异备份
当数据量很庞大时,一个常见的策略时做定期的增量或差异备份。它们之间的区别有点容易让人混淆,所以先来澄清这两个术语:差异备份是对自上次全备份后所有改变的部分而做的备份,而增量备份则是自从任意类型的上次备份后所有修改做的备份。
例如,加入在每周日做一个全备份。在周一,在自周日以来所有的改变做一个差异备份。在周二,就有两个选择:备份自周日以来所有的改变(差异),或只备份自从周一备份后所有的改变(增量)。增量和差异备份都是部分备份:它们一般不包含完整的数据集,因为某些数据几乎肯定没有改变。部分备份对减少服务器开销、备份时间及备份空间而言都很适合。尽管某些部分备份并不会真正减少服务器的开胸啊。例如,Percona XtraBackup和MySQL Enterprise Backup,仍然会扫描服务器上的所有数据块,因而并不会节约太多的开销,但它们确实会减少一定量的备份时间和大量用于压缩的CPU时间,当然也会减少磁盘空间使用(Percona XtraBackup正在开发"真正的"增量备份特性。它能够将备份变更的块,而需要扫描每个块)。不会因为会用高级备份技术而字符,解决方案越复杂,可能面临的风险也越大。要注意分析隐藏的危险,如果多次迭代备份紧密地耦合在一起,则只要其中的一次迭代备份有损坏,就可能会导致所有的备份都无效。下面有一些建议:
- 1.使用Percona XtraBackup和MySQL Enterprise Backup中的增量备份特性
- 2.备份二进制日志。可以在每次备份后使用FLUSH LOGS来开始一个新的二进制日志,这样就只需要备份新的二进制日志。
- 3.不要备份没有改变的表。有些存储引擎,例如MyISAM,会记录每个表最后修改时间。可以通过查看磁盘上的文件或运行SHOW TABLE STATUS来看这个时间。如果使用InnoDB,可以利用触发器记录修改时间到一个小的"最后修改时间"表中,帮助跟踪最新的修改操作。需要确保只对变更不频繁的表进行跟踪,这样才能降低开销。通过定制的备份脚本可以轻松获取到哪些表有变更。例如,如果有包含不同语种各个月的名称列表,或者州或区域的间歇之类的"查找"表,将它们放在一个单独的数据库中是个好主意,这样就不需要每次都备份这些表
- 4.不要备份没有改变的行,如果一个表只做插入,例如记录网页页面点击的表,那么可以增加一个时间戳的列,然后只备份自上次备份后插入的行
- 5.某些数据根本不需要备份。有时候这样做影响会很大------例如,如果有一个从其他数据构建的数据仓库,从技术上讲完全是冗余的,就可以仅备份构建仓库的数据,而不是数据仓库本身。即使从源数据文件重建仓库的"恢复"时间较长,这也是个好想法。相对于从全备中可能获得的快速恢复时间,避免备份可以节约更多的总的时间开胸啊。临时数据也可以不用备份,例如保留网站会话数据的表
- 6.备份所有的数据,然后发送到一个有去重特性的目的地,例如ZFS文件管理程序
增量备份的缺点包括增加恢复复杂性,额外的风险,以及更长的恢复时间。如果可以做全备,考虑到简便性,建议尽量做全备。不管如何,还是需要经常做全备份------建议至少一周一次。你肯定不会希望使用一个月的所有增量备份来进行恢复。即使一周也还是有很多的工作和风险的
存储引擎和一致性
MySQL对存储引擎的选择会导致备份明显更复杂。问题是,对于给定的存储引擎,如何得到一致的备份。实际上有两类一致性需要考虑:数据一致性和文件一致性。
- 1.数据一致性
当备份时,应该考虑是否需要数据在指定时间点一致。例如,在一个电子商务数据库中,可能需要确保发货单和付款之间一致。恢复付款时如果不考虑相应的发货单,或反过来,都会导致麻烦。如果做在线备份(从一个运行的服务器做备份),可能需要所有相关表的一致性备份。这意味着不能一次锁住一张表然后做备份------因而意味着备份可能比预想的要更有侵入性。如果使用的不是事务型存储引擎,则只能在备份时用LOCK TABLES来锁住所有要一起备份的表,备份完成后再释放锁。
InnoDB的多版本控制功能可以帮到我们。开始一个事务,转储一组相关的表,然后提交事务。(如果使用了事务获取一致性备份,则不能用LOCK TABLES,因为它会隐式地提交事务------详情参见MySQL手册)。只要在服务器上使用REPEATABLE READ事务隔离级别,并且没有任何DDL,就一定会有完美的一致性,以及基于时间点的数据快照,且在备份过程中不会阻塞任何后续的工作。尽管如此,这种方法并不能保护逻辑设计很差的应用。假如在电子商务库中插入一条付款记录,提交事务,然后在另外一个事务中插入一条发货单记录。备份过程可能在这两个操作之间开始,备份了付款记录却不包括发货单记录。这就是必需仔细设计事务以确保相关的操作放在一个组内的原因。也可以用mysqldump来获得InnoDB表的一致性逻辑备份,采用--single-transaction选项可以按照我们所描述的那样工作。但是,这可能会导致一个非常长的事务,在某些负载下会导致开销大到不可接受 - 2.文件一致性
每个文件内部的一致性也非常重要------例如,一条大的UPDATE语句执行时备份反映不出文件的状态------并且所有要备份的文件相互间也应一致。如果没有内部一致的文件,还原时可能会感到惊讶(它们可能已经损坏)。如果是在不同的时间复制相关的文件,它们彼此可能也不一致。MyISAM的.MYD和.MYI文件就是个例子。InnoDB如果检测到不一致或损坏,会记录错误日志乃至让服务器崩溃。对于非事务型存储引擎,例如MyISAM,可能的选项是锁住并刷新表。这意味着要么用LOCK TABLES和FLUSH TABLES结合的方法以使服务器将内存中的变更刷到磁盘上,要么用FLUSH TABLES WITH READ LOCK.一旦刷新完成,就可以安全地复制MyISAM的原始文件。对于InnoDB,确保文件在磁盘上一致更困难,即使使用FLUSH TABLES WITH READ LOCK,InnoDB依旧在后台运行:插入缓存、日志和写线程继续将变更合并到日志和表空间文件中。这些线程设计上是异步的------在后台执行这些工作可以帮助InnoDB取得更高的并发性------正因为如此它们与LOCK TABLES无关。因此,不仅需要确保每个文件内部是一致的,还需要同时复制同一个时间点的日志和表空间文件。如果在备份时有其他线程在修改文件,或在与表空间文件不同的时间点备份日志文件,会在恢复后再次因系统损坏而告终。可以通过下面几个方法规避这个问题。
1.等待直到InnoDB的清除线程和插入缓冲合并线程完成。可以观察SHOW INNODB STATUS的输出,当没有脏缓存或挂起的写时,就可以复制文件。尽管如此,这种方法可能需要很长一段时间;因为InnoDB的后台线程涉及太多的干扰而不太安全。所以我们不推荐这种方法
2.在一个类似LVM的系统中获取数据和日志文件一致的快照,必须让数据和日志文件一致的快照,必须让数据和日志文件在快照时相互一致;单独取它们的快照是没有意义的,
3.发送一个STOP信号给MySQL,做备份,然后再发送一个CONT信号来再次唤醒MySQL。看起来像是一个很少推荐的方法,但如果另外一种方法是在备份过程中需要关闭服务器,则这种方法值得考虑。至少这种技术不需要在重启服务器后预热。
在复制数据文件到其他地方后,就可以释放锁以使MySQL服务器再次正常运行