保存点

在MySQL中, 保存点SAVEPOINT属于事务控制处理部分。利用SAVEPOINT可以回滚指定部分事务,从而使事务处理更加灵活和精细。SAVEPOINT相关的SQL语句如下

SAVEPOINT identifier

设置SAVEPOINT。如果重复设置同名savepoint,新的会覆盖老的.

RELEASE SAVEPOINT identifier

释放SAVEPOINT。

ROLLBACK [WORK] TO [SAVEPOINT] identifier

回滚到指定的SAVEPOINT。

InnoDB内部实现

保存点跟事务有关,因此我们这里只讨论事务引擎InnoDB的savepoint实现。

首先看server层保存点结构:

struct st_savepoint {
struct st_savepoint *prev;
char *name; /* 名字 */
uint length;
Ha_trx_info *ha_list; /* 设置savepoint时已注册的插件 */
/** State of metadata locks before this savepoint was set. */
MDL_savepoint mdl_savepoint;
};

InnoDB层保存点结构:

保存点结构:
struct trx_named_savept_t{
char* name; /*!< savepoint name */
trx_savept_t savept; /*!< the undo number corresponding to
the savepoint */
ib_int64_t mysql_binlog_cache_pos;
/*!< the MySQL binlog cache position
corresponding to this savepoint, not
defined if the MySQL binlogging is not
enabled */
UT_LIST_NODE_T(trx_named_savept_t)
trx_savepoints; /*!< the list of savepoints of a
transaction */
}; 链表存储事务上的所有保存点:
trx_t
{
UT_LIST_BASE_NODE_T(trx_named_savept_t)
trx_savepoints;
…….
} 保存点最重要的信息,事务回滚日志的序号:
struct trx_savept_t{
undo_no_t least_undo_no; /*!< least undo number to undo */
};

SAVEPOINT与UNDO日志

事务回滚通过回滚UNDO日志来实现,同样,回滚至保存点也是通过应用UNDO日志来实现。

InnoDB事务在每次修改操作时都会记录UNDO日志,参见函数trx_undo_report_row_operation,每次操作都会记录UNDO日志序号记为undo_no,每次操作undo_no都会递增。回滚只需要反向应用UNDO日志即可。 SAVEPOINT与undo_no是一一对应的。

create table t1(c1 int primary key);
begin;
insert into t1 values(1);
savepoint a;
insert into t1 values(2);
savepoint b;
insert into t1 values(3);
rollback to savepoint a;
commit;

SAVEPOINT与BINLOG

InnoDB开启binlog的情况下,savepoint回滚的那段操作不应记录binlog. 我们知道,事务执行过程中产生的binlog先写入cache中,提交时再将cache中的数据写binlog文件中。 然而,savepoint回滚时,binlog还在cache中,那么被回滚的那段操作的binlog需要从cache中清理掉。

设置savepoint时,记录binlog在cache中起始位置。

trans_savepoint
->ha_savepoint
->binlog_savepoint_set
->binlog_trans_log_savepos

回滚至savepoint时,从保存的起始位置清理cache

trans_rollback_to_savepoint
->ha_rollback_to_savepoint
->binlog_savepoint_rollback
->binlog_trx_cache_data::restore_savepoint
->binlog_cache_data::truncate
->reinit_io_cache

SAVEPOINT与锁

回滚保存点以后,此保存点以后的保存点都会释放,但此保存点以后InnoDB层操作加的锁不会释放。这里不释放锁,是为了不破坏两阶段锁协议,减少死锁的发生。

而对于MDL(metadate lock)锁,在binlog关闭的情况下可以提前释放。 而binlog开启的情况下,需考虑如下情况:

  1. 如果操作的仅是InnoDB表且InnoDB层没有加锁,则MDL锁可以释放,否则,不能释放。 InnoDB层持有锁,如果释放MDL可能出现死锁。考虑如下情况: trx 1: rollback to savepoint xxx; InnoDB层持有t1的行锁,释放t1的MDL trx 2: 操作t1; 持有t1的MDL, 等待t1行锁 trx 1: 再次操作t1; 等待t1的MDL锁,从而构成死锁。

  2. 如果操作中有非事务引擎,则不能释放MDL锁。 如果是非事务引擎,例如t1为MyiSAM表。 ... begin; insert into t1 values(1); savepoint a; insert into t1 values(2); rollback to savepoint a; commit; ... savepoint和rollback to savepoint之间的sql都会写入binlog. 如果提前释放MDL,其他会话drop table t1可以成功,这样会导致应用binlog时,执行insert into t1 values(2);会找不到表t1。

SAVEPOINT作用域

官方文档 中,store function和trigger会重新开启新的savepoint作用域, store function和trigger完成后老的savepoint作用域重新可用。

A new savepoint level is created when a stored function is invoked or a trigger is activated. The savepoints on previous levels become unavailable and thus do not conflict with savepoints on the new level. When the function or trigger terminates, any savepoints it created are released and the previous savepoint level is restored.

delimiter //
drop procedure if exists p1//
create procedure p1()
begin
release savepoint a;
end//
delimiter ; begin;
savepoint a;
call p1();
rollback to savepoint a;
ERROR 1305 (42000): SAVEPOINT a does not exist

从结果来看与官方文档描述并不一致。

实际从代码中上看,stored function和trigger并没有开启独立的事务,而是与调用着共用同一事务。savepoint都在同一事务的链表中,因此store function和trigger中的savepoint作用域和调用者相同。

官方对savepoint的实现并不彻底。

匿名SAVEPOINT

实际上,InnoDB事务中每个语句执行前都会记录一个匿名savepoint;如果当前语句执行失败,不会回滚整个事务,而是利用这个匿名savepoint回滚失败的语句。

struct trx_t{
trx_savept_t last_sql_stat_start; //匿名savepoint
......

savepoint原理的更多相关文章

  1. [Flink原理介绍第四篇】:Flink的Checkpoint和Savepoint介绍

    原文:https://blog.csdn.net/hxcaifly/article/details/84673292 https://blog.csdn.net/zero__007/article/d ...

  2. mysqldump和xtrabackup备份原理实现说明

    背景: MySQL数据库备份分为逻辑备份和物理备份两大类,犹豫到底用那种备份方式的时候先了解下它们的差异: 逻辑备份的特点是:直接生成SQL语句,在恢复的时候执行备份的SQL语句实现数据库数据的重现. ...

  3. mysqldump的实现原理

    对于MySQL的备份,可分为以下两种: 1. 冷备 2. 热备 其中,冷备,顾名思义,就是将数据库关掉,利用操作系统命令拷贝数据库相关文件.而热备指的是在线热备,即在不关闭数据库的情况下,对数据库进行 ...

  4. 深入理解 Spring 事务原理

    本文由码农网 – 吴极心原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 一.事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供 ...

  5. 深入理解 Spring 事务原理【转】

    本文转自码农网 – 吴极心原创  连接地址:http://www.codeceo.com/article/spring-transactions.html 一.事务的基本原理 Spring事务的本质其 ...

  6. MySQL事务原理&实战【官方精译】

    事务隔离级别 事务隔离是数据库处理的基础之一.隔离是I中的首字母 ACID ; 隔离级别是在多个事务同时进行更改和执行查询时,对结果的性能和可靠性,一致性和可重复性之间的平衡进行微调的设置. Inno ...

  7. Flink 集群运行原理兼部署及Yarn运行模式深入剖析

    1 Flink的前世今生(生态很重要) 原文:https://blog.csdn.net/shenshouniu/article/details/84439459 很多人可能都是在 2015 年才听到 ...

  8. java事务 深入Java事务的原理与应用

    一.什么是JAVA事务 通常的观念认为,事务仅与数据库相关. 事务必须服从ISO/IEC所制定的ACID原则.ACID是原子性(atomicity).一致性(consistency).隔离性 (iso ...

  9. spring事务-说说Propagation及其实现原理

    前言 spring目前已是java开发的一个事实标准,这得益于它的便利.功能齐全.容易上手等特性.在开发过程当中,操作DB是非常常见的操作,而涉及到db,就会涉及到事务.事务在平时的开发过程当中,就算 ...

随机推荐

  1. 2-3. Using Type Deduction

    Type Deduction 发生在编译时期 可以对一般类型,自定义类型进行类型自推导 下面有两个例子: 1. Using auto with a class #include <iostrea ...

  2. 如何查看SharePoint未知错误的详细信息

    在sharepoint 开发的时候,需要查看具体的sharepoint报错信息需要在配置文件中配置如下 通过下面方法就可以直接在出错页面查看错误信息.修改Web应用程序根目录上的Web.config文 ...

  3. windows 8.1 下蓝屏报错:SYSTEM_SERVICE_EXCEPTION(NETIO.SYS)的解决办法

         大概2周前,电脑突然蓝屏了,我上网查了一下解决办法,因为大部分内容是英文的,所以我只大概看了下,看到这个问题好像是由于软件冲突造成的,于是就把小红伞去掉了,而那天电脑也真的没有再蓝屏(之前大 ...

  4. Winform打砖块游戏制作step by step第6节---双缓冲应用

    一 引子 为了让更多的编程初学者,轻松愉快地掌握面向对象的思考方法,对象继承和多态的妙用,故推出此系列随笔,还望大家多多支持. 二 本节内容---双缓冲应用 1.  主界面截图如下: 2.  什么是双 ...

  5. jQueryAjax笔记

    ajax优点:能在不刷新整个页面的前提下更新数据,使用户操作与服务器响应异步化. ajax缺点:破坏浏览器“前进”.“后退”按钮的正常功能,搜索引擎爬虫不能理解那些奇怪的JS代码和因此引起的页面内容的 ...

  6. 解决PKIX(PKIX path building failed) 问题 unable to find valid certification path to requested target

    最近在写java的一个服务,需要给远程服务器发送post请求,认证方式为Basic Authentication,在请求过程中出现了 PKIX path building failed: sun.se ...

  7. 【转】Nginx服务器详细配置含注释

    #使用的用户和组 user www www; #指定工作衍生进程数(一般等于CPU的总核数或总核数的两倍) worker_processes 8; #指定错误日志存放的路径,错误日志的记录级别可为de ...

  8. s1=s1+1与s1+=1的区别

    刚看到一面试题,题目是这样的:short s1=1;s1=s1+1;有什么错?short s1=1;s1+=1;有什么错? 初看之下就是s1=s1+1和s1+=1的区别.在开发中我们基本上是使用后一种 ...

  9. 配置Chrome Driver

    书中使用Firefox driver出现莫名问题,大概是firefox的版本太新了,懒得降级处理,故学习配置Chome driver进行测试. 1.到http://chromedriver.stora ...

  10. MySQL数据库安装与配置详解

    转载提示:在原文http://www.cnblogs.com/sshoub/p/4321640.html基础上修改. 目录 一.概述 二.MySQL安装 三.安装成功验证 四.NavicatforMy ...