mysqldump与innobackupex备份过程你知多少(二)

1.2.3. 使用WITH CONSISTENT SNAPSHOT子句的作用

START TRANSACTION语句使用WITH CONSISTENT SNAPSHOT子句时,会为事务启动一致性读(该子句仅适用于InnoDB)。其行为与执行START TRANSACTION语句之后+一个SELECT语句效果相同(会获取一个事务号,在read view中占个坑,但是不会请求任何锁)。WITH CONSISTENT SNAPSHOT子句不会自动修改当前的事务隔离级别,由于WITH CONSISTENT SNAPSHOT子句要求必须RR隔离级别下才会自动启用,因此只有当前隔离级别为RR时才会启用一致性快照,非RR隔离级别下,会忽略WITH CONSISTENT SNAPSHOT子句。从MySQL 5.7.2起,当WITH CONSISTENT SNAPSHOT子句被忽略时,会产生一个警告(类似上一篇mysqldump与innobackupex备份过程你知多少(一)提到的警告信息)。

为了使得更清晰地了解mysqldump在备份过程中使用WITH CONSISTENT SNAPSHOT子句的作用,下面咱们来演示一下带与不带WITH CONSISTENT SNAPSHOT子句会发生什么?

  • 开启两个会话,操作同一张表

从上面的表格对比结果中可以看到:

  • WITH CONSISTENT SNAPSHOT子句的作用就相当于START TRANSACTION+ SELECT语句,目地是为了在开启事务的那一刻往mvcc的read view中立即加入这个事务,就好像read view在事务一开始就被固定了一样,使得后续其他事务的DML不会影响到该事务的查询结果,这就是所说的一致性读
  • 如果不使用WITH CONSISTENT SNAPSHOT子句,在使用START TRANSACTION语句显式开启一个事务之后,在执行SELECT语句之前,这段时间内如果有别的事务发起了DML操作,就会导致该事务查询该表的时候读取的数据与事务开始时间点不一致。

1.2.4. 使用savepoint来设置回滚点的作用

大家都知道,设置SAVEPOINT是为了回滚在设置这个点时候发生变更的数据,但是mysqldump备份只是使用select语句做查询,为什么要使用savepoint呢?需要回滚什么呢?请看下文分析:

  • SAVEPOINT 'identifier' 语句,为事务设置一个命名的事务保存点(回滚点),该字符串为事务保存点的标识符。
  • ROLLBACK TO SAVEPOINT 语句的作用是将事务回滚到指定的保存点的位置,而不终止事务。当前事务在回滚点之后的修改的行数据将被撤销(注:InnoDB不会释放这些发生修改且被撤销行的行锁,注意是修改,不是新插入,这些发生修改的数据行行锁被存储在内存中),对于设置了保存点之后,新插入的行数据也会被撤销(注:这些锁信息被存储在行数据中的事务ID上,这些行锁不会单独存储在内存中,在这种情况下,这些新插入的行数据在被回滚之后,对应的行锁将被释放)。另外,回滚到某个保存点之后,比这个保存点在时间上更晚设置的保存点将被删除。
  • ROLLBACK TO SAVEPOINT 语句还有一个作用,可以释放在设置保存点之后事务持有的MDL锁,这点便是mysqldump需要使用保存点的关键点。

为了更清晰地了解mysqldump在备份过程中使用SAVEPOINT sp + ROLLBACK TO SAVEPOINT sp语句的作用,下面使用两个会话演示一下使用与不使用保存点会发生什么?

从上面的对比结果中可以得知:

  • mysqldump使用savepoint的作用就是,当一个显式开启的事务回滚到保存点时,除了回滚数据变更之外,还会释放保存点之后select语句获取的MDL锁,使得其他会话的DDL语句可以正常执行。对于mysqldump来说,select 语句执行完成之后就代表着该表的数据已经备份完成,无需再继续持有MDL锁,使用savepoint就实现了在select 执行完成之后释放MDL锁的目的(注:在事务内,执行select *语句虽然不会有数据行锁,但是会持有表的MDL锁)。
  • with consistent snapshot子句对应mysqldump实现一致性备份来说至关重要,不仅仅是数据的一致性,使用该子句时,表定义也保持事务开启的那一刻,所以,从上面的对比结果中可以看到,使用了with consistent snapshot子句开启一个一致性快照事务之后,如果一旦表结构定义发生改变,事务将无法重复查询表。
  • 从上面的演示过程中,我们也可以看到,使用 with consistent snapshot子句显式开启一个事务之后,如果该事务没有对任何表做任何操作时,此时是没有获得任何锁的,所以,如果在该事务对某表执行操作之前其他事务对该表执行了DDL操作之后,将导致该事务无法再对表执行查询,会报表结构发生变化的错误;当然,如果显式开启事务后立即对某表执行查询,那么其他会话的DDL是会发生阻塞的;当在该事务使用savepoint实现方式释放表的MDL锁之后,其他会话允许执行DDL,但是执行了DDL语句之后,该事务就无法再对该表执行查询。当然,如果不使用 with consistent snapshot子句,则其他会话执行的DDL对表定义的变更不会影响到该事务重复对表执行查询。

下一篇"mysqldump与innobackupex备份过程你知多少(三)"我们将接着介绍"关于mysqldump的那些坑”,精彩内容不容错过,敬请期待!!

原文发布于微信公众号 - 沃趣科技(woqutech)

原文发表时间:2017-07-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏程序员的SOD蜜

在OQL上使用UPDLOCK锁定查询结果,安全的更新实体数据

SqlServer查询记录的时候提供多种锁定方式,其中UPDLOCK 的优点是允许您读取数据(不阻塞其它事务)并在以后更新数据,同时确保自从上次读取数据后数据没...

961
来自专栏大内老A

谈谈基于Kerberos的Windows Network Authentication[下篇]

六、User2User Sub-Protocol:有效地保障Server的安全 通过3个Sub-protocol的介绍,我们可以全面地掌握整个Kerberos的...

2307
来自专栏杨建荣的学习笔记

通过shell脚本监控日志切换频率 (94天)

在数据库遇到性能问题的时候,可能从io,cpu等角度能够下手找到性能瓶颈,日志的切换也是影响性能的一个因素,如果日志切换台频繁,等待时间就会在日志相关的事件上,...

3468
来自专栏做全栈攻城狮

C#(Net)软件开发常用工具汇总,提高你的开发效率

作为C#语言官方的开发工具,VS的强大只有在多种语言开发工具使用之后,你才会明白VS的强大之处。可谓神器。其中,开发工具尽量选择版本高的。数据库尽量选择版本低的...

1822
来自专栏杨建荣的学习笔记

物化视图prebuilt和在线重定义 (r10笔记第25天)

数据迁移中有一种解决方案很有亮点,如果表的数据量大,迁移涉及的表不多,同时对于维护时间有要求的情况下,物化视图的prebuilt方式就是一种很不错的选择。 大体...

3624
来自专栏java系列博客

pl/sql导入excel到oracle表

2287
来自专栏杨建荣的学习笔记

MySQL中insert语句没有响应的问题分析(r11笔记第21天)

今天开发的一个同学问我一个MySQL的问题,说在测试数据库中执行一条Insert语句之后很久没有响应。我一看语句是一个很常规的insert into xxx ...

36712
来自专栏杨建荣的学习笔记

浅谈MySQL中的事务隔离级别(r11笔记第86天)

之前写了一篇浅谈事务(一),算是对事务的一个基本认识,今天来简单总结一下事务的隔离级别,虽然是老掉牙的知识点,重温一下还是值得的。 在MySQL中基...

3389
来自专栏码农阿宇

利用EF Core的Join进行多表查询

背景 话说有这么一家子,老公养了一条狗,老婆养了一只猫。 数据库的设计 人表 ? 宠物表 ? 通过表可以知道,宠物通过Owner指向主人的Id。 问题来了,我要...

3677
来自专栏magicsoar

C++操作mysql方法总结(2)

C++通过ODBC和通过MFC ODBC操作mysql的两种方式 使用vs2013和64位的msql 5.6.16进行操作 ? 项目中使用的数据库名和表数据请参...

2806

扫码关注云+社区

领取腾讯云代金券