场景复现

如果我们执行事务update set name=’after’ where id =1;的执行过程

  1. begin
  2. 查询id=1数据,如果在buffer_pool中,直接返回给执行器,否则从磁盘基于B+树索引查询出该行所在页内存的偏移量返回给buffer_pool并缓存,然后继续返回给执行器。
  3. 执行器执行update操作
  4. 先更新buffer_pool中的缓存数据,更新该页后称为脏页。
  5. 再更新redolog,该行数据被更新为name=’after’,存储的是二进制数据,此时redolog的状态为prepare。
  6. 再更新undolog,该行更新前的数据为name=’before’,存储的是逻辑数据。
  7. undolog落盘
  8. binlog落盘,redolog状态更新为commit
  9. commit

redolog的两阶段提交

1、prepare阶段,写redo log;
2、commit阶段,写binlog并且将redo log的状态改成commit状态;
mysql发生崩溃恢复的过程中,会根据redo log日志,结合 binlog 记录来做事务回滚:
1、如果redo log 和 binlog都存在,逻辑上一致,那么提交事务;
2、如果redo log存在而binlog不存在,逻辑上不一致,那么回滚事务;
最后大家可发现,这里的两阶段提交,实际是存在与redo log与binlog。所以当未开启binlog,那就是提交事务直接写到redo log里面。这也就是redo log事务两阶段提交,看场景区分的原因。