ROLLBACK TO SAVEPOINT 语句的作用是将事务回滚到指定的保存点的位置,而不终止事务。当前事务在回滚点之后的修改的行数据将被撤销(注:InnoDB不会释放这些发生修改且被撤销行的行锁,注意是修改,不是新插入,这些发生修改的数据行行锁被存储在内存中),对于设置了保存点之后,新插入的行数据也会被撤销(注:这些锁信息被存储在行数据中的事务ID上,这些行锁不会单独存储在内存中,在这种情况下,这些新插入的行数据在被回滚之后,对应的行锁将被释放)。另外,回滚到某个保存点之后,比这个保存点在时间上更晚设置的保存点将被删除。
ROLLBACK TO SAVEPOINT 语句还有一个作用,可以释放在设置保存点之后事务持有的MDL锁,这点便是mysqldump需要使用保存点的关键点。
为了更清晰地了解mysqldump在备份过程中使用SAVEPOINT sp + ROLLBACK TO SAVEPOINT sp语句的作用,下面使用两个会话演示一下使用与不使用保存点会发生什么?
with consistent snapshot子句对应mysqldump实现一致性备份来说至关重要,不仅仅是数据的一致性,使用该子句时,表定义也保持事务开启的那一刻,所以,从上面的对比结果中可以看到,使用了with consistent snapshot子句开启一个一致性快照事务之后,如果一旦表结构定义发生改变,事务将无法重复查询表。
从上面的演示过程中,我们也可以看到,使用 with consistent snapshot子句显式开启一个事务之后,如果该事务没有对任何表做任何操作时,此时是没有获得任何锁的,所以,如果在该事务对某表执行操作之前其他事务对该表执行了DDL操作之后,将导致该事务无法再对表执行查询,会报表结构发生变化的错误;当然,如果显式开启事务后立即对某表执行查询,那么其他会话的DDL是会发生阻塞的;当在该事务使用savepoint实现方式释放表的MDL锁之后,其他会话允许执行DDL,但是执行了DDL语句之后,该事务就无法再对该表执行查询。当然,如果不使用 with consistent snapshot子句,则其他会话执行的DDL对表定义的变更不会影响到该事务重复对表执行查询。