Skip to content

Latest commit

 

History

History
16 lines (12 loc) · 3.27 KB

3-4.md

File metadata and controls

16 lines (12 loc) · 3.27 KB

mysqldump 程序的实现原理是通过我们给的参数信息加上数据库中的系统表信息来一个表一个表获取数据然后生成 INSERT 语句再写入备份文件中的。这样就出现了一个问题,在系统正常运行过程中,很可能会不断有数据变更的请求正在执行,这样就可能造成在 mysqldump 备份出来的数据不一致。也就是说备份数据很可能不是同一个时间点的数据,而且甚至可能都没办法满足完整性约束。这样的备份集对于有些系统来说可能并没有太大问题,但是对于有些对数据的一致性和完整性要求比较严格系统来说问题就大了,就是一个完全无效的备份集。 对于如此场景,我们该如何做?我们知道,想数据库中的数据一致,那么只有两种情况下可以做到。

第一、同一时刻取出所有数据;

第二、数据库中的数据处于静止状态。

对于第一种情况,大家肯定会想,这可能吗?不管如何,只要有两个以上的表,就算我们如何写程序,都不可能昨晚完全一致的取数时间点啊。是的,我们确实无法通过常规方法让取数的时间点完全一致,但是大家不要忘记,在同一个事务中,数据库是可以做到所读取的数据是处于同一个时间点的。所以,对于事务支持的存储引擎,如 Innodb 或者 BDB 等 ,我们就可以通过控制将整个备份过程控制在同一个事务中,来达到备份数据的一致性和完整性,而且 mysqldump 程序也给我们提供了相关的参数选项来支持该功能,就是通过--single-transaction选项,可以不影响数据库的任何正常服务。原理是通过快照实现的。 补充: single-transaction可以让mysqldump 的时候不锁表。但是他有3个前提:

a、innodb的引擎

b、不能在执行的同时,有其他alter table ,drop table,rename table,truncate table的操作。

c、隔离级别 必须是REPEATABLE READ ,很多公司都会修改这个隔离级别的,比如阿里云的rds ,默认隔离级别是READ-COMMITTED

对于第二种情况我想大家首先想到的肯定是将需要备份的表锁定,只允许读取而不允许写入。是的,我们确实只能这么做。我们只能通过一个折衷的处理方式,让数据库在备份过程中仅提供数据的查询服务,锁定写入的服务,来使数据暂时处于一个一致的不会被修改的状态,等mysqldump 完成备份后再取消写入锁定,重新开始提供完整的服务。mysqldump 程序自己也提供了相关选项如--lock-tables--lock-all-tables ,在执行之前会锁定表,执行结束后自动释放锁定。这里有一点需要注意的就是,--lock-tables一次性将需要 dump 的所有表锁定,如果你需要 dump 的表分别在多个不同的数据库中,一定要使用“--lock-all-tables”才能确保数据的一致完整性。

mysqldump是MySQL用于转存储数据库的客户端程序。转储包含创建表和/或装载表的SQL语句 ,用来实现轻量级的快速迁移或恢复数据库,是mysql数据库实现逻辑备份的一种方式。 mysqldump不适用于大型数据库备份与恢复,速度慢,不支持并行,其次SQL重放将耗用大量的I/O。