mysql之事务二阶段提交

说到mysql事务的二阶段提交,那么不得不说说redolog日志和binlog日志,二阶段提交也是围绕这两哥们展开的,所以我们先来理解一下这两个日志

redolog日志

redolog日志,是用来保证数据持久性的日志,记录的是某个数据页修改操作,如:对表空间xx中的数据页xx中的偏移量offset的地方更新的数据xx,当系统宕机后用来恢复到事务提交的最后一次的数据库状态。

redolog日志又分为
  • 日志缓冲(redo log buffer):这部分日志是易失性的
  • 重做日志(redo log file):这部分日志是持久性的

mysql每执行一次DML操作,都现往日志缓冲中记录日志,后续再某个时间点将日志缓冲中的日志一次性记录到重做日志中,这种先写日志再写磁盘的操作就是MYSQL中常说的WAL(write-Ahead Logging)

binlog日志

binlog日志也叫归档日志,是mysql底层的日志,记录的是所有的DML和DDL语句(不包含查询语句),而且以事件的形式记录,主要的作用是数据库的主从同步

二阶段提交

mysql之事务二阶段提交_第1张图片
以上就是事务二阶段提交的流程图,从上图中可以了解到,在事务提交的最后有三个步骤

  • 1、写入redo log,处于prepare状态
  • 2、写bin log
  • 3、写入redo log,处于commit状态
    由于redo log日志的提交分别为prepare和commit两个阶段,所以成为二阶段提交

为什么需要二阶段提交

如果不需要二阶段提交,那么事务提交无非就两种情况
1、先写bin log日志,再写redo log日志:假设写完bin log日志的A记录数据库就宕机,因为bin log日志中存在了这个记录,所以从服务器同步数据时就会同步到A记录,而主服务器的redo log日志不存在A记录,就照成了主从数据不一致

2、先写redo log,再写bin log:假设redo log日志写完A记录就宕机,数据库恢复时因为redo log中存在A记录,就会将A记录恢复到数据库中,而bin log日志中不存在A记录,同步数据时就没有A记录的数据,从而照成数据不一致

而使用二阶段提交就可以解决这些问题
1、一阶段提交之后崩溃了,即写入 redo log,处于 prepare 状态 的时候崩溃了,此时:由于 binlog 还没写,redo log 处于 prepare 状态还没提交,所以崩溃恢复的时候,这个事务会回滚,此时 binlog 还没写,所以也不会传到备库。

2、假设写完 binlog 之后崩溃了,此时:redolog 中的日志是不完整的,处于 prepare 状态,还没有提交,那么恢复的时候,首先检查 binlog 中的事务是否存在并且完整,如果存在且完整,则直接提交事务,如果不存在或者不完整,则回滚事务。

3、假设 redolog 处于 commit 状态的时候崩溃了,那么重启后的处理方案同情况二。

你可能感兴趣的:(mysql,数据库,服务器)