Binlog的写入、还原和复制
4、Binlog是如何写入的
由于MySQL的SQL和引擎层的双日志体系,Binlog写入需要解决多个引擎之间事务执行的一致性问题。此外,由于从日志产生到落盘是数据库写入的关键路径,所以写入的效率也是需要关注的。下面我就从这两个方面来介绍Binlog的写入过程。
4.1、分布式事务模型——XA
XA源于Distributed Transaction Processing: The XA Specification,这篇文章定义了分布式事务处理模型,其中定义了事务管理器(充当协调者),负责为事务分配标识符,监视它们在不同参与者上执行的进度,并负责事务完成和故障恢复。 还定义了资源管理器,充当参与者,受协调者管理。此外还有应用程序,充当事务的发起者。
4.1.1 MySQL中的XA类型以及协调者选择
在MySQL中,如果事务的参与者是各个实例节点,那么是外部XA,由上层程序担当协调者,上层程序可以通过XA start,XA prepre,XA end,和XA commit的命令管理事务的执行。如果事务的参与者只在单实例节点内部,那么称为内部XA,例如参与者是Binlog和innodb。对于内部XA的协调者,如果开启Binlog,则Binlog为协调者,显然选择Binlog作为协调者是最合适的,因为Binlog位于引擎层之上且还负责主备之间数据的同步。如果不开Binlog,且只有innodb一个成员,那就不需要XA了。但是如果没有Binlog且在引擎层有多个参与者,那么MySQL会使用TC_LOG_MMAP作为协调者。XA采用两阶段提交协议保证分布式事务的一致性。两阶段提交分为prepare和commit两个阶段,协议的内容参考分布式事务两阶段提交,
在Prepare阶段前,进入函数ha_commit_trans。这里有个参数all。'all为false' 表示这是用户发出的显式提交,'all为true'表示是 DDL 发出的隐式提交。某些DDL在执行完成后会隐式提交,也就是无需用户调用commit等结束语句而自发提交,这就意味着一条DDL是一个单独的事务,用户无法回滚它,详见Statements That Cause an Implicit Commit。如果打开了autocommit,DML也会自发提交,详见autocommit。所以XA事务有很多种情况(内部、外部、是否开Binlog、是否为DDL等),接下来主要介绍开启row_based格式的Binlog,开启GTID,存储引擎只有innodb的内部XA执行过程。以DDL和DML语句为例,整个过程如图6所示。