保存点

在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开启的情况下,需考虑如下情况:

如果操作的仅是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锁,从而构成死锁。

如果操作中有非事务引擎,则不能释放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

......

mysql savepoint作用_savepoint原理相关推荐

  1. mysql savepoint语法_SAVEPOINT语法错误一例

    前几天帮同事解决一个案例,在主从复制环境下,从库上的MySQL版本号是5.5.5,遇到下面的错误: ~~~ #其他非相关信息我都隐藏掉了 [(yejr@imysql.com)]> show sl ...

  2. MySQL主从复制作用和原理

    该文章是转载的,但是原文中有些描述的不准确,进行了修改. 一.什么是主从复制? 主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库:主数据库一般是准实时的业务数据库. 二.主从复制的 ...

  3. mysql rollback作用_mysql rollback 原理以及若干疑问

    最近在研究mysql的事务,参考了网上的一些例子写了一些,但是感觉有一点疑问,google后发现还是没找到答案,翻了下源码,还没找到核心关键点,想请大神们,帮忙指个路 1.如果在commit之前发生异 ...

  4. Bundler 的作用及原理

    Bundler 的作用及原理 翻译 · yesmeck · Created at one year ago · Last by teacafe2000 Replied at one year ago  ...

  5. 《深入理解分布式事务》第二章 MySQL 事务的实现原理

    shua# <深入理解分布式事务>第二章 MySQL 事务的实现原理 文章目录 一.Redo Log 1.Redo Log 基本概念 2.Redo Log 基本原理 3.Redo Log ...

  6. mysql+join的原理,Mysql连接join查询原理知识点

    Mysql连接join查询原理知识点 Mysql连接(join)查询 1.基本概念 将两个表的每一行,以"两两横向对接"的方式,所得到的所有行的结果. 假设: 表A有n1行,m1列 ...

  7. Mysql权限系统工作原理(转)

    Mysql权限系统工作原理: MySQL权限系统保证所有的用户可以严格地做他们假定被允许做的事情.当你连接一个MySQL服务器时, 你的身份由你从那连接的主机和你指定的用户名来决定,系统根据你的身份和 ...

  8. MySQL 索引的实现原理

    文章目录 常见索引 哈希索引 平衡二叉树索引 BTree 索引 B+ 树索引 MySQL索引的实现原理 MyISAM索引实现: InnoDB索引实现: 由于索引引起的小思考 索引实现原理小细节 MyS ...

  9. Galera replication for MySQL(包括Galera replication原理)

    Galera replication for MySQL(包括Galera replication原理) 原文  http://www.gpfeng.com/?p=603 转自:http://blog ...

最新文章

  1. 高德渲染网关Go语言重构实践
  2. 开源要“开”得安全高效:开源云计算的五大发展趋势
  3. TCP连接中TIME_WAIT连接过多
  4. DELL本本 执行SQL语句要FN+F5 如何更改成F5
  5. 利用74LS161计数器芯片分别实现模12,模20的计数器,并在QuartusⅡ上进行仿真
  6. ELK学习5_ELK文档资料:《ELK stack 权威指南/饶琛琳》推荐
  7. Android实现ExpandableTextView可扩展TextView
  8. 使用工具分析 SAP UI5 应用前端执行的性能问题
  9. android 渠道号_亲测:安卓打渠道包神器,1分钟出自动出100个渠道包
  10. 高速信号传输约翰逊 pdf_学习笔记之传输线基础
  11. 如何配置android的adb环境变量,如何配置adb环境变量?win7配置adb环境变量的方法...
  12. php与mysql连接程序_PHP与Mysql连接
  13. EF(Entity FrameWork)实体框架
  14. 信息学奥赛一本通C++语言——1024:保留3位小数的浮点数
  15. (10)<label>标签的用途
  16. 【实践篇】推荐系统之矩阵分解模型-腾讯技术
  17. easyui刷新几种方式
  18. 【04】Kubernets:资源清单(pod)
  19. SSM SpringBoot vue高校实训管理系统
  20. Linux搭建FTP服务器

热门文章

  1. 重新解读DDD领域驱动设计(一)
  2. 微软内部全面拥抱开源流程Inner Source
  3. ASP.NET Core 数据加解密的一些坑
  4. 漫谈单体架构与微服务架构(上):单体架构
  5. 【翻译】asp.net core中使用MediatR
  6. 64位的Mac OS X也有Windows.Forms了
  7. 有效事件: 可取代数十种设计模式
  8. .Net大户的选择:Windows Container在携程的应用
  9. Android WebView 图片超出宽度自适应,点击查看大图
  10. linux之lsof和netstat判断端口(port)被哪些应用占用