MySQL事务--两阶段提交
2021/8/7 19:07:53
本文主要是介绍MySQL事务--两阶段提交,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
MySQL事务协调器
MySQL支持多种存储引擎,并在MySQL Server层实现Binlog机制来进行主从数据同步。每种存储引擎相互独立,使用不同的数据文件和日志文件,当MySQL实例内部一个事务涉及到多个事务存储引擎表时,需要使用2PC来保证数据一致性。
## 文件sql\mysqld.cc static int init_server_components() { tc_log = &tc_log_dummy; if (total_ha_2pc > 1 || (1 == total_ha_2pc && opt_bin_log)) { if (opt_bin_log) tc_log = &mysql_bin_log; else tc_log = &tc_log_mmap; } } ## 等价于 static int init_server_components() { tc_log = &tc_log_dummy; if (total_ha_2pc > 0 && opt_bin_log) { tc_log = &mysql_bin_log; } if (total_ha_2pc > 1 && !opt_bin_log) { tc_log = &tc_log_mmap; } }
- 默认使用tc_log_dummy来作为事务协调者
- 当事务引擎超过1个且开启Binlog,则使用binlog来作为事务协调者。
- 当事务引擎大于1个且未开启binlog,则使用tc_log_mmap作为事务协调者。
无论tc_log_dummy还是Binlog或tc_log_mmap都基于TC_LOG这个基类来实现:
class TC_LOG { public: virtual int open(const char *opt_name) = 0; virtual void close() = 0; virtual enum_result commit(THD *thd, bool all) = 0; virtual int rollback(THD *thd, bool all) = 0; virtual int prepare(THD *thd, bool all) = 0; };
tc_log_dummy是一个空实现,不会记录事务日志。
tc_log_mmap是一个标准的事务协调者实现,它会创建一个名为 tc.log
的日志并使用操作系统的内存映射(memory-map,mmap)机制将内容映射到内存中。tc.log
文件中分为一个一个 PAGE,每个 PAGE 上有多个XID。
binlog同样基于TC_LOG来实现事务协调者功能,会递增生成mysql-binlog.xxxxx的文件,每个文件中包含多个事务产生的binlog event,并在binlog event中包含XID。
tc_log_mmap和binlog都基于XID来确定事务是否已提交。
InnoDB事务存储引擎
MySQL存储引擎会在初始化时将相应方法注册到MySQL Server层,以InnoDB事务存储引擎为例,在初始化时会注册prepare、commit、rollback、recover等函数到MySQL Server层,供事务协调者调用。
## 文件 storage\innobase\handler\ha_innodb.cc /** Initialize the InnoDB storage engine plugin. @param[in,out] p InnoDB handlerton @return error code @retval 0 on success */ static int innodb_init(void *p) { handlerton *innobase_hton = (handlerton *)p; innodb_hton_ptr = innobase_hton; innobase_hton->commit = innobase_commit; innobase_hton->rollback = innobase_rollback; innobase_hton->prepare = innobase_xa_prepare; innobase_hton->recover = innobase_xa_recover; }
在使用Binlog作为事务协调器的2PC过程中:
- 在prepare阶段,使用MYSQL_BIN_LOG::prepare调用InnoDB存储引擎的innobase_xa_prepare方法,将InnoDB的事务日志Redo Log持久化。
- 在Commit阶段,使用MYSQL_BIN_LOG::commit先将Binlog日志进行持久化,然后调用innobase_commit方法,将事务在InnoDB存储引擎层进行提交。
MySQL两阶段提交
无论时MySQL 外部XA事务还是内部XA事务,都需要通过两阶段事务提交2PC的方式来保证数据一致性。在大部分的使用场景中,都会开启MySQL Binlog来进行主从数据同步,同时InnoDB事务存储引擎成为主流选择,因此在讨论MySQL两阶段提交时更多的会关注在MySQL Server层的Binlog日志和InnoDB事务日志(Redo Log)。
参考资料
无处不在的 MySQL XA 事务
这篇关于MySQL事务--两阶段提交的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-24MySQL集群部署资料:新手入门教程
- 2024-12-24MySQL集群资料详解:新手入门教程
- 2024-12-24MySQL集群部署入门教程
- 2024-12-24部署MySQL集群学习:新手入门教程
- 2024-12-24部署MySQL集群入门:一步一步搭建指南
- 2024-12-07MySQL读写分离入门:轻松掌握数据库读写分离技术
- 2024-12-07MySQL读写分离入门教程
- 2024-12-07MySQL分库分表入门详解
- 2024-12-07MySQL分库分表入门指南
- 2024-12-07MySQL慢查询入门:快速掌握性能优化技巧