千家信息网

MySQL事务的提交过程

发表于:2024-11-24 作者:千家信息网编辑
千家信息网最后更新 2024年11月24日,本篇内容介绍了"MySQL事务的提交过程"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!MySQL事务
千家信息网最后更新 2024年11月24日MySQL事务的提交过程

本篇内容介绍了"MySQL事务的提交过程"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

MySQL事务提交过程
开启binlog后事务提交流程会变成两阶段提交,这里的两阶段提交并不涉及分布式事务,当然mysql把它称之为内部xa事务(Distributed Transactions),与之对应的还有一个外部xa事务。


这里所谓的两阶段提交分别是prepare阶段和commit阶段。


内部xa事务主要是mysql内部为了保证binlog与redo log之间数据的一致性而存在的,这也是由其架构决定的(binlog在mysql层,而redo log 在存储引擎层);


外部xa事务则是指支持多实例分布式事务,这个才算是真正的分布式事务。


既然是xa事务,必然涉及到两阶段提交,对于内部xa而言,同样存在着提交的两个阶段。


下文会结合源码详细解读内部xa的两阶段提交过程,以及各种情况下,mysqld crash后,mysql如何恢复来保证事务的一致性。

数据库版本:5.6.16


操作系统版本:CentOS 6.5


配置文件参数:
log-bin=/my/log/mysql-bin


binlog_format=ROW


set autocommit=0


innodb_support_xa=1


sync_binlog=1


innodb_flush_log_at_trx_commit=1


【innodb_flush_log_at_trx_commit=1,sync_binlog=1


不同的模式区别在于,写文件调用write和落盘fsync调用的频率不同,所导致的后果是mysqld 或 os crash后,不严格的设置可能会丢失事务的更新。


双一模式是最严格的模式,这种设置情况下,单机在任何情况下不会丢失事务更新。】




测试条件:
set autocommit=0;


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;


prepare阶段:


1.设置undo state=TRX_UNDO_PREPARED; //trx_undo_set_state_at_prepare调用


2.刷事务更新产生的redo日志;【步骤1产生的redo日志也会刷入】


MYSQL_BIN_LOG::prepare


ha_prepare_low


{


engine:


binlog_prepare


innobase_xa_prepare


mysql:


trx_prepare_for_mysql


{


1.trx_undo_set_state_at_prepare //设置undo段的标记为TRX_UNDO_PREPARED


2.设置事务状态为TRX_STATE_PREPARED


3.trx_flush_log_if_needed //将产生的redolog刷入磁盘


}


}




commit阶段:


1.将事务产生的binlog写入文件,刷入磁盘;


2.设置undo页的状态,置为TRX_UNDO_TO_FREE或TRX_UNDO_TO_PURGE; // trx_undo_set_state_at_finish调用


3.记录事务对应的binlog偏移,写入系统表空间; //trx_sys_update_mysql_binlog_offset调用

MYSQL_BIN_LOG::commit


ordered_commit


{


1.FLUSH_STAGE


flush_cache_to_file // 刷binlog


2.SYNC_STAGE


sync_binlog_file //Call fsync() to sync the file to disk.


3.COMMIT_STAGE


ha_commit_low


{


binlog_commit


innobase_commit


trx_commit(trx)


{


trx_write_serialisation_history(trx, mtr); //更新binlog位点,设置undo状态


trx_commit_in_memory(trx, lsn); //释放锁资源,清理保存点列表,清理回滚段


}


}


}

在任何情况下(机器掉电)mysqld crash或者os crash,MySQL仍然能保证数据库的一致性。数据的一致性是如何做到的哪?正是二阶段提交。


我们结合几种场景来分析下二阶段提交是如何做到的:


1.prepare阶段,redo log落盘前,mysqld crash


2.prepare阶段,redo log落盘后,binlog落盘前,mysqld crash


3.commit阶段,binlog落盘后,mysqld crash


对于第一种情况,由于redo没有落盘,毫无疑问,事务的更新肯定没有写入磁盘,数据库的一致性受影响;


对于第二种情况,这时候redo log写入完成,但binlog还未写入,事务处于TRX_STATE_PREPARED状态,这是提交还是回滚呢?


对于第三种情况,此时,redo log和binlog都已经落盘,只是undo状态没有更新,虽然redo log和binlog已经一致了,事务是否应该提交?

我们结合mysqld异常重启后的执行逻辑以及关键的源代码。

对于第三种情况,我们可以搜集到未提交事务的binlog event,所以需要提交;

对于第二种情况,由于binlog未写入,需要通过执行回滚操作来保证数据库的一致性。

异常重启后,如何判断事务该提交还是回滚


1.读binlog日志,获取崩溃时没有提交的event; //info->commit_list中含有该元素


2.若存在,则对应的事务要提交;否则需要回滚。

判断事务提交或回滚源码如下:



上面讨论了两阶段提交的基本流程,以及服务器异常crash后,mysql如何重启恢复保证binlog和数据的一致性。


简而言之,对于异常的xa事务,若binlog已落盘,则事务应该提交;binlog未落盘,则事务就应该回滚。


//异常重启后,回滚流程

innobase_rollback_by_xidrollback_by_xidtrx_rollback_resurrected    trx_rollback_active        row_undo        { //从回滚页获取undo记录 //分析undo记录类型 if (insert)                row_undo_ins else row_undo_mod        }



//异常重启后,提交流程

commit_by_xidtrx_commit_for_mysql


//写binlog接口

handler.cc:binlog_log_rowsql/binlog.cc:commitmysys/my_sync:my_syncsql/binlog.cc:sync_binlog_filehandler/ha_innodb.cc:innobase_xa_prepare

binlog日志文件是为了解决MySQL主从复制功能而引入的一份新日志文件,它包含了引发数据变更的事件日志集合。

从库请求主库发送 binlog 并通过日志事件还原数据写入从库,所以从库的数据来源为 binlog。

这样 MySQL 主库只需做到 binlog 与本地数据一致就可以保证主从库数据一致(暂且忽略网络传输引发的主从不一致)。

"MySQL事务的提交过程"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

事务 阶段 数据 一致 情况 一致性 日志 保证 更新 过程 文件 状态 数据库 流程 分布式 模式 磁盘 不同 主从 事件 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 小白学计算机网络技术难学吗 fast的网络安全密钥 人工智能与软件开发有关吗 软件开发副总监 网络安全科普小故事 计算机网络技术与实现论文 奉贤区个人软件开发教育 天龙八部怀旧服二区服务器 政治网络安全调查报告 购买云服务器费用怎么记账 橙子互联网科技的介绍 幻塔服务器为什么只有红石柱 数据处理软件开发 数据库集群阿里 军人网络安全承诺书范文 一分钟学会网络安全 企业网络安全防护证书样本 自考数据库及其应用电子版教程 网络安全工程师面试视频 分析杂志需要提供原始数据库 我遇到的网络安全问题及对策 想学网络技术应该应聘什么职位 网络安全文明上网绘画内容 我的世界服务器生存指令推荐 网络安全事件分几级IIV 武汉荆棘谷网络技术有限公司 银行数据库怎么测试 学生选课系统网络技术 网络安全模式还要密码吗 网络安全会议汇报
0