MySQL之备份与恢复(七)

备份与恢复

文件系统快照

规划LVM备份

LVM快照备份也是有开销的。服务器写到原始卷的越多,引发的额外开销也越多。当服务器随机修改许多不同块时,磁头需要需要自写时复制空间来来回回寻址,并且将数据的老版本写到写时复制空间。从快照中读取也有开销,因为LVM需要从原始卷中读取大部分数据。只有快照创建后修改过的数据从写时复制空间读取;因此,逻辑顺序读取快照数据实际上也可能导致磁头来回移动。所以应该为此规划好快照。快照实际上会导致原始卷和快照都比正常的读/写性能要差------如果使用过多的写时复制空间,性能可能会差很多。这会降低MySQL服务器和复制文件进行备份的性能。我们做了基准测试,发现LVM快照的开销要远高于它本应该有的------我们发现性能最多可能会慢5倍,具体取决于负载和文件系统。再规划备份时要记得这一点。

规划中另外一个重要的事情是,为快照分配足够多的空间。我们一般采取下面的方法.

  • 1.记住,LVM只需要复制每个修改块到快照一次。MySQL写一个块到原始卷中时,它会复制这个块到快照中,然后对复制的块在例外表中生成一个标记。后续对这个块的写不会产生任何到快照的复制
  • 2.如果只使用InnoDB,要考虑InnoDB是如何写数据的。InnoDB实际需要对数据写两遍,至少一半的InnoDB的写IO会到双写缓冲区(doublewrite buffer)、日志文件,以及其他磁盘上相对小的区域中。这部分会多次重用相同的磁盘块,因此第一次时对快照有影响,但写过一次以后就不会对快照带来写压力
  • 3.接下来,相对于反复修改同样的数据,需要评估有多少IO需要写入到那些还没有复制到快照写时复制的空间的块中,对评估的结果要保留足够的余量
  • 4.使用vmstat或iostat来手机服务器每秒写多少块的统计信息
  • 5.衡量(或评估)复制备份到其他地方需要多久。换言之,需要在复制起见保持LVM快照打开多长时间。

假设评估出有一半的写会导致往快照的写时复制空间的写操作,并且服务器支持10MB/s的写入。如果需要一个小时(3600s)将快照复制到另外一个服务器上,那么将需要1/2 * 10MB * 3600 即18GB的快照空间。考虑到容错,还要增加一些额外的空间。有时候当快照打开时,很容易计算会有多少数据发生改变。让我们看个例子。BoardReader论坛搜索引擎每隔存储节点有1TB的InnoDB表。但是,我们知道最大的开销时加载心数据。每天新增近10GB的数据,因此50GB的快照空间应该完全足够。然而这样来评估不总是正确的。假设在某个时间点,有一个长时间运行的依次修改每个分片的ALTER TABLE操作,它会修改超过50GB的数据;在这个时间点,就不能做备份的操作。为了避免这样的问题,可以稍后再创建快照,因为创建快照后会导致一个负载的高峰。

备份误区2:"快照就是备份"

一个快照,不论是LVM快照、ZFS快照,还是SAN快照,都不是实际的备份,因为它不包含数据的完整副本。正因为快照是写时复制的,所以它只包含实际数据和快照发生的时间点的数据之间的差异数据。如果一个没有被修改的块在备份副本时被损坏,那就没有该块的正常副本可以用来恢复,并且备份副本时每隔快照看到的都是相同的损坏的块。可以使用快照来"冻结"备份时的数据,但不要把快照当作一个备份

快照的其他用途和替代方案

快照有更多的其他用途,而不仅仅用于备份。例如,之前提到,在一个有潜在危险的动作之前生成一个"检查点"会有帮助。有些系统允许将快照提升为原文件系统,这使得回滚到生成快照的时间点的数据非常简单。文件系统快照不是取得数据瞬间副本的唯一方法。另一个选择是RAID分裂;举个例子,如果有一个三磁盘的软RAID镜像,就可以从该RAID组中移出来一个磁盘单独加载。这样做没有写时复制的代价,并且需要时将此类"快照"提升为主副本的操作也很简单。不错,如果要将磁盘加回到RAID集合,就必须重新进行同步,当然,天下没有免费的午餐。

从备份中恢复

如何恢复数据取决于是怎么备份的。可能需要以下部分或全部步骤。

  • 1.停止MySQL服务器
  • 2.记录服务器的配置和文件权限
  • 3.将数据从备份中移到MySQL数据目录
  • 4.改变配置
  • 5.改变文件权限
  • 6.以限制访问模式重启服务器,等待完成启动
  • 7.载入逻辑备份文件
  • 8.检查和重放二进制日志
  • 9.检测已经还原的数据
  • 10.以完全权限重启服务器

如果有机会使用文件的当前版本,就不要用备份中的文件来代替。例如,如果备份包含二进制日志,并且需要重放这些日志来做基于时间点的恢复,那么不要把当前二进制日志用备份中的老的副本替代。如果有需要,可以将其重命名或移动到其他地方。

在恢复过程中,保证MySQL除了恢复进程外不接受其他访问,这一点往往比较重要。我们喜欢以--skip-networking和--socket=/tmp/mysql_recover.sock选项来启动MySQL.以确保它对于已经存在的应用不可访问,直到我们检测完并重新提供服务。这对于按块加载的逻辑备份的恢复来说尤其重要

恢复物理备份

恢复物理备份往往非常直接------换言之,没有太多的选项。这可能是好事,也可能是坏事,具体取决于恢复的需求。一般过程是简单地复制文件到正确位置。是否需要关闭MySQL取决于存储引擎。MyISAM的文件一般相互独立,即使服务器正在运行,简单地复制每个表的.frm .MYI和.MYD文件也可以正常操作。一旦有任何对此表的查询,或者其他会导致服务器访问此表的操作(例如,执行SHOW TABLES),MySQL都会立刻找到这些表。如果在复制这些文件时表是打开的,可能会有麻烦,因为此操作要么删除或重命名该表,要么使用LOCK TABLES和FLUSH TABLES来关闭它。InnoDB的情况有所不同。如果用传统的InnoDB的步骤来还原,即所有表都存储在单个表空间,就必须关闭MySQL,复制或移动文件到正确位置上,然后重启。同样也需要InnoDB的事务日志文件与表空间文件匹配。如果文件不匹配------例如,替换了表空间文件但没有替换事务日志文件------InnoDB将会拒绝启动。这也是将日志和数据文件一起备份非常关键的一个原因。入股哦使用InnoDB file-per-table特性(innodb_file_per_table),InnoDB会将每隔表的数据和索引存储于一个.ibd文件中,这就像MyISAM的.MYI和.MYD文件合在一起。可以在服务器运行时通过复制这些文件来备份和还原单个表,但这并不像MyISAM中那样简单。这些文件并不完全独立于InnoDB。每个.ibd文件都有一些内部的信息,保存着它与主(共享)表空间之前的关系。在还原这样的文件时,需要让InnoDB先"导入"这个文件。这个过程有许多的西安至,如果有需要可以阅读MySQL手册 中关于每个表使用独立表空间中的部分。最大的限制是只能在当初备份的服务器上还原单个表。用这种配置来备份和还原多个表不是不可能,但可能比想象得要更棘手。

所有这些复杂度意味着还原物理备份会非常乏味,并且容易出错。一个好的值得倡导的规则是,恢复过程越难越复杂,也就需要逻辑备份的保护。为了防止一些无法意料的情况或者某些无法使用物理备份的场景,准备好逻辑备份总是值得推荐的。

还原物理备份后启动MySQL

在启动正在恢复的MySQL服务器之前,还有些步骤要做,首先,最重要且最容易忘记的事情,是在启动MySQL服务器之前检查服务器的配置,确保恢复的文件有正确的归属和权限。这些属性必须完全正确,否则MySQL可能无法启动。这些属性因系统的不同而不同,因此要仔细检查是否和之前做的记录温和。一般都需要mysql用户和组拥有这些文件和目录,并且只有这个用户和组拥有可读/写权限。建议观察MySQL启动时的错误日志。在UNIX类系统上,可以如下观察文件。

bash 复制代码
tail -f /var/log/mysql/mysql.err

注意错误日志的准确位置会有所不同。一旦开始监测文件,就额可以启动MySQL服务器并监测错误。如果一切进展顺利,MySQL启动后就有一个恢复好的数据库服务器了。观察错误日志对于新的MySQL版本更为重要。老版本在InnoDB有错时不会启动,但新版本不管怎样都会启动,而只是让InnoDB失效。即使服务器看起来启动没有任何问题,也应该对每隔数据库运行SHOW TABLE STATUS来再次检测错误日志

相关推荐
师太,答应老衲吧1 分钟前
SQL实战训练之,力扣:2020. 无流量的帐户数(递归)
数据库·sql·leetcode
Yaml41 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~1 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616881 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
Channing Lewis1 小时前
salesforce case可以新建一个roll up 字段,统计出这个case下的email数量吗
数据库·salesforce
追风林1 小时前
mac 本地docker-mysql主从复制部署
mysql·macos·docker
aloha_7891 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~2 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
毕业设计制作和分享2 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis