前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >1.Mysql 事务处理过程

1.Mysql 事务处理过程

原创
作者头像
马说
修改2020-10-29 17:49:06
1.2K0
修改2020-10-29 17:49:06
举报
文章被收录于专栏:Java 汇总

源自https://dev.mysql.com/doc/internals/en

每个访问事务表 都会启动一个statement事务。如果语句成功,则提交statement事务。如果语句失败,则回滚事务。statement事务的提交是不持久的——每个statement事务都嵌套在normal事务中,如果回滚normal事务,被包含的statement事务所影响的数据也会被撤销。在 autocommit  自动提交模式下,normal事务与statement事务等价。

     由于MySQL支持可插拔存储引擎体系结构(PSEA),一次可能有多个事务引擎处于活动状态。所以从 服务器 的角度来看,事务总是 分布式 的。每个引擎的事务状态在MYSQL中是独立的。为了提交事务,MySQL使用 两阶段提交(two-phase commit)协议。      并非所有语句都在事务上下文中执行。管理和状态信息语句不会修改引擎数据,因此它们不会启动语句事务,也不会影响正常事务。例如SHOW STATUS和RESET SLAVE。类似地,DDL语句不是事务性的,因此(几乎)从来没有为DDL语句启动事务。但是DDL语句和管理语句之间有一个区别:DDL语句总是在继续之前提交当前事务(如果有),而管理语句则不会。


数据结构:       MySQL将其与事务相关的数据存储在 thd->transaction 中。这个结构有两个THD_TRANS 类型的成员变量:     thd->transaction.stmt 保存着参与执行语句的存储引擎列表;     thd->transaction.all  包含参与normal 事务上下文中的 任意 statement 事务的存储引擎列表,每个元素包含:存储引擎的指针、engine-specific transactional data、 engine-specific transaction flags.

在autocommit模式下,thd->transaction.all 是空的,thd->transaction.stmt被用于提交/回滚normal事务;每个存储引擎只会在列表中注册一次,并且以栈(先进后出)的方式放入list中。


事务的生命周期:     当建立新连接时,thd->transaction成员被初始化为空状态。如果语句使用到了任何表,则所有受影响的引擎都将注册到statement engine list 中。在非自动提交(non-autocommit)模式下,相同的存储引擎注册在normal transaction list中。在语句末尾,服务器对statement list中的所有引擎发出提交或回滚。此时,引擎的事务标志(如果有)将从statement list传播到normal transaction list。提交/回滚完成后,statement list将被清除。它将被下一个语句再次填充,并在下一个语句结束时再次清空。     在normal事务提交后,thd->transaction.all list 被清空;在connection 关闭后,当前未完成的normal 事务被回滚。     normal transaction 以相似的方式提交:         1.用户发送  SQL COMMIT 语句          2.当服务器开始处理DDL语句或SET AUTOCOMMIT={0|1}语句时     normal transaction 回滚:         1.发送rollback 语句         2.参与执行sql的引擎,如果其中某个引擎发送了rollback 请求,通过设置thd->transaction_rollback_request

        在提交transaction时,服务器要么使用两阶段提交协议,要么在每个引擎中独立地发出一个提交。只有在以下情况下,服务器才使用两阶段提交协议:     1.所有参与引擎都支持两阶段提交,通过调用 handlerton::prepare 方法     2.事务至少在两个存储引擎中修改了数据。 请注意,两阶段提交用于statement transaction,即使语句事务无论如何都不是持久的。这确保了多引擎事务中数据的逻辑一致性。  normal transaction 提交后,thd->transaction.all list 被清空。  当连接关闭,当前的normal transaction 被 回滚


        服务器使用一种方法可以知道一个引擎参与执行语句,并且一个事务已经在引擎中启动。为了成为执行事务中的一部分,存储引擎必须注册自己,通过调用trans_register_ha()方法;通常情况下,存储引擎每当调用handler::external_lock() 时,都会注册自己(trans_register_ha 方法,内嵌在external_lock方法中被调用的),如果autocommit 未设置,则存储引擎需要在statement list 和normal transaction list中注册自己。         在语句执行期间,只要使用了data-modifying PSEA 方法,则 read-write flag 就会被标记,这样 服务器 会知道存储引擎中修改了数据,并执行两阶段提交。在语句的结尾,会调用ha_autocommit_or_rollback()方法,转而调用 handlerton::prepare() 方法,事务提交后,注册列表将清空。         在statement 结尾会调用 ha_autocommit_or_rollback() 方法,服务器对每个涉及到的存储引擎 调用handlerton::prepare()方法,在此之后又会调用handlerton::commit_one_phase()方法,如果 one-phase commit 单阶段提交就足够了,则不会调用handlerton::prepare(),服务器只调用handlerton::commit_one_phase()。在语句提交时,与语句相关的读写引擎标志将传播到normal事务中对应的flag 。提交完成后,将清除已注册引擎的列表。


        具有非事务引擎的DDL语句和操作 不会在thd->transaction list 中“注册”,因此不会修改事务状态。此外,MySQL中的每个DDL语句都以一个隐式的正常事务提交开始,因此没有任何内容需要修改。但是,CREATE TABLE。。SELECT,一些DDL语句会启动一个 新的 事务。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档