InnoDB的Mini-transaction(简称mtr)是保证若干个page原子性变更的单位。一个mtr中包含若干个日志记录——mlog,每个日志记录都是对某个page——mblock;
http://liuyangming.tech/05-2019/InnoDB-Mtr.html
为啥需要mtr保证Page原子性变更?
首先,Redolog不是幂等的,所以对Page的操作必须保证全部成功或全部失败。
单个Page可能有多个RedoLOG需要执行,多个Page更不必说了。
如何辨别一个物理事务是否完整呢?
这个问题是在物理事务提交时用了个很巧妙的方法保证了,在提交前,如果发现这个物理事务有日志,则在日志最后再写一些特殊的日志,这些特殊的日志就是一个物理事务结束的标志,那么提交时一起将这些特殊的日志写入,在重做时如果当前这一批日志信息最后面存在这个标志,则说明这些日志是完整的,否则就是不完整的,则不会重做。
https://cloud.tencent.com/developer/article/1056426
MTR的大致执行过程
mtr.start() 开启一个mini transaction
mtr_x_lock() 加锁,这个操作分成两步,1. 对space->latch加X锁;2. 将space->latch放入mtr_t::m_impl::memo中(这样在mtr.commit()后就可以将mtr之前加过的锁放掉)
mlog_write_ull 写数据,这个操作也分成两步,1. 直接修改page上的数据;2. 将该操作的redo log写入mtr::m_impl::m_log中
mtr.commit() 写redo log + 放锁,这个操作会将上一步m_log中的内容写入redo log file,并且在最后放锁
https://zhuanlan.zhihu.com/p/56188735?utm_source=com.yinxiang&utm_medium=social&utm_oi=27778455961600
在mtr_start后,只有mtr_commit一个操作;mtr_commit时会将mtr中的mlog和�mblock(dirty page)分别拷贝到logbuffer和flushlist中。在真实事务提交时,会将该事务涉及的所有mlog刷盘,这样各个原子变更就持久化了。恢复的时候按照类型(mtr_type_t)调用相应的回调函数,恢复page。