在双1的情况下,两阶段提交的过程

环境准备:mysql 5.5.18, innodb 1.1 version

配置:

sync_binlog=1

innodb_flush_log_at_trx_commit=1

autocommit=0

设置断点:

sql_parse.cc::dispatch_command --命令跳转入口

sql_parse.cc::mysql_parse

sql_parse.cc::mysql_execute_command

sql_parse.cc::trans_commit_stmt --语句commit入口

handler.cc::ha_commit_trans --commit入口

log.cc::binlog_prepare --binlog prepare入口

Ha_innodb.cc::innobase_xa_prepare --innodb prepare入口

log.cc::binlog_commit--binlog commit入口

Ha_innodb.cc::innobase_commit--innodb commit入口

实验步骤

步骤1:

1 usetest;2 create table xpchild(id int auto_increment primary key, name varchar(100));3 insert into xpchild(1,'xpchild');

步骤1过程:

1. dispatch_command:

command= COM_QUERY

inc_thread_running():增加thread running

statistic_increment:增加计数

switch (command):跳转命令

2. mysql_execute_command:

解析命令为:SQLCOM_INSERT

3. mysql_insert:

跳转到真正的insert

bool log_on= (thd->variables.option_bits & OPTION_BIN_LOG):判断是否打开了binlog

open_and_lock_tables(thd, table_list, TRUE, 0):打开table并锁表

4. trans_commit_stmt:

语句级别的提交

if (thd->transaction.stmt.ha_list)

res= ha_commit_trans(thd, FALSE);

针对语句所有参与的引擎进行提交, 但这里all的参数是false,说明是语句的提交动作,而非真正的事务commit。

5. ha_commit_trans:

这里trans=all ? &thd->transaction.all : &thd->transaction.stmt,说明是stmt的transaction。

ha_check_and_coalesce_trx_read_only:判断事务是否需要两阶段提交

for (Ha_trx_info *hi= ha_info; hi; hi= hi->next())

一共有两个引擎参与:binlog&&innodb

进入prepare阶段:

5.1. binlog_prepare:

直接返回什么也没有做

5.2. innobase_xa_prepare:

all参数是false,innodb认为是语句级别的提交,就只做如下的事情:

row_unlock_table_autoinc_for_mysql(trx);释放语句hold的auto_increment锁

trx_mark_sql_stat_end(trx);记录本语句的undo信息,以便语句级的回滚

进入提交阶段:

commit_one_phase_low(thd, all, trans, is_real_trans);

5.3. binlog_commit

只是cache了statement的binlog,没有做flush操作

5.4. innobase_commit

row_unlock_table_autoinc_for_mysql(trx);释放了自增锁

trx_mark_sql_stat_end(trx);记录本语句的undo信息

这个地方做的事情和prepare阶段一样,多做虽然没有坏处,但也没有看到有什么意义

srv_active_wake_master_thread:给主线程发信号唤醒,就结束

6. close_thread_tables(thd)

在mysql_execute_command中close table,然后这次命令就结束了。

步骤2:

commit

1. 前面的步骤都相似:

mysql_execute_command函数中跳转到trans_commit进行真正的提交。

2. ha_commit_trans

进入commit函数,传入参数all=true,为真正的提交动作。

检查rw_ha_count= ha_check_and_coalesce_trx_read_only(thd, ha_info, all)

rw_ha_count=2 代表binlog引擎和innodb引擎

is_real_trans=true

进入两阶段提交过程:

3. binlog_prepare:

直接return 0;

4. innobase_xa_prepare:

trx_prepare_off_kernel:

mutex_enter(&(rseg->mutex));锁住undo segment的mutex

trx_undo_set_state_at_prepare;设置这个insert语句所对应的undo的状态从TRX_UNDO_ACTIVE-》TRX_UNDO_PREPARED。

mutex_exit(&(rseg->mutex));释放mutex

mtr_commit(&mtr): 对于本次的内存更改,因为非原子操作,所以也对应一个提交动作

lsn = mtr.end_lsn:或者最后的lsn后,flush的时候要保证大于或者等于lsn。

if flush_log_at_trx_commit=1

log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE); 参数flush_to_disk=true表示flush log到disk中。

5. tc_log->log_and_order:这里做了大部分的commit的工作,包括:

binlog_commit_flush_trx_cache:刷新binlog到disk

TC_LOG::run_commit_ordered:

对binlog进行group commit操作

innodb::innobase_commit_ordered:

trx_commit_off_kernel:

标记事务为TRX_COMMITTED_IN_MEMORY,

如果是insert undo,直接purge掉。

trx->flush_log_later=true,所以这里并不进行flush,只是记录了commit的lsn,flush的动作放在了提交阶段。

trx_roll_free_all_savepoints:释放所有的save_point.

事务的标记最终为: trx->conc_state = TRX_NOT_STARTED

进入最终提交阶段:

commit_one_phase_low(thd, all, trans, is_real_trans):

binlog_commit:这里貌似什么都没有做,直接进入

if (cache_mngr->trx_cache.empty())

cache_mngr->reset_cache(&cache_mngr->trx_cache)

所以binlog commit并不是真正flush log的地方,而是在ha_commit_trans函数中,完成prepare过程后,commit提交前做了:

cookie= tc_log->log_and_order(thd, xid, all, need_commit_ordered);

所以,其实binlog已经提交了,只不过位置不在这里,不过,不妨碍一致性,因为都是在一阶段完成后。

innobase_commit:

trx_commit_complete_for_mysql:

log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE);刷新log到disk中,这里的lsn是commit_lsn.

到这里commit完整结束。

提交mysql代码_MySQL源码之两阶段提交相关推荐

  1. 源码安装mysql主从_mysql源码安装和主从同步配置

    mysql源码安装和主从同步配置 mysql介绍: MySQL 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性.MySQL ...

  2. flink的mysql两阶段提交_flink 两阶段提交

    flink exactly-once系列目录: 一.两阶段提交概述 二.TwoPhaseCommitSinkFunction与FlinkKafkaProducer源码分析 三.StreamingFil ...

  3. mysql之两阶段提交

    什么是两阶段提交 当有数据修改时,会先将修改redo log cache和binlog cache然后在刷入到磁盘形成redo log file,当redo log file全都刷入到磁盘时(prep ...

  4. 两阶段提交实际项目V1

    项目介绍 两阶段提交项目主要是实际用代码演示复现一下,两阶段提交的执行过程,仅供学习参考.本次主要分析的版本为V1版本,主要实现的流程包括服务端的基础架构编写,客户端的基础架构编写,完成事务提交的过程 ...

  5. 关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究[转]

    1.XA XA是由X/Open组织提出的分布式事务的规范.XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接 ...

  6. 关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究[转]...

    1.XA XA是由X/Open组织提出的分布式事务的规范.XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接 ...

  7. 浅谈两阶段提交和三阶段提交

    本文主要分为三个部分 第一部分阐述两阶段提交的原理和优缺点. 第二部分阐述三阶段提交的原理和优缺点. 第三部分阐述如何解决业务中最终一致性的问题. 一.两阶段提交 两阶段提交方法是用于分布式事务中用来 ...

  8. 关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究

    本文原文连接: http://blog.csdn.net/bluishglc/article/details/7612811 ,转载请注明出处! 1.XA XA是由X/Open组织提出的分布式事务的规 ...

  9. 关于分布式事务 两阶段提交 一阶段提交 Best Efforts 1PC模式和事务补偿机制的研究

    本文原文连接: http://blog.csdn.net/bluishglc/article/details/7612811 ,转载请注明出处! 1.XA XA是由X/Open组织提出的分布式事务的规 ...

最新文章

  1. mysql 客户端提示“Cannot proceed because system tabl...
  2. AU3学习案例----------考勤机手工补卡
  3. es6+的javascript拓展内容
  4. MCU实战经验:多种的按键处理
  5. unittest ResourceWarning: unclosed socket.socket fd=864, family=AddressFamily.AF_INET... 解决办法...
  6. 如何学习linux设备驱动
  7. 博客文章列表(一)——JAVA
  8. zepto为什么不支持animate,报animate is not a function
  9. atitit.极光消息推送服务器端开发实现推送  jpush v3. 总结o7p
  10. c语言加减乘除怎么随机输入,注会机考加减乘除如何输入,注会机考加减乘除如何输入...
  11. Qt 6.2的下载和安装
  12. Java之旅-Day3
  13. crc16modbus查表法_分别用定义法和查表法求取MODBUS_CRC16的值
  14. iOS UIAppearance使用详解
  15. 试题 算法训练 24点 蓝桥杯 Java
  16. opencv-python 详解阈值分割
  17. Facebook再现丑闻,约100位应用程序开发人员偷看用户数据
  18. jqgrid使用分析
  19. /MD /MDd /MT /MTd
  20. 一文读懂PCA算法的数学原理

热门文章

  1. JGroups 入门实践(转)
  2. class.forname().newInstance()
  3. ESFramework介绍之(16)―― Tcp数据自动发送器ITcpAutoSender
  4. 6、 restful API
  5. 「mysql优化专题」高可用性、负载均衡的mysql集群解决方案(12)
  6. 邓侃:深度强化学习“深”在哪里?
  7. Kendo UI开发教程(23): 单页面应用(一)概述
  8. dojo Quick Start/dojo入门手册--package机制
  9. “影响100活动”答记者问(二)
  10. java jdk 1.8 配置_java_Day01: java的jdk环境变量配置(1.8)