MySQL作为一种关系型数据库,已被广泛应用到互联网中的诸多项目中。今天我们来讨论下事务的提交过程。

MySQL体系结构

由于mysql插件式存储架构,导致开启binlog后,事务提交实质是二阶段提交,通过两阶段提交,来保证存储引擎和二进制日志的一致。

本文仅讨论binlog未打卡状态下的提交流程,后续会讨论打开binlog选项后的提交逻辑。

测试环境

OS:WIN7

ENGINE:

bin-log:off

DB:

测试条件

set autocommit=0;
-- ------------------------------ Table structure for `user`-- ----------------------------DROP TABLE IF EXISTS `user`;CREATE TABLE `user` (`id` int(20) NOT NULL,`account` varchar(20) NOT NULL,`name` varchar(20) NOT NULL,PRIMARY KEY (`id`),KEY `id` (`id`) USING BTREE,KEY `name` (`name`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8;

测试语句

insert into user values(1, 'sanzhang', '张三');
commit;

一般常用的DML:Data Manipulation Language 数据操纵语言,对表的数据进行操作,(insert、update、delete )语句 和 DCL:Data Control Language 数据库控制语言

(创建用户、删除用户、授权、取消授权)语句 和 DDL:Data Definition Language 数据库定义语言,对数据库内部的对象进行创建、删除、修改的操语句

,均是使用MySQL提供的公共接口mysql_execute_command,来执行相应的SQL语句。我们来分析下mysql_execute_command接口执行的流程:

mysql_execute_command{   switch (command)   {       case SQLCOM_INSERT:                mysql_insert();                break;       case SQLCOM_UPDATE:                mysql_update();                break;       case SQLCOM_DELETE:                mysql_delete();                break;       ......   }   if thd->is_error()  //语句执行错误     trans_rollback_stmt(thd);  else    trans_commit_stmt(thd);}

从上述流程中,可以看到执行任何语句,最后都会执行trans_rollback_stmt或者trans_commit_stmt,这两个分别是语句回滚和语句提交。

语句提交,对于非自动模式下,主要有两个作用:

1、释放autoinc锁,这个锁主要用来处理多个事务互斥的获取自增序列。因此,无论最后执行的是语句提交还是语句回滚,该资源都是需要立马释放掉的。

2、标识语句在事务中的位置,方便语句级回滚。执行commit后,可以进入commit流程。

现在看下具体的事务提交流程:

mysql_execute_commandtrans_commit_stmtha_commit_trans(thd, FALSE);{    TC_LOG_DUMMY:ha_commit_low        ha_commit_low()               innobase_commit            {                //获取innodb层对应的事务结构                trx = check_trx_exists(thd);                if(单个语句,且非自动提交)                {                     //释放自增列占用的autoinc锁资源                     lock_unlock_table_autoinc(trx);                     //标识sql语句在事务中的位置,方便语句级回滚                     trx_mark_sql_stat_end(trx);                }                else 事务提交                {                     innobase_commit_low()                     {                          trx_commit_for_mysql();                            trx_commit(trx);                      }//确定事务对应的redo日志是否落盘【根据flush_log_at_trx_commit参数,确定redo日志落盘方式】                    trx_commit_complete_for_mysql(trx);trx_flush_log_if_needed_low(trx->commit_lsn);log_write_up_to(lsn);                }            }}
trx_commit    trx_commit_low        {            trx_write_serialisation_history            {                trx_undo_update_cleanup //供purge线程处理,清理回滚页            }            trx_commit_in_memory            {                lock_trx_release_locks //释放锁资源                trx_flush_log_if_needed(lsn) //刷日志                trx_roll_savepoints_free //释放savepoints            }        }

MySQL是通过WAL方式,来保证数据库事务的一致性和持久性,即ACID特性中的C(consistent)和D(durability)。

WAL(Write-Ahead Logging)是一种实现事务日志的标准方法,具体而言就是:

1、修改记录前,一定要先写日志;

2、事务提交过程中,一定要保证日志先落盘,才能算事务提交完成。

通过WAL方式,在保证事务特性的情况下,可以提高数据库的性能。

从上述流程可以看出,提交过程中,主要做了4件事情,

1、清理undo段信息,对于innodb存储引擎的更新操作来说,undo段需要purge,这里的purge主要职能是,真正删除物理记录。在执行delete或update操作时,实际旧记录没有真正删除,只是在记录上打了一个标记,而是在事务提交后,purge线程真正删除,释放物理页空间。因此,提交过程中会将undo信息加入purge列表,供purge线程处理。

2、释放锁资源,mysql通过锁互斥机制保证不同事务不同时操作一条记录,事务执行后才会真正释放所有锁资源,并唤醒等待其锁资源的其他事务;

3、刷redo日志,前面我们说到,mysql实现事务一致性和持久性的机制。通过redo日志落盘操作,保证了即使修改的数据页没有即使更新到磁盘,只要日志是完成了,就能保证数据库的完整性和一致性;

4、清理保存点列表,每个语句实际都会有一个savepoint(保存点),保存点作用是为了可以回滚到事务的任何一个语句执行前的状态,由于事务都已经提交了,所以保存点列表可以被清理了。

关于mysql的锁机制,purge原理,redo日志,undo段等内容,其实都是数据库的核心内容。

MySQL 本身不提供事务支持,而是开放了存储引擎接口,由具体的存储引擎来实现,具体来说支持 MySQL 事务的存储引擎就是 InnoDB。

存储引擎实现事务的通用方式是基于 redo log 和 undo log。

简单来说,redo log 记录事务修改后的数据, undo log 记录事务前的原始数据。

所以当一个事务执行时实际发生过程简化描述如下:

  1. 先记录 undo/redo log,确保日志刷到磁盘上持久存储。
  2. 更新数据记录,缓存操作并异步刷盘。
  3. 提交事务,在 redo log 中写入 commit 记录。

在 MySQL 执行事务过程中如果因故障中断,可以通过 redo log 来重做事务或通过 undo log 来回滚,确保了数据的一致性。

这些都是由事务性存储引擎来完成的,但 binlog 不在事务存储引擎范围内,而是由 MySQL Server 来记录的。

那么就必须保证 binlog 数据和 redo log 之间的一致性,所以开启了 binlog 后实际的事务执行就多了一步,如下:

  1. 先记录 undo/redo log,确保日志刷到磁盘上持久存储。
  2. 更新数据记录,缓存操作并异步刷盘。
  3. 将事务日志持久化到 binlog。
  4. 提交事务,在 redo log 中写入commit记录。

这样的话,只要 binlog 没写成功,整个事务是需要回滚的,而 binlog 写成功后即使 MySQL Crash 了都可以恢复事务并完成提交。

要做到这点,就需要把 binlog 和事务关联起来,而只有保证了 binlog 和事务数据的一致性,才能保证主从数据的一致性。

所以 binlog 的写入过程不得不嵌入到纯粹的事务存储引擎执行过程中,并以内部分布式事务(xa 事务)的方式完成两阶段提交。

列表数据提交_MySQL事务提交过程(一)相关推荐

  1. mysql 提交_MySQL 事务提交过程

    开发老大要求通过binlog查询一条被修改的数据,数据被查出后问我,有没有可能binlog中不会记录,回答不会,因为数据被修改,若失败直接回滚,不会在binlog中记录,此刻一个朋友用了洪荒之力告诉我 ...

  2. linux mysql提交_MySQL 事务提交过程

    开发老大要求通过binlog查询一条被修改的数据,数据被查出后问我,有没有可能binlog中不会记录,回答不会,因为数据被修改,若失败直接回滚,不会在binlog中记录,此刻一个朋友用了洪荒之力告诉我 ...

  3. mysql事务回滚是什么意思_Mysql事务提交及事务回滚是什么意思

    本篇文章主要给大家介绍mysql事务提交及事务回滚的相关知识. 事务可以说是一段sql 语句的批处理,但是这个批处理是一个atom(原子) ,不可分割,要么都提交执行,要么回滚(rollback)都不 ...

  4. mysql 提交事务_MySQL事务提交过程

    一.MySQL事务提交过程(一) MySQL作为一种关系型数据库,已被广泛应用到互联网中的诸多项目中.今天我们来讨论下事务的提交过程. 由于mysql插件式存储架构,导致开启binlog后,事务提交实 ...

  5. Oracle数据库事务回滚和提交,数据库 事务提交和回滚

    事务  -  (transaction / tx) 原子性操作性(不可以分割的操作) - 要么全做, 要么全不做 事务的特点  -  ACID 特性 A - atomicity  原子性 : 不可分割 ...

  6. java spring 事务提交_Spring 事务提交之后再执行操作

    Spring代码实现: import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.ster ...

  7. mysql 设置事物自动提交_mysql事务自动提交的问题

    1:mysql的aut0commit配置默认是开启的,也就是没执行一条sql都会提交一次,就算显示的开启事务也会导致多条SQL不在一个事务中, 如果需要相关的SQL在同一个事务中执行,那么必须将aut ...

  8. mysql回滚与错误提示_对mysql事务提交、回滚的错误理解 – jae – 博客园

    一.起因 begin或者START TRANSACTION开始一个事务 rollback事务回滚 commit 事务确认 人们对事务的解释如下:事务由作为一个单独单元的一个或多个 这句话本身没有什么问 ...

  9. 修改数据无法提交_MySQL数据库精讲:一文讲解MySQL事务隔离!

    欢迎关注专栏<Java架构筑基>--专注于Java技术的研究与分享! Java架构筑基​zhuanlan.zhihu.com Java架构筑基--专注于Java技术的研究与分享! 后续文章 ...

最新文章

  1. 尚硅谷学习:createElement 方法笔记
  2. Android stadio 自定义debug release keystore
  3. mysql表误删回复_mysql 找回误删表的数据方法(必看)
  4. iOS开发技术之微信支付
  5. [BZOJ5292][BJOI2018]治疗之雨(概率DP+高斯消元)
  6. C#四种相等性判断方法 equals,referenceEquals
  7. hive 去重 字符串_hive函数
  8. Webpack实战(六):如何优雅地运用样式CSS预处理
  9. 使用Android OpenGL ES 2.0绘图之四:应用投影和相机视图
  10. webgl存本地文件_20万存款该怎么存?银行员工:这样存,每年利息近万元!
  11. Vue源码解析:Vue实例
  12. Python 使用Selenium 爬取Linkedin领英数据
  13. python中求绝对值的函数_python如何取绝对值 python取绝对值方法
  14. 台式计算机不同处理器型号,买电脑不要再被坑了,CPU型号解读
  15. revit二开之关联族参数的实现
  16. 混乱是怎样炼成的——《C解毒》试读
  17. 解决Win10锁屏超1分钟,显示器关闭问题
  18. java.lang.UnsatisfiedLinkError: C:\Users\Administrator\AppData\Local\Temp\2\librocksdbjni91
  19. php中文网教程 百度云,网盘直链问题请教
  20. 坚守天门 1.0版 发布

热门文章

  1. 1024 程序员节岳麓对话即将开启,院士、掌门人开谈论道,话技术、聊人才、畅未来
  2. 期货长线交易资金管理(浮赢加仓)?
  3. Mastercam2022程序单升级版
  4. 多国语言实时翻译工具Mate Translate中文版
  5. linux下docker安装taiga
  6. batch-size选取
  7. 菜鸟也想玩搜索引擎——爬虫部分技术要点浅析
  8. TPS65983ACZQZR USB Type-C 控制器和553SDCGI8时钟缓冲器、SLB9665TT2.0应用说明
  9. stm32f的一些问题
  10. EAS系统管理特训营