undo-log
作用
- 搜索引擎层用于事务回滚的日志,目的是用于保证事务的原子性
- MVCC的实现是通过:read view + undo log实现的。
实现过程
- 事务开始后,根据不同的增删改类型的语句在undo-log中记录不同的数据,以便于事务回滚后数据的恢复。并且在记录行上维护undo-log中两个额外的字段事务id和roll_point指针。数据行之间由roll_point指针连接,数据行被串成一条版本链。
- 增语句:记录新增语句的id,回滚只需要删除改行即可。
- 删除:记录被删除行的数据
- 修改:记录改行原本的数据内容
- 如果事务还未提交前数据库发生崩溃,那么就可以用undo-log回滚事务。
- 如果事务超时未提交,需要结束事务时也会利用undo-log进行回滚。
如何持久化的?
undo-log也是通过redo-log来进行持久化的。
被修改的数据写入缓冲池中,被修改的数据页被标记为脏页。脏页会被写入redo-log中,通过redo-log刷盘机制进行
在缓冲池中有undo页,修改undo-log也是通过把数据添加到undo页中,对undo页的修改也会记录到redo-log中,redo
redo-log
存储模型
如何刷盘
bin-log
存储模型
刷盘时机
undolog解决redolog不完整
参考文章:
InnoDB在因sql执行失败或者MySQL服务宕机导致redolog不完整从而出现数据不一致是这么解决的:
- 在更新数据页之前,InnoDB会先将数据当前的状态记录在「Undo Log」中。
- 之后,再将更新后的相关数据记录到「Redo Log」中。
undo log是以页为单位,跟随页的刷新机制,会存在丢失的情况,所以在记录undo后也会将该undo记录到redo,避免undo丢失,一旦undo丢失就回滚不了了。
有了undo log后,假设第二条sql执行失败,这个时候就会通过行记录中的事务ID(txidx)和回滚指针(roll_pointx、roll_pointx1)去undolog中找对应的回滚操作,最终将事务回滚保证原子性和一致性。
如果发生宕机,那么在重新MySQL服务时,会有两个操作:
- 会先通过redo log构建「脏页」。
- 根据redo log中记录的事务提交状态来决定是否回滚。
两阶段提交解决binlog和redolog的不一致
XA的两阶段分别是prepare和commit,在事务提交前,redolog中记录的状态都是prepare,当事务提交后,该状态就会被更新为commit,同时将XID写入到对应的binlog中并刷新到磁盘。
XA两阶段提交保证了binlog和redolog逻辑一致,从而避免主从节点的数据不一致。
总结
MySQL一致性的保证基本上涉及到InnoDB存储引擎的各个组件,「Buffer Pool」、「Log Buffer」、「Redo Log」、「Undo Log」等,还有DML操作的流程、锁、故障恢复等功能。最后再总结下MySQL是如何保证一致性的。
- 对于并发操作带来的数据不一致性问题,InnoDB通过锁来解决。
- 对于可能会发生的redolog不完整的情况,InnoDB通过Undo Log来解决。
- 对于redolog&binlog不一致带来的主从节点数据不一致,MySQL是通过XA两阶段提交来解决。