前言 node
数据库的备份与恢复一直都是 DBA 工做中最为重要的部分之一,也是基本工做之一。任何正式环境的数据库都必须有完整的备份计划和恢复测试,本章内容将主要介绍 MySQL 数据库的备份与恢复相关内容。 mysql
你真的明白了本身所作的数据库备份是要面对什么样的场景的吗? 正则表达式
我想任何一位维护过数据库的人都知道数据库是须要备份的,也知道备份数据库是数据库维护必不可少的一件事情。那么是否每个人都知道本身所作的备份究竟是为了应对哪些场景的呢?抑或者说咱们每一个人是否都很清楚的知道,为何一个数据库须要做备份呢?读到这里,我想不少读者朋友都会嗤之以鼻,"备份的做用不就是为了防止原数据丢失吗,这谁不知道?"。确实,数据库的备份很大程度上的做用,就是当咱们的数据库由于某些缘由而形成部分或者所有数据丢失后,方便找回丢失的数据。可是,不一样类型的数据库备份,所能应付状况是不同的,并且,数据库的备份同时也还具备其余不少的做用。并且我想,每一个人对数据库备份的做用的理解可能都会有部分区别。 sql
下面我就列举一下我我的理解的咱们可以须要用到数据库备份的一些比较常见的状况吧。 数据库
1、数据丢失应用场景 安全
一、人为操做失误形成某些数据被误操做; 二、软件 BUG 形成数据部分或者所有丢失; 服务器
2、非数据丢失应用场景 session
上面所列出的只是一些常见的应用场景而已,除了上面这几种场景外,数据库备份还会有不少其余应用场景,这里就不一一列举了。那么各位读者过曾经或是如今所作的数据库备份究竟是为了应对以上哪种(或者几种)场景?或者说,咱们所作的数据库备份可以应对以上哪几种应用场景?不知道这个问题你们是否有考虑过。 工具
咱们必须认可,没有哪种数据库备份可以解决全部以上列举的几种常见应用场景,即便仅仅只是数据丢失的各类场景都没法经过某一种数据库备份完美的解决,固然也就更不用说可以解决全部的备份应用场景了。 测试
好比当咱们遇到磁盘故障,丢失了整个数据库的全部数据,而且没法从已经出现故障的硬盘上面恢复出来的时候,咱们可能必须经过一个实时或者有短暂时间差的复制备份数据库存在。固然若是没有这样的一个数据库,就必需要有最近时间的整个数据库的物理或者逻辑备份数据,而且有该备份以后的全部物理或者逻辑增量备份,以指望尽量将数据恢复到出现故障以前最近的时间点。而当咱们遇到认为操做失误形成数据被误操做以后,咱们须要有一个能恢复到错误操做时间点以前的瞬间的备份存在,固然这个备份多是整个数据库的备份,也能够仅仅只是被误操做的表的备份。而当咱们要作跨平台的数据库迁移的时候,咱们所须要的又只能是一个逻辑的数据库备份,由于平台的差别可能使物理备份的文件格式在两个平台上没法兼容。
既然没有哪种不少中数据库备份可以完美的解决全部的应用场景,而每一个数据库环境所须要面对的数据库备份应用场景又可能各不同,可能只是须要面对不少种场景中的某一种或几种,那么咱们就很是有必要指定一个合适的备份方案和备份策略,经过最简单的技术和最低廉的成本,来知足咱们的需求。
你们都知道,数据库在返回数据给咱们使用的时候都是按照咱们最初所设计指望的具备必定逻辑关联格式的形式一条一条数据来展示的,具备必定的商业逻辑属性,而在物理存储的层面上数据库软件倒是按照数据库软件所设计的某种特定格式通过必定的处理后存放。
数据库逻辑备份就是备份软件按照咱们最初所设计的逻辑关系,以数据库的逻辑结构对象为单位,将数据库中的数据按照预约义的逻辑关联格式一条一条生成相关的文本文件,以达到备份的目的。
逻辑备份能够说是最简单,也是目前中小型系统最常使用的备份方式。在 MySQL 中咱们经常使用的逻辑备份主要就是两种,一种是将数据生成能够彻底重现当前数据库中数据的 INSERT 语句,另一种就是将数据经过逻辑备份软件,将咱们数据库表数据以特定分隔符进行分隔后记录在文本文件中。
一、生成 INSERT 语句备份
两种逻辑备份各有优劣,所针对的使用场景也会稍有差异,咱们先来看一下生成 INSERT 语句的逻辑备份。
在 MySQL 数据库中,咱们通常都是经过 MySQL 数据库软件自带工具程序中的 mysqldump 来实现声称 INSERT 语句的逻辑备份文件。其使用方法基本以下:
Dumping definition and data mysql database or table
Usage: mysqldump [OPTIONS] database [tables]
OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
OR mysqldump [OPTIONS] --all-databases [OPTIONS]
因为 mysqldump 的使用方法比较简单,大部分须要的信息均可以经过运行"mysqldump -help"而得到。这里我只想结合 MySQL 数据库的一些概念原理和你们探讨一下当咱们使用 mysqldump 来作数据库逻辑备份的时候有些什么技巧以及须要注意一些什么内容。
咱们都知道,对于大多数使用数据库的软件或者网站来讲,都但愿本身数据库可以提供尽量高的可用性,而不是时不时的就须要停机中止提供服务。由于一旦数据库没法提供服务,系统就没法再经过存取数据来提供一些动态功能。因此对于大多数系统来讲若是要让每次备份都停机来作可能都是不可接受的,但是 mysqldump 程序的实现原理是经过咱们给的参数信息加上数据库中的系统表信息来一个表一个表获取数据而后生成 INSERT 语句再写入备份文件中的。这样就出现了一个问题,在系统正常运行过程当中,极可能会不断有数据变动的请求正在执行,这样就可能形成在 mysqldump 备份出来的数据不一致。也就是说备份数据极可能不是同一个时间点的数据,并且甚至可能都没办法知足完整性约束。这样的备份集对于有些系统来讲可能并无太大问题,可是对于有些对数据的一致性和完整性要求比较严格系统来讲问题就大了,就是一个彻底无效的备份集。
对于如此场景,咱们该如何作?咱们知道,想数据库中的数据一致,那么只有两种状况下能够作到。
第1、同一时刻取出全部数据;第2、数据库中的数据处于静止状态。
对于第一种状况,你们确定会想,这可能吗?无论如何,只要有两个以上的表,就算咱们如何写程序,都不可能昨晚彻底一致的取数时间点啊。是的,咱们确实没法经过常规方法让取数的时间点彻底一致,可是你们不要忘记,在同一个事务中,数据库是能够作到所读取的数据是处于同一个时间点的。因此,对于事务支持的存储引擎,如 Innodb 或者 BDB 等 ,咱们就能够经过控制将整个备份过程控制在同一个事务中,来达到备份数据的一致性和完整性,并且 mysqldump 程序也给咱们提供了相关的参数选项来支持该功能,就是经过 "-single-transaction"选项,能够不影响数据库的任何正常服务。
对于第二种状况我想你们首先想到的确定是将须要备份的表锁定,只容许读取而不容许写入。是的,咱们确实只能这么作。咱们只能经过一个折衷的处理方式,让数据库在备份过程当中仅提供数据的查询服务,锁定写入的服务,来使数据暂时处于一个一致的不会被修改的状态,等 mysqldump 完成备份后再取消写入锁定,从新开始提供完整的服务。mysqldump 程序本身也提供了相关选项如"--lock-tables"和"--lock-all-tables",在执行以前会锁定表,执行结束后自动释放锁定。这里有一点须要注意的就是,"--lock-tables"并非一次性将须要 dump 的全部表锁定,而是每次仅仅锁定一个数据库的表,若是你须要 dump 的表分别在多个不一样的数据库中,必定要使用"--lock-all-tables"才能确保数据的一致完整性。
当经过 mysqldump 生成 INSERT 语句的逻辑备份文件的时候,有一个很是有用的选项能够供咱们使用,那就是"--master-data[=value]"。当添加了"--master-data=1"的时候, mysqldump 会将当前 MySQL 使用到 binlog 日志的名称和位置记录到 dump 文件中,而且是被以 CHANGE_MASTER 语句的形式记录,若是仅仅只是使用"--master-data"或者"--masterdata=2",则 CHANGE_MASTER 语句会以注释的形式存在。这个选项在实施 slave 的在线搭建的时候是很是有用的,即便不是进行在线搭建 slave,也能够在某些状况下作恢复的过程当中经过备份的 binlog 作进一步恢复操做。
在某些场景下,咱们可能只是为了将某些特殊的数据导出到其余数据库中,而又不但愿经过先建临时表的方式来实现,咱们还能够在经过 mysqldump 程序的"—where='wherecondition'"来实现,但只能在仅 dump 一个表的状况下使用。
其实除了以上一些使用诀窍以外,mysqldump 还提供了其余不少有用的选项供你们在不一样的场景下只用,如经过"--no-data"仅仅 dump 数据库结构建立脚本,经过"--no-createinfo"去掉 dump 文件中建立表结构的命令等等,感兴趣的读者朋友能够详细阅读 mysqldump 程序的使用介绍再自行测试。
二、生成特定格式的纯文本备份数据文件备份
除了经过生成 INSERT 命令来作逻辑备份以外,咱们还能够经过另一种方式将数据库中的数据以特定分隔字符将数据分隔记录在文本文件中,以达到逻辑备份的效果。这样的备份数据与 INSERT 命令文件相比,所须要使用的存储空间更小,数据格式更加清晰明确,编辑方便。可是缺点是在同一个备份文件中不能存在多个表的备份数据,没有数据库结构的重建命令。对于备份集须要多个文件,对咱们产生的影响无非就是文件多了维护和恢复成本增长,但这些基本上均可以经过编写一些简单的脚原本实现
那咱们通常可使用什么方法来生成这样的备份集文件呢,其实 MySQL 也已经给咱们实现的相应的功能。
在 MySQL 中通常都使用如下两种方法来得到能够自定义分隔符的纯文本备份文件。
一、经过执行 SELECT ... TO OUTFILE FROM ...命令来实现
在 MySQL 中提供了一种 SELECT 语法,专供用户经过 SQL 语句将某些特定数据以指定格式输出到文本文件中,同时也提供了实用工具和相关的命令能够方便的将导出文件原样再导入到数据库中。正不正是咱们作备份所须要的么?
该命令有几个须要注意的参数以下:
实现字符转义功能的"FIELDS ESCAPED BY ['name']" 将 SQL 语句中须要转义的字符进行转义;
能够将字段的内容"包装"起来的"FIELDS [OPTIONALLY] ENCLOSED BY 'name'",如
果不使用"OPTIONALLY"则包括数字类型的全部类型数据都会被"包装",使 用"OPTIONALLY" 以后,则数字类型的数据不会被指定字符"包装"。
经过"FIELDS TERMINATED BY"能够设定每两个字段之间的分隔符;而经过"LINES TERMINATED BY"则会告诉 MySQL 输出文件在每条记录结束的时候须要
添加什么字符。
如如下示例:
root@localhost : test 10:02:02> SELECT * INTO OUTFILE '/tmp/dump.text'
-> FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
-> LINES TERMINATED BY '\n'
-> FROM test_outfile limit 100; Query OK, 100 rows affected (0.00 sec)
root@localhost : test 10:02:11> exit Bye root@sky:/tmp# cat dump.text
350021,21,"A","abcd"
350022,22,"B","abcd"
350023,23,"C","abcd"
350024,24,"D","abcd"
350025,25,"A","abcd" ... ...
二、经过 mysqldump 导出可能咱们都知道 mysqldump 能够将数据库中的数据以 INSERT 语句的形式生成相关备份文件,其实除了生成 INSERT 语句以外,mysqldump 还一样能实现上面"SELECT ... TO
OUTFILE FROM ..."所实现的功能,并且同时还会生成一个相关数据库结构对应的建立脚本 。
如如下示例:
root@sky:~# ls -l /tmp/mysqldump total 0 root@sky:~# mysqldump -uroot -T/tmp/mysqldump test test_outfile --fields-
enclosed-by=\" --fields-terminated-by=, root@sky:~# ls -l /tmp/mysqldump total 8
-rw-r--r-- 1 root root 1346 2008-10-14 22:18 test_outfile.sql
-rw-rw-rw- 1 mysql mysql 2521 2008-10-14 22:18 test_outfile.txt
root@sky:~# cat /tmp/mysqldump/test_outfile.txt
350021,21,"A","abcd"
350022,22,"B","abcd"
350023,23,"C","abcd"
350024,24,"D","abcd"
350025,25,"A","abcd" ... ...
root@sky:~# cat /tmp/mysqldump/test_outfile.sql
-- MySQL dump 10.11
--
-- Host: localhost Database: test
-- ------------------------------------------------------- Server version 5.0.51a-log
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `test_outfile` --
DROP TABLE IF EXISTS `test_outfile`;
SET @saved_cs_client = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `test_outfile` (
`id` int(11) NOT NULL default '0',
`t_id` int(11) default NULL,
`a` char(1) default NULL,
`mid` varchar(32) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
SET character_set_client = @saved_cs_client;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2008-10-14 14:18:23
这样的输出结构对咱们作为备份来使用是很是合适的,固然若是一次有多个表须要被 dump,就会针对每一个表都会生成两个相对应的文件。
仅仅有了备份仍是不够啊,咱们得知道如何去使用这些备份,如今咱们就看看上面所作的逻辑备份的恢复方法:
因为全部的备份数据都是以咱们最初数据库结构的设计相关的形式所存储,因此逻辑备份的恢复也相对比较简单。固然,针对两种不一样的逻辑备份形式,恢复方法也稍有区别。下面咱们就分别针对这两种逻辑备份文件的恢复方法作一个简单的介绍。
对于 INSERT 语句形式的备份文件的恢复是最简单的,咱们仅仅只须要运行该备份文件中的全部(或者部分)SQL 命令便可。首先,若是须要作彻底恢复,那么咱们能够经过使用 "mysql < backup.sql"直接调用备份文件执行其中的全部命令,将数据彻底恢复到备份时候的状态。若是已经使用 mysql 链接上了 MySQL,那么也能够经过在 mysql 中执行"source
/path/backup.sql"或者"\. /path/backup.sql"来进行恢复。
若是是上面第二中形式的逻辑备份,恢复起来会稍微麻烦一点,须要一个表一个表经过相关命令来进行恢复,固然若是经过脚原本实现自动多表恢复也是比较方便的。恢复方法也有两个,一是经过 MySQL 的"LOAD DATA INFILE"命令来实现,另外一种方法就是经过 MySQL 提供的使用工具 mysqlimport 来进行恢复。
逻辑备份能作什么?不能作什么?
在清楚了如何使用逻辑备份进行相应的恢复以后,咱们须要知道咱们能够利用这些逻辑备份作些什么。
在知道了逻辑备份能作什么以后,咱们必须还要清楚他不能作什么,这样咱们本身才能清楚的知道这样的一个备份可否知足本身的预期,是否确实是本身想要的。
5.2.4 逻辑备份恢复测试
时有听到某某的数据库出现问题,而当其信心十足的准备拿以前所作好的数据库进行恢复的时候才发现本身的备份集不可用,或者并不能达到本身作备份时候所预期的恢复效果。遇到这种情景的时候,恐怕每一个人都会郁闷至极的。数据库备份最重要最关键的一个用途就是当咱们的数据库出现某些异常情况,须要对数据进行恢复的时候使用的。做为一个维护人员,咱们是绝对不该该出现此类低级错误的。那咱们到底该如何避免此类问题呢?只有一个办法,那就是周期性的进行模拟恢复测试,校验咱们的备份集是否真的有效,是否确实可以按照咱们的备份预期进行相应的恢复。
到这里可能有人会问,恢复测试又该如何作呢,咱们总不能真的将线上环境的数据进行恢复啊?是的,线上环境的数据确实不能被恢复,可是咱们为何不能在测试环境或者其余的地方作呢?作恢复测试只是为了验证咱们的备份是否有效,是否能达到咱们的预期。因此在作恢复测试以前咱们必定要先清楚的知道咱们所作的备份究竟是为了应用于什么样的场景的。就好比咱们作了一个全库的逻辑备份,目的多是为了当数据库出现逻辑或者物理异常的时候可以恢复整个数据库的数据到备份时刻,那么咱们恶的恢复测试就只须要将整个逻辑备份进行全库恢复,看是否可以成功的重建一个完整的数据库。至于恢复的数据是否和备份时刻一致,就只能依靠咱们本身来人工判断比较。此外咱们可能还但愿当某一个数据库对象,好比某个表出现问题以后可以尽快的恢复该表数据到备份时刻。那么咱们就能够针对单个指定表进行抽样恢复测试。
下面咱们就假想数据库主机崩溃,硬件损坏,形成数据库数据所有丢失,来作一次全库恢复的测试示例:
当咱们的数据库出现硬件故障,数据所有丢失以后,咱们必须尽快找到一台新的主机以顶替损坏的主机来恢复相应的服务。在恢复服务以前,咱们首先须要重建损坏的数据库。假设咱们已经拿到了一台新的主机,MySQL 软件也已经安装就位,相关设置也都已经调整好,就等着恢复数据库了。
咱们须要取回离崩溃时间最近的一次全库逻辑备份文件,复制到准备的新主机上,启动已经安装好的 MySQL。
因为咱们有两种逻辑备份格式,每种格式的恢复方法并不同,因此这里将对两种格式的逻辑备份的恢复都进行示例。
一、若是是 INSERT 语句的逻辑备份
或者先经过 mysql 登陆到数据库中,而后再执行以下命令:
root@localhost : (none) 09:59:40> source /tmp/backup.sql
固然上面所说的步骤都是在默认每一步都正常的前提下进行的,若是发现某一步有问题。倘若在 b 步骤出现异常,没法继续进行下去,咱们首先须要根据出现的错误来排查是不是咱们恢复命令有错?是否咱们的环境有问题等?等等。若是咱们确认是备份文件的问题,那么说明咱们的这个备份是无效的,说明测试失败了。若是咱们恢复过程很正常,可是在校验的时候发现缺乏数据库对象,或者某些对象中的数据不正确,或者根本没有数据。一样说明咱们的备份级没法知足预期,备份失败。固然,若是咱们是在实际工做的恢复过程当中遇到相似状况的时候,若是还有更早的备份集,咱们必须退一步使用更早的备份集作相同的恢复操做。虽然更早的备份集中的数据可能会有些失真,可是至少能够部分恢复,而不至于丢失全部数据。
二、若是咱们是备份的以特殊分隔符分隔的纯数据文本文件 a、第一步和 INSERT 备份文件没有区别,就是将最接近崩溃时刻的备份文件准备好;
b、经过特定工具或者命令将数据导入如到数据库中:
因为数据库结构建立脚本和纯文本数据备份文件分开存放,因此咱们首先须要执行数据库结构建立脚本,而后再导入数据。结构建立脚本的方法和上面第一种备份的恢复测试中的 b 步骤彻底同样。
有了数据库结构以后,咱们就能够导入备份数据了,以下:
mysqlimport --user=name --password=pwd test --fields-enclosed-by=\" -fields-terminated-by=, /tmp/test_outfile.txt 或者
LOAD DATA INFILE '/tmp/test_outfile.txt' INTO TABLE test_outfile FIELDS
TERMINATED BY '"' ENCLOSED BY ',';
后面的步骤就和备份文件为 INSERT 语句备份的恢复彻底同样了,这里就再也不累述。
前面一节咱们了解了如何使用 MySQL 的逻辑备份,并作了一个简单的逻辑备份恢复示例,在这一节咱们再一块儿了解一些 MySQL 的物理备份。
在了解 MySQL 的物理备份以前,咱们须要先了解一下,什么是数据库物理备份?既然是物理备份,那么确定是和数据库的物理对象相对应的。就如同逻辑备份根据由咱们根据业务逻辑所设计的数据库逻辑对象所作的备份同样,数据库的物理备份就是对数据库的物理对象所作的备份。数据库的物理对象主要由数据库的物理数据文件、日志文件以及配置文件等组成。在 MySQL 数据库中,除了 MySQL 系统共有的一些日志文件和系统表的数据文件以外,每一种存储引擎本身还会有不太同样的物理对象,在以前第一篇的"MySQL 物理文件组成"中咱们已经有了一个基本的介绍,在下面咱们将详细列出几种经常使用的存储引擎各自所对应的物理对象(物理文件),以便在后面你们可以清楚的知道各类存储引擎在作物理备份的时候到底哪些文件是须要备份的哪些又是不须要备份的。
MyISAM 存储引擎
MyISAM 存储引擎的全部数据都存放在 MySQL 配置中所设定的"datadir"目录下。实际上无论咱们使用的是 MyISAM 存储引擎仍是其余任何存储引擎,每个数据库都会在 "datadir"目录下有一个文件夹(包括系统信息的数据库 mysql 也是同样)。在各个数据库中每个 MyISAM 存储引擎表都会有三个文件存在,分别为记录表结构元数据的".frm"文件,存储表数据的".MYD"文件,以及存储索引数据的".MYI"文件。因为 MyISAM 属于非事务性存储引擎,因此他没有本身的日志文件。因此 MyISAM 存储引擎的物理备份,除了备份 MySQL 系统的共有物理文件以外,就只须要备份上面的三种文件便可。
Innodb 存储引擎
Innodb 存储引擎属于事务性存储引擎,并且存放数据的位置也可能与 MyISAM 存储引擎有所不一样,这主要取决于咱们对 Innodb 的""相关配置所决定。决定 Innodb 存放数据位置的 配 置 为 " innodb_data_home_dir " 、 " innodb_data_file_path " 和 "innodb_log_group_home_dir"这三个目录位置指定参数,以及另一个决定 Innodb 的表空间存储方式的参数"innodb_file_per_table"。前面三个参数指定了数据和日志文件的存放位置,最后一个参数决定 Innodb 是以共享表空间存放数据仍是以独享表空间方式存储数据。这几个参数的相关使用说明咱们已经在第一篇的"MySQL 存储引擎介绍"中作了相应的解释,在 MySQL 的官方手册中也有较为详细的说明,因此这里就再也不累述了。
如 果 我 们 使 用 了 共 享 表 空 间 的 存 储 方 式 , 那 么 Innodb 需 要 备 份 备 份
"innodb_data_home_dir"和"innodb_data_file_path"参数所设定的全部数据文件,
"datadir"中相应数据库目录下的全部 Innodb 存储引擎表的".frm"文件;
而若是咱们使用了独享表空间,那么咱们除了备份上面共享表空间方式所须要备份的全部文件以外,咱们还须要备份"datadir"中相应数据库目录下的全部".idb"文件,该文件中存放的才是独享表空间方式下 Innodb 存储引擎表的数据。可能在这里有人文,既然是使用独享表空间,那咱们为何还要备份共享表空间"才使用到"的数据文件呢?其实这是不少人的一个共性误区,觉得使用独享表空间的时候 Innodb 的全部信息就都存放在 "datadir"所设定数据库目录下的".ibd"文件中。实际上并非这样的,".ibd"文件中所存放的仅仅只是咱们的表数据而已,你们都很清楚,Innodb 是事务性存储引擎,他是须要 undo 和 redo 信息的,而无论 Innodb 使用的是共享仍是独享表空间的方式来存储数据,与事务相关的 undo 信息以及其余的一些元数据信息,都是存放在"innodb_data_home_dir" 和"innodb_data_file_path"这两个参数所设定的数据文件中的。因此要想 Innodb 的物理备 份 有 效 ,"innodb_data_home_dir"和"innodb_data_file_path"参数所设定的数据文件无论在什么状况下咱们都必须备份。
此外,除了上面所说的数据文件以外,Innodb 还有本身存放 redo 信息和相关事务信息的日志文件在"innodb_log_group_home_dir"参数所设定的位置。因此要想 Innodb 物理备份可以有效使用,咱们还比须要备份"innodb_log_group_home_dir"参数所设定的位置的全部日志文件。
NDB Cluster 存储引擎
NDB Cluster 存储引擎(其实也能够说是 MySQL Cluster)的物理备份须要备份的文件主要有一下三类:
不管是经过停机冷备份,仍是经过 NDB Cluster 自行提供的在线联机备份工具,或者是第三方备份软件来进行备份,都须要备份以上三种物理文件才能构成一个完整有效的备份集。固然,相关的配置文件,尤为是管理节点上面的配置信息,一样也须要备份。
因为不一样存储引擎所须要备份的物理对象(文件)并不同,且每一个存储引擎对数据文件的一致性要求也不同因此各个存储引擎在进行物理备份的时候所使用的备份方法也有区别。固然,若是咱们是要作冷备份(停掉数据库以后的备份),咱们所须要作的事情都很简单,那就是直接 copy 全部数据文件和日志文件到备份集须要存放的位置便可,无论是何种存储引擎均可以这样作。因为冷备份方法简单,实现容易,因此这里就不详细说明了。
在咱们的实际应用环境中,是不多有可以让咱们能够停机作平常备份的状况的,咱们只能在数据库提供服务的状况下来完成数据库备份。这也就是咱们俗称的热物理备份了。下面咱们就针对各个存储引擎单独说明各自最经常使用的在线(热)物理备份方法。
MyISAM 存储引擎
上面咱们介绍了 MyISAM 存储引擎文件的物理文件比较集中,并且不支持事务没有 redo 和 undo 日志,对数据一致性的要求也并非特别的高,因此 MyISAM 存储引擎表的物理备份也比较简单,只要将 MyISAM 的物理文件 copy 出来便可。可是,虽然 MyISAM 存储引擎没有事务支持,对数据文件的一致性要求没有 Innodb 之类的存储引擎那么严格,可是 MyISAM 存储引擎的同一个表的数据文件和索引文件之间是有一致性要求的。当 MyISAM 存储引擎发现某个表的数据文件和索引文件不一致的时候,会标记该表处于不可用状态,并要求你进行修复动做,固然,通常状况下的修复都会比较容易。可是,即便数据库存储引擎自己对数据文件的一致性要求并非很苛刻,咱们的应用也容许数据不一致吗?我想答案确定是否认的,因此咱们本身必须至少保证数据库在备份时候的数据是处于某一个时间点的,这样就要求咱们必须作到在备份 MyISAM 数据库的物理文件的时候让 MyISAM 存储引擎中止写操做,仅仅提供读服务,其根本实质就是给数据库表加锁来阻止写操做。
MySQL 本身提供了一个使用程序 mysqlhotcopy,这个程序就是专门用来备份 MyISAM 存储引擎的。不过若是你有除了 MyISAM 以外的其余非事务性存储引擎,也能够经过合适的参数设置,或者微调该备份脚本,也都能经过 mysqlhotcopy 程序来完成相应的备份任务,基本用法以下:
mysqlhotcopy db_name[./table_regex/] [new_db_name | directory]
从上面的基本使用方法咱们能够看到,mysqlhotcopy 出了能够备份整个数据库,指定的某个表,还能够经过正则表达式来匹配某些表名来针对性的备份某些表。备份结果就是指定数据库的文件夹下包括全部指定的表的相应物理文件。
mysqlhotcopy 是一个用 perl 编写的使用程序,其主要实现原理实际上就是经过先 LOCK 住表,而后执行 FLUSH TABLES 动做,该正常关闭的表正常关闭,将该 fsync 的数据都 fsync,而后经过执行 OS 级别的复制(cp 等)命令,将须要备份的表或者数据库的全部物理文件都复制到指定的备份集位置。
此外,咱们也能够经过登陆数据库中手工加锁,而后再经过操做系统的命令来复制相关文件执行热物理备份,且在完成文件 copy 以前,不能退出加锁的 session(由于退出会自动解锁),以下:
root@localhost : test 08:36:35> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.00 sec)
不退出 mysql,在新的终端下作以下备份:
mysql@sky:/data/mysql/mydata$ cp -R test /tmp/backup/test mysql@sky:/data/mysql/mydata$ ls -l /tmp/backup/ total 4 drwxr-xr-x 2 mysql mysql 4096 2008-10-19 21:57 test mysql@sky:/data/mysql/mydata$ ls -l /tmp/backup/test total 39268
-rw-r----- 1 mysql mysql |
8658 2008-10-19 21:57 hotcopy_his.frm |
-rw-r----- 1 mysql mysql |
36 2008-10-19 21:57 hotcopy_his.MYD |
-rw-r----- 1 mysql mysql |
1024 2008-10-19 21:57 hotcopy_his.MYI |
-rw-r----- 1 mysql mysql ... ... |
8586 2008-10-19 21:57 memo_test.frm |
-rw-rw---- 1 mysql mysql |
8554 2008-10-19 22:01 test_csv.frm |
-rw-rw---- 1 mysql mysql |
0 2008-10-19 22:01 test_csv.MYD |
-rw-rw---- 1 mysql mysql |
1024 2008-10-19 22:01 test_csv.MYI |
-rw-r----- 1 mysql mysql |
8638 2008-10-19 21:57 test_myisam.frm |
-rw-r----- 1 mysql mysql 20999600 2008-10-19 21:57 test_myisam.MYD
-rw-r----- 1 mysql mysql 10792960 2008-10-19 21:57 test_myisam.MYI
-rw-r----- 1 mysql mysql 8638 2008-10-19 21:57 test_outfile.frm
-rw-r----- 1 mysql mysql 2400 2008-10-19 21:57 test_outfile.MYD
-rw-r----- 1 mysql mysql 1024 2008-10-19 21:57 test_outfile.MYI
... ...
而后再在以前的执行锁定命令的 session 中解锁
root@localhost : test 10:00:57> unlock tables;
Query OK, 0 rows affected (0.00 sec)
这样就完成了一次物理备份,并且你们也从文件列表中看到了,备份中还有 CSV 存储引擎的表。
Innodb 存储引擎
Innodb 存储引擎因为是事务性存储引擎,有 redo 日志和相关的 undo 信息,并且对数据的一致性和完整性的要求也比 MyISAM 要严格不少,因此 Innodb 的在线(热)物理备份要比 MyISAM 复杂不少,通常很难简单的经过几个手工命令来完成,大都是经过专门的 Innodb 在线物理备份软件来完成。
Innodb 存储引擎的开发者(Innobase 公司)开发了一款名为 ibbackup 的商业备份软件 ,专门实现 Innodb 存储引擎数据的在线物理备份功能。该软件能够在 MySQL 在线运行的状态下,对数据库中使用 Innodb 存储引擎的表进行备份,不过仅限于使用 Innodb 存储引擎的表。
因为这款软件并非开源免费的产品,我我的也不多使用,主要也是下载的试用版试用而已,因此这里就不详细介绍了,各位读者朋友能够经过 Innobase 公司官方网站获取详细的使用手册进行试用
NDB Cluster 存储引擎
NDB Cluster 存储引擎也是一款事务性存储引擎,和 Innodb 同样也有 redo 日志。NDB Cluter 存储引擎本身提供了备份功能,能够经过相关的命令实现。固然,停机冷备的方法也是有效的。
在线联机备份步骤以下:
因为 NDB Cluster 的备份,备份指令是从管理节点发起,且并不会等待备份完成就会返回,因此也没办法直接经过 "Ctrl + c" 或者其余方式来中断备份进程,因此 NDB
Cluster 提供了相应的命令来中断当前正在进行的备份操做,以下:
**而放弃"。至此,中断备份操做完成。
经过 NDB Cluster 存储引擎本身的备份命令来进行备份以后,会将前面所提到的三种文件存放在参与备份的节点上面,且被存放在三个不一样的文件中,相似以下:
BACKUP-backup_id.node_id.ctl,内容包含相关的控制信息和元数据的控制文件。每一个节点均会将相同的表定义(对于 Cluster 中的全部表)保存在本身的该文件中。
BACKUP-backup_id-n.node_id.data,数据备份文件,被分红多个不一样的片断来保存,在备份过程当中,不一样的节点将保存不一样的备份数据所产生的片断,每一个节点保存的文件都会有信息指明数据所属表的部分,且在备份片断文件最后还包含了最后的校验信息,以确保备份可以正确恢复。
BACKUP-backup_id.node_id.log,事务日志备份文件中仅包含已提交事务的相关信息,且仅保存已在备份中保存的表上的事务,各个阶段所保存的日志信息也不同,由于仅仅针对各节点所包含的数据记录相关的日志信息。
上面的备份文件命名规则中,backup_id 是指备份号,不一样的备份集会针对有一个不一样的备份号,node_id 则是指明该备份文件属于哪一个数据节点,而在数据文件的备份文件中的 n 则是指明片断号。
和以前逻辑备份同样,光有备份是没有意义的,还须要可以将备份有效的恢复才行。物理备份和逻辑备份相比最大的优点就是恢复速度快,由于主要是物理文件的拷贝,将备份文件拷贝到须要恢复的位置,而后进行简单的才作便可。
MyISAM 存储引擎
MyISAM 存储引擎因为其特性,物理备份的恢复也比较简单。
若是是经过停机冷备份或者是在运行状态经过锁定写入操做后的备份集来恢复,仅仅只须要将该备份集直接经过操做系统的拷贝命令将相应的数据文件复制到对应位置来覆盖现有文件便可。
若是是经过 mysqlhotcopy 软件来进行的在线热备份,并且相关的备份信息也记录进入了数据库中相应的表,其恢复操做可能会须要结合备份表信息来进行恢复。
Innodb 存储引擎
对于冷备份,Innodb 存储引擎进行恢复所须要的操做和其余存储引擎没有什么差异,一样是备份集文件(包括数据文件和日志文件)复制到相应的目录便可。可是对于经过其余备份软件所进行的备份,就须要根据备份软件自己的要求来进行了。好比经过 ibbackup 来进行的备份,一样也须要经过他来进行恢复才能够,具体的恢复方法请经过该软件的使用手册来进行,这里就不详细介绍了。
NDB Cluster 存储引擎
对于停机冷备,恢复方法和其余存储引擎也没有太多区别,只不过有一点须要特别注意的就是恢复的时候必需要将备份集中文件恢复到对应的数据节点之少,不然没法正确完成恢复过程。
而经过 NDB Cluster 所提供的备份命令来生成的备份集,须要使用专用的备份恢复软件 ndb_restore 来进行。ndb_restore 软件将从备份集中读取出备份相关的控制信息,并且 ndb_restore 软件必须在单独的数据节点上面分别进行。因此当初备份进行过程当中有多少数据节点,如今就须要运行多少次 ndb_restore。并且,首次经过 ndb_restore 来进行恢复的话,还必须恢复元数据,也就是会重建全部的数据库和表。
备份是否完整,可否知足要求,关键仍是须要看所设计的备份策略是否合理,以及备份操做是否确实按照所设计的备份策略进行了。
针对于不一样的用途,所须要的备份类型是不同的,因此须要的备份策略有各有不一样。如为了应对本章最开始所描述的在线应用的数据丢失的问题,咱们的备份就须要快速恢复,并且最好是仅仅须要增量恢复就能找回所需数据。对于这类需求,最好是有在线的,且部分延迟恢复的备用数据库。由于这样能够在最短期内找回所须要的数据。甚至在某些硬件设备出现故障的时候,将备用库直接开发对外提供服务均可以。固然,在资源缺少的状况下,可能难以找到足够的备用硬件设备来承担这个备份责任的时候,咱们也能够经过物理备份来解决,毕竟物理备份的恢复速度要比逻辑备份的快不少。
而对于那些非数据丢失的应用场景,大多数时候恢复时间的要求并非过高,只要能够恢复出一个完整可用的数据库就能够了。因此不管是物理备份仍是逻辑备份,影响都不大。
从我我的经验来看,能够根据不一样的需求不一样的级别经过以下的几个思路来设计出合理的备份策略:
上面的四种备份策略都还比较较粗糙,甚至不能算是一个备份策略。目的只是但愿能给你们一个指定备份策略的思路。各位读者朋友能够根据这个思路根据实际的应用场景,指定出各类不一样的备份策略。
总的来讲,MySQL 的备份与恢复都不是太复杂,方法也比较单一。姑且不说逻辑备份,对于物理备份来讲,确实是还不够完善。缺乏一个开源的比较好的在线热物理备份软件,一直是 MySQL 一个比较大的遗憾,也是全部 MySQL 使用者比较郁闷的事情。
固然,没有开源的备份软件使用,非开源的商业软件也仍是有的,如比较著名的 Zmanda 备份恢复软件,功能就比较全面,使用也不太复杂,在商业的 MySQL 备份恢复软件市场上有较高的占有率。并且,Zmanda 同时还提供社区版本的免费下载使用。
不过,稍微让人有所安慰的是 MySQL 在实际应用场景中大可能是有一台或者多台 Slave 机器来做为热备的。在须要进行备份的时候经过 Slave 来进行备份也不是太难,并且经过暂时中止 Slave 上面的 SQL 线程,便可让 Slave 机器中止全部数据写入操做,而后就能够进行在线进行备份操做了。因此即便买不起商用软件或者不太想买关系也不是太大。