- 第一、同一时刻取出所有数据;
- 第二、数据库中的数据处于静止状态。
对于第一种情况,大家肯定会想,这可能吗?
不管如何,只要有两个以上的表,就算我们如何写程序,都不可能昨晚完全一致的取数时间点啊。是的,我们确实无法通过常规方法让取数的时间点完全一致,但是大家不要忘记,在同一个事务中,数据库是可以做到所读取的数据是处于同一个时间点的。
所以,对于事务支持的存储引擎,如 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
”或者“--master-data=2
”,则 CHANGE_MASTER
语句会以注释的形式存在。这个选项在实施 slave 的在线搭建的时候是非常有用的,即使不是进行在线搭建 slave,也可以在某些情况下做恢复的过程中通过备份的 binlog 做进一步恢复操作。
在某些场景下,我们可能只是为了将某些特殊的数据导出到其他数据库中,而又不希望通过先建临时表的方式来实现,我们还可以在通过 mysqldump 程序的“—where='where-condition
’”来实现,但只能在仅 dump 一个表的情况下使用。
其实除了以上一些使用诀窍之外,mysqldump 还提供了其他很多有用的选项供大家在不同的场景下只用,如通过“--no-data
”仅仅 dump 数据库结构创建脚本,通过“--no-create-info
”去掉 dump 文件中创建表结构的命令等等,感兴趣的读者朋友可以详细阅读 mysqldump
程序的使用介绍再自行测试。
②生成特定格式的纯文本备份数据文件备份
除了通过生成 INSERT 命令来做逻辑备份之外,我们还可以通过另外一种方式将数据库中的数据以特定分隔字符将数据分隔记录在文本文件中,以达到逻辑备份的效果。这样的备份数据与 INSERT 命令文件相比,所需要使用的存储空间更小,数据格式更加清晰明确,编辑方便。但是缺点是在同一个备份文件中不能存在多个表的备份数据,没有数据库结构的重建命令。对于备份集需要多个文件,对我们产生的影响无非就是文件多了维护和恢复成本增加,但这些基本上都可以通过编写一些简单的脚本来实现。
那我们一般可以使用什么方法来生成这样的备份集文件呢,其实 MySQL 也已经给我们实现的相应的功能。
在 MySQL 中一般都使用以下两种方法来获得可以自定义分隔符的纯文本备份文件。
1.通过执行 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”
… …
2.通过 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 --fieldsenclosed-by=" --fields-terminated-by=,
root@sky:~# ls -l /tmp/mysqldump
total 8
-rw-r–r-- 1 root root 1346 2021-4-20 22:18 test_outfile.sql
-rw-rw-rw- 1 mysql mysql 2521 2021-4-20 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 2021-4-20 14:18:23
这样的输出结构对我们做为备份来使用是非常合适的,当然如果一次有多个表需要被 dump,就会针对每个表都会生成两个相对应的文件。
三、逻辑备份恢复方法
仅仅有了备份还是不够啊,我们得知道如何去使用这些备份,现在我们就看看上面所做的逻辑备份的恢复方法:
由于所有的备份数据都是以我们最初数据库结构的设计相关的形式所存储,所以逻辑备份的恢复也相对比较简单。当然,针对两种不同的逻辑备份形式,恢复方法也稍有区别。下面我们就分别针对这两种逻辑备份文件的恢复方法做一个简单的介绍。
①INSERT 语句文件的恢复
对于 INSERT 语句形式的备份文件的恢复是最简单的,我们仅仅只需要运行该备份文件中的所有(或者部分)SQL 命令即可。首先,如果需要做完全恢复,那么我们可以通过使用 “mysql < backup.sql
”直接调用备份文件执行其中的所有命令,将数据完全恢复到备份时候的状态。如果已经使用 mysql 连接上了 MySQL,那么也可以通过在 mysql 中执行“source/path/backup.sql
”或者“\. /path/backup.sql
”来进行恢复。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数软件测试工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年软件测试全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上软件测试开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注软件测试)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
转存中…(img-EXq4tLci-1712802174201)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!