我们不打算包括的话题:
安全(访问备份,恢复数据的权限,文件是否需要加密)
备份存储在哪里,包括他们应该离源数据多远,以及如何将数据从源头移动到目的地
保留策略、审计、法律要求,以及相应的条款
存储解决方案和介质,压缩,以及增量备份
存储的格式
对备份的监控和报告
存储层内置备份功能,或者其他专用设备,例如预制式文件服务器
还原意味着从备份文件中获取数据,可以加载这些文件到MySQL里,也可以将这些文件放置到MySQL期望的路径中。恢复一般意味着当某些异常发生后对一个系统或者其部分的拯救,包括从备份中还原数据,以及使服务器完恢复功能的所有必要操作,例如重启MySQL、改变配置和预热服务器的缓存等。
存储引擎的奔溃恢复要求数据和日志文件一致。要确保数据文件中只包含已经提交的事务所做的修改,恢复操作会将日志中还没有应用到数据文件的食物重新执行。
为什么要备份
灾难恢复:硬件故障、一个不经意的Bug导致数据损坏,或者服务器及其数据由于某些原因不可获取或无法使用等。
人们改变想法:删除某些数据和又想要恢复这些数据
审计: 数据快照,过去某个时间点的数据状态
测试:取数据到测试环境做测试使用
定义恢复需求
不仅仅要有备份系统,还要有一个强大的恢复系统。
规划恢复策略时,有两个重要的需求可以帮助思考:恢复点目标(PRO)和恢复时间目标(RTO)。他们定义了可以容忍丢失多少数据,以及需要等待多久将数据恢复。
在定义RPO和RTO是,先尝试回答下面几类问题:
- 在不导致严重后果的情况下,可以容忍丢失多少数据?需要故障恢复,还是可以接受自从上次日常备份后所有的工作全部丢失?是否有法律法规的要求?
- 恢复需要在多长时间内完成?哪种类型的宕机是可以接受的?哪些影响(例如,部分服务不可用)是应用和用户可以接受的?当那些场景发生时,又该如何持续服务?
- 需要恢复什么?常见的需求是恢复整个服务器,单个数据库,单个表,或仅仅是特定的事务或语句
复制!=备份: 例如Drop table后需要恢复,复制就恢复不了,需要靠备份才能恢复,当然延迟复制有可能的。
设计MySQL备份方案
细节之前的建议:
- 在生产实践中,大数据库来说,物理备份是必须的:逻辑备份太慢并且受资源限制,逻辑备份中恢复需要很长时间。基于快照的备份,例如Perconna XtraBackup和MySQL Enterprise Backup是最好的选择。
- 保留多个备份集
- 定期从逻辑备份(或者物理备份)中抽取数据进行恢复测试
- 保存二进制日志以用于基于故障时间点的恢复。expire_logs_days应该设置的足够长.至少大于全量备份的间隔时间。
- 完不借助备份工具本身来监控备份和备份的过程。需要另外验证备份是否正常。
- 通过演练整个恢复过程来测试备份和恢复。测算恢复所需要的资源(CPU、磁盘空间、实际时间,以及网络带宽等)
- 对安全性要仔细考虑。
在线备份还是离线备份
规划备份是,有一些与性能相关的因素需要考虑:
- 锁时间:需要持有锁多长时间,例如备份期间持有的全局FLUSH TABLES WITH READ LOCK?
- 备份时间: 复制备份到目的地需要多久
- 备份负载:在复制备份到目的地时对服务器性能的影响有多少
- 恢复时间:把备份镜像从存储位置复制到MySQL服务器,重放二进制日志需要多久?
最大的权衡是备份时间与备份负载。提高备份的优先级,代价是降低服务器性能。
逻辑备份还是物理备份
逻辑备份(也叫"导出")和直接复制原始文件的物理备份。
逻辑备份有如下的优点:
- 逻辑备份可以使用编辑器或grep和sed之类的命令查看和操作的普通文件。
- 恢复非常简单。直接导入。
- 可以通过网络来备份和恢复
- 可以在类似Amazon RDS这样不能访问底层文件系统中使用
- 非常灵活,因为mysqldump大部分人喜欢的工具.
- 与存储引擎无关
- 有助于避免数据损坏,物理备份可能磁盘损坏
逻辑备份的缺点:
- 必须由数据库服务器完成生成逻辑备份的工作,因此要使用更多的cpu周期
- 逻辑备份在某些场景下笔数据库文件本身更大
- 无法保证到处后再还原出俩的一定是同样的数据
- 从逻辑备份中还原需要MySQL加载和解释语句,转化为存储格式,并重建索引,所有这一切会很慢
最大的缺点是恢复,测试恢复所需要的时间将非常重要.
物理备份有如下好处:
- 基于文件的物理备份,只需要将需要的文件复制到其他地方即可完成备份。不需要其他额外的工作来生成原始文件
- 恢复更简单,取决于存储引擎。对于MyISAM复制到目的地即可。InnoDB需要停止数据库服务采取其他的步骤
- InnoDB和MyISAM的物理备份非常容易跨平台、操作系统和MySQL版本
- 从屋里备份中恢复会更快,因为不需要执行任何SQL或构建索引
事实上,逻辑备份最可怕的地方就是不确定的还原时间。
物理备份的缺点:
- InnoDB的原始文件通常比相应的逻辑备份要大的多。InnoDB的表空间包含很多未使用的空间。还有很多空间被用来做存储数据意外的用途(插入缓冲、回滚段等)
- 物理备份不总是可以跨平台、操作系统以及MySQL版本。文件名大小写敏感和浮点格式是可能会遇到的麻烦。很可能因浮点格式不同而不能移动文件到另一个系统
备份什么
恢复的需求决定需要备份什么,最简单的测率是指备份数据和表定义
下面是MySQL备份需要考虑的几点:
- 非显著数据: 容易被忽略的数据,例如二进制日志和InnoDB事务日志
- 代码 : 触发器和存储过程
- 复制配置: 有复制关系的。二进制日志、中继日志、日志索引文件和info文件
- 服务器配置: 配置文件
- 选定的操作系统文件管理脚本等
郑亮备份和差异备份:
差异备份是对自上次全备份后所有改变的部分而做的备份,而增量备份则是自从任意类型的上次备份后所有修改做的备份
下面是一些建议:
- 使用Percona XtraBackup和MySQL Enterprise Backup中的增量备份特性
- 备份二进制日志。
- 不要备份没有改变的表。
- 不要备份没有改变的行
- 某些数据根本不需要备份
- 备份所有的数据,然后发送到一个有去重特性的目的地。
增量备份的缺点包括增加恢复复杂性,额外的风险,以及更长的恢复时间。如果可全备,考虑到简便性,我们建议尽量做全备。
存储引擎和一致性
数据一致性:只要服务器上使用REPEATABLE READ事务隔离级别,并且没有任何DDL,就一定会有完美的一致性,以及基于时间点的数据快照,且在备份过程中不会阻塞任何后续的工作。
文件一致性:如果是MyISAM,可能是锁住并刷新表。
复制:从悲苦中备份最大的好处是可以不干扰主库,避免在主库上增加额外的负载。
管理和备份二进制日志
服务器的二进制日志是备份的最重要因素之一。
MySQL 5.6版本的mysqlbinlog有一个非常方便的特性,可以连接到服务器上来实时对二进制日志做镜像。
二进制日志格式: 使用mysqlbinlog工具查看二进制日志的内容。时间的日志和时间、原服务器的服务器ID,end_log_pos,下一个时间的偏移字节值、时间类型,元服务器上执行时间的线程ID,对于审计和执行CONNECTION_ID()函数很重要。 exec_time,在原服务器上时间产生的错误代码。
如果使用的是MySQL5.1中基于行的日志,事件将不再是SQL。而是可读性较差的由语句对表所做变更的”镜像“。
安全清理二进制日志:expire_log_days 变量来告诉MySQL定期清理日志。这个变量是MySQL 4.1才引入。之前都是rm mysql-bin.[0-9]*直接删除
在新版本中不要这样做,用rm删除日志会导致mysql-bin.index转台文件与磁盘上的文件不一致,有些语句,例如show master logs可能会受到影响而悄然失败,手动修改mysql-bin.index文件也不会修复这个问题
应该iyong雷利下面的cron命令:
/usr/bin/mysql -e "PURGE MASTER LOGS BEFORE CURRENT_DATA - INTERVAL N DAY"
expire_logs_days 设置在服务器启动或MySQL切换二进制日志时生效,因此,如果二进制日志从没有增长和切换,服务器不会清楚老条目。此设置是通过产看日志的修改时间而不是内容来决定哪个文件需要被清除的。
备份数据
逻辑备份: SQL导出和符号分隔文件
SQL导出:mysqldump不是生成sql逻辑备份的唯一工具。例如,也可以用mydumper或phpmyadmin工具来创建。
SQL逻辑备份缺点:
- schema和数据存储在一起
- 巨大的SQL语句
- 单个巨大的文件
- 逻辑备份的成本很高
符号分割文件备份:可以使用SQL命令SELECT INTO OUTFILE以符号分割文件格式创建数据的逻辑备份。(可以用mysqldump --tab选项到处到符号分隔文件中)。 优点是备份和还原速度更快。
可以使用LOAD DATA INFILE方法加载数据到表中
SELECT INTO OUTFILE方法的一些限制:
- 只能备份到运行MySQL服务器的机器上的文件中
- 运行MySQL的系统用户必须有文件目录的写权限,因为是由MySQL服务器来执行文件的写入,而不是运行SQL命令的用户。
- 出于安全原因,不能覆盖已经存在的文件,不管文件权限如何
文件系统快照: 一种非常好的在线备份的方法。支持快照的文件系统能够瞬间创建用来备份的内容一致的景象。支持快照的文件系统和设备包括FreeBSD的文件系统、ZFS文件系统、GNU/Linux的逻辑卷管理(LVM),以及许多的SAN系统和文件存储解决方案,例如NetApp存储.
lvm方式应该用不到的,看了一下,不写了。
从备份中恢复
如何恢复数据取决于是怎么备份的。可能需要一下部分或全部步骤:
- 停止MySQL服务器
- 记录服务器的配置和文件权限
- 将数据从备份中移到MySQL数据目录
- 改变配置
- 改变文件权限
- 以限制访问模式重启服务器,等待完成启动
- 载入逻辑备份文件
- 检查和重放二进制日志
- 检测已经还原的数据
- 以完全权限重启服务器
在恢复过程中,保证MySQL除了恢复进程外不接受其他访问,这一点往往比较重要。
加参数 --skip-networking 和 --socket=/tmp/mysql_recover.sock来启动MySQL
恢复物理备份:
检查目录的权限、配置文件的参数、观察错误日志
还原逻辑备份:
mysql < backup.sql
加载符号分割符文剑: LOAD DATA INFILE 或者使用mysqlimport
基于时间点的恢复:常见方法是还原最近一次全备份,然后从那个时间点开始重放二进制日志。623页
更高级的恢复技术:
用于快速回复的延时复制:搭建一个延时数据库
使用日志服务器进行恢复:
InnoDB崩溃恢复
根据日志文件将事务应用到数据文件,将未提交的变更从数据文件中回滚
InnoDB损坏的原因:硬件有关的(例如电力问题或内存损坏而导致损坏页的写入)。错误配置的硬件是更多的问题之源。
常见的错误配置包括打开了不包含电池备份单元的RAID卡的回写缓存,或打开iale硬盘驱动器本身的诙谐缓存。
严重的损坏会使InnoDB或MySQL奔溃,而不是那么严重的损坏则可能只是由于日志文件未真正同步到磁盘而丢掉了某些事务。
如何恢复损坏的InnoDB数据
InnoDB损坏有三种主要类型:
- 二级索引损坏: 一般可以用optimize table 来修复损坏的二级索引;也可以使用select into outfile,删除和重建表,然后 LOAD DATA INFILE的方法。这些都是通过构建一个新表受影响的索引,来修复损坏的索引数据。
- 聚簇索引损坏:也许只能使用 innodb_force_recovery选项导出表.笔者就曾遇到过不止一次,都是因为意外断电导致,或者存储挂掉。
- 损坏系统结构:包括InnoDB事务日志、表空间的撤销日志(undo log)区域和数据字典。这种损坏可能需要整个数据库的导出和还原,因为InnoDB内部绝大部分的工作都可能受到影响。
如果InnoDB的数据损坏到根本不能启动MySQL的程度,还可以使用Percona出品的InnoDB Recovery Toolkit从表空间的数据文件里面直接抽取数据。
Percona Server还有允许服务器在某些表损坏时仍能运行的选项,而不是像MySQL那样单个表损害页被检测出时就默认强制崩溃.
备份和恢复工具
- MySQL Enterprise Backup : 之前叫做InnoDB Hot Backup 或ibbackup。备份不需要停止MySQL,也不需要设置锁或中断正常的数据库活动。支持类似压缩备份、增量备份和到其他服务器的流备份特性。官方的备份工具
- Percona XtraBackup: 开源并且免费,支持类似流、增量、压缩和多线程(并行)备份操作。工作方式是在后台线程不断追踪InnoDB日志文件尾部,然后复制InnoDB数据文件。这是个轻量级的侵入过程,依靠特别的检测机制确保复制的数据是一致的。 还有XtraBack Manager项目:http://code.google.com/p/xtrabackup-manager
- mylvmbackup: http://lenz.homelinux.org/mylvmbackup 是一个perl脚本,通过LVM快照帮助MySQL自动备份。此工具首先获全局读锁,创建快照,释放锁。然后通过tar压缩数据并移除快照。它通过备份时的时间戳命名压缩包。
- Zmanda Recovery Manager: http://www.zmanda.com。配置、备份、验证、恢复、报告和调度,分免费和商业两种版本。
- mydumper: mysqldump的替代品。多线程备份和还原: http://www.mydumper.org
- mysqldump: 与mysql一起发行的程序。最常见。
--all-databases 备份所有的数据库
--databases sakila > dump.sql 备份数据库单个
mysqldump sakila actor > dump.sql 备份sakila.actor表
--result-file=dump.sql 指定输出文件
--opt 启用一组优化选项,包括关闭缓冲区,导出数据时把更多的数据卸载更少的SQL语句里
--allow-keyworkds,--quote-names 是用户在导出和恢复表时,可以使用保留字作为表的名字
--complete-insert 使用户能在不完全相同列的表之间移动数据
--tz-utc 使用户能在具有不同时区的服务器之间移动数据
--locak-all-tables 使用FLUSH TABLE WITH READ LOCK来获取全局一致的备份
--tab 用select into outfile 导出文件
--skip-extended-insert 使每一行数据都有自己的insert语句。
--single-transaction 对于InnoDB备份,这回使用InnoDB的MVCC特性在单个时间点创建一个一致的备份,而不需要使用LOCK TABLES锁定所有表
--master-data 备份会包括在备份时服务器的二进制日志文件位置,这对基于时间点的恢复和设置复制非常有帮助。
总结:
每个人都知道需要备份,但并不是每个人都意识到需要的是可恢复的备份。我们需要明确并记录恢复点目标和恢复时间目标,并且在选择备份系统时将其作为参考。
----内容摘自《高性能MySQL 第三版》