三丶Mini-Transactionmysql把底层页面的一次原子访问
过程称为一个Mini-Transaction(MTR)(比如向B+树中插入一条记录的过程算作一个MTR , 即使这个sql涉及到多个B+树)一个MTR可以包含一组redo log , 在进行崩溃恢复的时候需要把这一组MTR看作是一个不可分割的整体(B+树中插入一条记录 , 可能涉及到叶子节点 , 非叶子点的改动 , 不能说只新增了叶子节点 , 但是没用更新非叶子节点 , 需要保证这个过程的原子性)
一个事务可以包含多个语句 , 一个语句可以包含多个MTR , 一个MTR可以包含多个redo log日志 , 那么innodb是如何确认多个redo log属于一个MTR的昵
文章插图
多个redo log以最后一条类型为
MLOG_MULTI_REC_END
类型的日志结尾 , 那么视为前面的redo log为同一MTR中的日志 。系统在进行崩溃恢复的时候 , 只有解析到MLOG_MULTI_REC_END
类型的日志的时候 , 才认为解析到了一组完整的redo log日志 , 才会进行恢复 。有些需要保证原子性的操作 , 只会产生一条redo log , 比如更新
Max Row ID
(innodb在用户没用指定主键的时候 , 将此值存储在页中 , 没增大到256的整数倍的时候 , 才会更新写回磁盘) , 这个时候会将其的type字段的第一个比特置为1 , 表示这个单个redo log 便是一个原子性操作 , 而不是加上一个MLOG_MULTI_REC_END
类型的日志 。四丶redo log日志写入过程1.redo log block
文章插图
innodb 将通过MTR生成的redo log放在大小为512字节的block中 , 其中存储redo log的部分只有
log block body
其余的两部分存储一些统计信息- log block header
- log_block_hdr_no:每一个block 具备一个大于0的唯一编号 , 此属性便是记录编号值
- log_block_hdr_data_len:记录当前lock block使用了多少字节(从12开始 , 因为lock block header占用了12字节) , 随着越来越多的日志写入block最后最大为512字节
- log_block_first_rec_group:一个MTR包含多个日志 , 这个字段记录该block中第一个MTR生成redo log日志记录组的偏移量 。
- log_block_checkpoint_no:表示checkpoint的序号
- log block trailer
- log_block_check_sum:表示block检验和 , 用于正确性校验
文章插图
innodb_log_buffer_size
可以指定其大小 , 默认16mb3.redo log写入log bufferinnodb保存了一个
buf_free
的全局变量用于记录log buffer中空闲位置的偏移量 , 让后续redo log的写入从buf_free的位置开始写 。不同的事务是可以并发运行的 , 并发的写入redo log buffer中 , 每当一个MTR执行完成时 , 伴随着该MTR生成的redo log被写入到log buffer中 , 多个不同事务的MTR可能时交替写如到log buffer中的
五丶redo log持久化1.redo log buffer中的内容何时持久化到磁盘MTR运行过程中产生的一组redo log会在MTR结束的时候被复制到log buffer中 , 但是何时落盘昵?
经验总结扩展阅读
- MySQL的下载、安装、配置
- 我的Vue之旅 09 数据数据库表的存储与获取实现 Mysql + Golang
- 「MySQL高级篇」MySQL之MVCC实现原理&&事务隔离级别的实现
- Mysql InnoDB Buffer Pool
- 「MySQL高级篇」MySQL锁机制 && 事务
- 【MySQL】Navicat15 安装
- 「MySQL高级篇」explain分析SQL,索引失效&&常见优化场景
- 「MySQL高级篇」MySQL索引原理,设计原则
- MySQL 索引失效-模糊查询,最左匹配原则,OR条件等。
- MySQL 全局锁、表级锁、行级锁,你搞清楚了吗?