mysql两阶段提交和日志一致性
文章目录
【注意】最后更新于 December 30, 2021,文中内容可能已过时,请谨慎使用。
redo log
当有一条记录要更新时,InnoDB 引擎就会先把记录写到 redo log(并更新内存),这个时候更新就算完成了。在适当的时候,将这个操作记录更新到磁盘里面
-
为什么需要redo log
假设没有redo log,可以看到当数据库crash后,在内存中的数据就会丢失

-
写入redo log失败怎么办
借助undo log将数据恢复到事务开始前
redo log和binlog的区别
- binlog只有innodb才有
- binlog记录的是一种逻辑日志,即通过SQL语句的方式来记录数据库的修改;而InnoDB层产生的redo log是一种物理格式日志,其记录的是对于磁盘中每一个数据页的修改
- 记录的时间点不同,binlog在事务提交完成后写入一次,redolog在事务过程中不断被写入,redo log不会随着事务的提交顺序进行写入
两阶段提交
XA-2PC (two phase commit, 两阶段提交 )
XA是由X/Open组织提出的分布式事务的规范。XA规范主要定义了(全局)事务管理器(TM: Transaction Manager)和(局部)资源管理器(RM: Resource Manager)之间的接口
XA为了实现分布式事务,将事务的提交分成了两个阶段:也就是2PC (tow phase commit),XA协议就是通过将事务的提交分为两个阶段来实现分布式事务
prepare 阶段:第一阶段,事务管理器向所有涉及到的数据库服务器发出prepare"准备提交"请求,数据库收到请求后执行数据修改和日志记录等处理,处理完成后只是把事务的状态改成"可以提交",然后把结果返回给事务管理器.
commit阶段:事务管理器收到回应后进入第二阶段,如果在第一阶段内有任何一个数据库的操作发生了错误,或者事务管理器收不到某个数据库的回应,则认为事务失败,回撤所有数据库的事务。数据库服务器收不到第二阶段的确认提交请求,也会把"可以提交"的事务回撤。如果第一阶段中所有数据库都提交成功,那么事务管理器向数据库服务器发出"确认提交"请求,数据库服务器把事务的"可以提交"状态改为"提交完成"状态,然后返回应答

-
为什么需要两阶段提交
因为mysql 数据恢复主要依靠redo log,假设没有两阶段提交会是什么样,流程变为下面这样

如果在写入binlog的时候,数据库crash了,恢复后基于redo log恢复数据的时候,因为binlog没有相关记录,这时候如果有从库的话,从库的记录和主库就不一致了
如何完成崩溃恢复
在做Crash recovery时,分为以下3种情况:
- binlog有记录,redolog状态commit:正常完成的事务,不需要恢复;
- binlog有记录,redolog状态prepare:在binlog写完提交事务之前的crash,恢复操作:提交事务。(因为之前没有提交)
- binlog无记录,redolog状态prepare:在binlog写完之前的crash,恢复操作:回滚事务(因为crash时并没有成功写入数据库)
文章作者 lialzm
上次更新 2021-12-30