高性能MySql学习笔记-第十五章:备份和恢复
1. 为什么要备份
- 灾难恢复。灾难恢复是下列场景下需要做的事情:硬件故障、一个不经意的BUG导致数据损坏、或者服务器及其数据由于某些原因不可获取或无法使用等。
- 人们改变想法。很多人经常会在删除数据后又想要恢复这些数据。
- 审计。
- 测试。一个基于实际数据来测试的方法是,定期用最新的生产环境数据更新测试服务器。
2. 定义恢复需求
- 规划备份和恢复策略时,有两个重要的需求可以帮助思考:恢复点目标(PRO)和恢复时间目标(RTO)。它们规定了可以容忍多少数据丢失,以及需要等待多久将数据恢复。
3. 设计MySQL备份方案
- 一些建议:
- 对于大数据库而言,物理备份是必需的。
- 保留多个备份集。
- 定期从逻辑备份(或者物理备份)中抽取数据进行恢复测试。
- 保存二进制日志以用于基于故障时间点的恢复。expire_logs_day参数应该设置得足够长,至少可以从最近两次物理备份中做基于时间点的恢复。
- 完全不借助备份工具本身来监控备份和备份的过程。需要另外验证备份是否正常。
- 通过演练整个恢复过程来测试备份和恢复。
在线备份还是离线备份
- 关闭MySQL做备份是最简单最安全的,也是所有获取一致性副本的方法中最好的,而且损坏或不一致的风险最小。但是这在实际应用中几乎不可能实现。
- 在规划备份时,一些与性能相关的因素需要考虑。其中最大的权衡是备份时间和备份负载。
- 锁时间。需要持有锁多长时间?
- 备份时间。复制备份到目的地需要多久?
- 备份负载。复制备份时对服务器性能的影响有多少?
- 恢复时间。把备份镜像从存储位置复制到MySQL服务器,重放二进制日志需要多久?
逻辑备份还是物理备份
-
有两种方法来备份MySQL数据:逻辑备份(也叫“导出”)和直接复制原始文件的物理备份。逻辑备份将数据包含在一种MySQL能够解析的格式中,要么是SQL,要么是以某个符号分隔的文本。原始文件是指存在硬盘上的文件。
-
逻辑备份的优点:
- 逻辑备份是可以用编辑器或像grep和sed之类的命令查看和操作的普通文件。当需要恢复数据或只想查看数据但不恢复时会比较有用。
- 恢复非常简单。
- 可以通过网络来备份和恢复。
- 可以在类似Amazon RDS这样不能访问底层文件系统的系统中使用。
- 非常灵活。可以接受许多选项,比如使用WHERE语句过滤。
- 与存储引擎无关。因为是从MySQL服务器中提取数据而生产,所以消除了底层数据存储和不同。
-
逻辑备份的缺点:
- 必须由数据库服务器完成生产逻辑备份的工作,因此需要使用更多的CPU周期。
- 无法保证导出后再还原出来的一定是同样的数据。浮点表示的问题,软件BUG等都可能导致问题,尽管非常少见。
- 从逻辑备份中还原需要MySQL加载和解释语句,转化为存储格式,并重建索引,这一切会非常慢。
-
物理备份的优点:
- 基于文件的物理备份,只需要将需要的文件复制到其他地方即可完成备份。
- 物理备份的恢复更加简单,但具体取决于存储引擎。
- InnoDB和MyISAM的物理备份非常容易跨平台、操作系统和MySQL版本。
- 从物理备份中恢复会更快,甚至可能比逻辑备份快一个数量级,因为MySQL服务器不需要执行任何SQL或构建索引。
-
物理备份的缺点
- InnoDB的原始文件通常比相应的逻辑备份要大得多。
- 物理备份不总是可以跨平台、操作系统或MySQL版本。文件名大小写敏感和浮点数格式可能会遇到麻烦。
-
建议混合使用物理和逻辑两种方式来做备份:先使用物理复制,以此数据启动MySQL服务器并运行mysqlcheck。然后周期性地使用mysqldump执行逻辑备份。
备份什么
- 除了备份的数据和表定义外,还应当备份
- 非显著数据,如二进制日志和InnoDB事务日志。
- 代码,如MySQL服务器中存储的触发器和存储过程等。
- 复制配置,如果恢复一个涉及复制关系的服务器,应该备份所有与复制相关的文件。
- 服务器配置。
- 选定的操作系统文件。
- 差异备份是指对自上次全备份后所有改变的部分所做的备份。增量备份是指自从任意类型的上次备份后所有修改做的备份。
存储引擎和一致性
- 数据一致性。需要考虑在备份时,数据是否在指定时间点一致。在数据库使用可重复读的事务级别,并使用InnoDB的多版本控制功能下,开启一个事务并转储一组相关的表,可以保证数据一致性。
- 文件一致性
- 复制。从备库中备份最大的好处是可以不干扰主库,避免在主库上增加额外的负载。当从备库备份时,应当保存所有关于复制进程的信息。
4. 管理和备份二进制日志
二进制日志格式
- 二进制日志包含了一系列的事件,每个事件都有一个固定长度的头。
- 第一行包含了日志文件内的字节偏移量。
- 第二行包含如下几项:事件的日期和时间。原服务器的服务器ID。end_log_pos,下一个事件的字节偏移值。事件类型,本例中的是Query。原服务器上执行事件的线程ID。原服务器上产生的错误代码。
- 后续的行包含重放时所需的数据。
5. 备份数据
生成逻辑备份
- SQL 导出
- 导出文件包含表结构和数据,均以有效的 SQL 命令形式写出。文件以设置 MySQL 各种选项的注释开始。
- 符号分割文件备份
- 可以使用 SQL 命令
SELECT INTO OUTFILE
以符号分割文件格式创建数据的逻辑备份。 - 比起SQL 导出文件,符号分割文件更紧凑且更易于用命令行工具操作,这种方法最大的优点是备份和还原速度更快。可以使用
LOAD DATA INFILE
命令加载数据到表中。
- 可以使用 SQL 命令
文件系统快照
- 文件系统快照是一种非常好的在线备份方法,支持快照的文件系统能够瞬间创建用来备份的内容一致的镜像。支持快照的文件系统和设备包括 FreeBSD 的文件系统、ZFS 文件系统、GNU/Linux 的逻辑卷管理(LVM),以及许多的 SAN 系统和文件存储解决方案。
- LVM 快照是如何工作的
- LVM 使用写时复制(copy-on-write)的技术来创建快照——例如,对整个卷的某个瞬间的逻辑副本。相比复制数据到快照中,LVM 只是简单标记创建快照的时间点,然后对该快照请求读数据时,实际上是从原始卷中读取的。因此,初始的复制基本上是一个瞬时就能完成的操作,不管创建快照的卷有多大。
- 当原始卷中某些数据有变化时,LVM 在任何变更写入之前,会复制受影响的块到快照预留的区域中。
- 先决条件和配置。创建一个快照的消耗几乎微不足道,但还是需要确保系统配置可以在获取快照备份瞬间的所有需要的文件的一致性副本。 确保系统满足以下条件:
- 所有的 InnoDB 文件(InnoDB 的表空间文件和 InnoDB 的事务日志)必须是在单个逻辑卷(分区)。LVM 不能为多于一个卷做某个时间点一致的快照。
- 如果需要备份表定义,MySQL 数据目录必须在相同的逻辑卷中。
- 必须在卷组中有足够的空闲空间来创建快照。
- 创建、挂载和删除 LVM 快照
- 如下命令是为 /dev/vg/mysql 卷创建一个有16GB 写时复制空间,名为 backup_mysql 的快照:
lvcreate --size --snapshot --name back_mysql /dev/vg/mysql
。 - 快照可以和其他文件系统一样进行挂载
- 卸载快照并用 lvremove命令将其删除:
- 如下命令是为 /dev/vg/mysql 卷创建一个有16GB 写时复制空间,名为 backup_mysql 的快照:
unmount /tmp/backup
rmdir /tmp/backup
lvremove --force /dev/vg/back_mysql
-
用于在线备份的 LVM 快照
- 连接 MySQL 服务器并使用一个全局读锁将表刷到磁盘上,然后获取二进制日志的位置:
FLUSH TABLES WITH READ LOCK; SHOW MASTER STATUS;
。记录 SHOW MASTER STATUS 的输出,确保到 MySQL 的连接处于打开状态,以使读锁不被释放。然后获取 LVM 的快照并立刻释放读锁,如使用UNLOCK TABLES
命令或者直接关闭链接。最后,加载快照并复制文件到备份位置。 - 当链接等待全局读锁时,所有的查询都将被阻塞,并且不可预测这会持续多久。
- 连接 MySQL 服务器并使用一个全局读锁将表刷到磁盘上,然后获取二进制日志的位置:
-
使用 LVM 快照无锁 InnoDB 备份
- 无锁备份只有一点不同,不需要执行
FLUSH TABLES WITH READ LOCK
。如果只使用 InnoDB,这没什么太大问题。 - 如果你认为 MySQL 系统表可能会变更,那么可以锁住并刷新这些表,一般不会对这些表有长时间运行的查询,所以通常很快。
- 无锁备份只有一点不同,不需要执行
-
规划 LVM备份
- LVM 快照备份也是有开销的。服务器写到原始卷的越多,引发的额外开销也越多。从快照中读取也有开销,因为 LVM 需要从原始卷中读取大部分数据,只有快照创建后修改过的数据从写时复制空间读取。因此,逻辑顺序读取快照数据实际上也可能导致磁头来回移动。
- 规划中的另一个事情是为快照分配足够多的空间。
6. 从备份中恢复
恢复物理备份
- 恢复物理备份的过程一般是简单地复制文件到正确位置。
- 恢复 InnoDB 时,需要保证 InnoDB 的事务日志文件和表空间文件匹配,否则 InnoDB 将拒绝启动。
- 还原物理备份后启动 MySQL 服务器之前,需要检查服务器的配置,确保恢复的文件有正确的归属和权限,这些属性必须完全正确。
还原逻辑备份
- 服务器加载一个巨大的导出文件的代价非常高,并且写二进制日志会增加更多的开销。加载巨大的文件对于一些存储引擎影响。例如在单个事务中加载100GB 数据到 InnoDB 可能产生巨大的回滚段导致问题。
基于时间点的恢复
- 对 MySQL做基于时间点的恢复常见的方法是还原最近一次全备份,然后从那个时间点开始重放二进制日志。只要有二进制日志,就可以恢复到任何希望的时间点。
更高级的恢复技术
- 用于快速恢复的延时复制。如果有一个延时的备库,并且在问题备库执行问题语句之前就发现问题,则可以通过重放事件但是跳过问题语句的方式进行恢复。
- 使用日志服务器进行恢复。使用日志服务器也是一种使用复制做恢复的方法。
InnoDB 崩溃恢复
- InnoDB 损坏的原因
- InnoDB 非常健壮且可靠,并且有许多内建安全检测来防止、检查和修复损坏的数据——比其他 MySQL 存储引擎要强很多。
- InnoDB 依赖于无缓冲的 IO 调用和 fsync()调用,直到数据完全地写入到物理介质上才会返回。如果硬件不能保证写入的持久化,InnoDB 也就不能保证数据的持久,崩溃就有可能导致数据损坏。
- 如何恢复损坏的 InnoDB 数据
- InnoDB 损坏有三种主要类型,它们对数据恢复有着不同程度的要求。
- 二级索引损坏。一般可以用
OPTIMIZE TABLE
来修复损坏的二级索引。此外也可以使用逻辑备份的方式重建数据。这些过程都是通过构建一个新表重建受影响的索引。 - 聚簇索引损坏。如果是聚簇索引损坏,也许只能使用 innodb_force_recovery 选项来导出表。
- 损坏系统结构。系统结构保留 InnoDB 事务日志、表空间的撤销日志(undo log)区域和数据字典。这种损坏可能需要做整个数据库的导出和还原,因为 InnoDB 内部绝大部分工作都可能受影响。
7. 备份和恢复工具
- MySQL Enterprise Backup。MySQL 官方的备份工具,此工具备份时不需要停止 MySQL,也不需要设置锁或中断正常的数据库活动。
- Percona XtraBackup。和MySQL Enterprise Backup类似的开源且免费的工具。
- mylvmbackup。通过 LVM 帮助 MySQL 自动备份。
- Zmanda Recovery Manager。
- mydumper。
- mysqldump。