:: 流程
- 连接验证及解析、
- 写undolog,记录数据被修改前的样子
- 从索引中查找数据
- 更新数据
- 数据操作
4.1 数据页在内存中
4.1.1 普通索引: 直接更新内存中的数据页
4.1.2 唯一索引: 更新后是否会数据冲突,不会则更新
4.2 数据页不在内存中
4.2.1 普通索引: 将对数据页的更新操作记录到change buffer,暂时不更新到磁盘。changebuffer会在空闲时异步更新到磁盘
4.2.2 唯一索引: 因为需要保证更新后的唯一性,所以不能延迟更新,必须把数据页从磁盘加载到内存,然后判断更新后是否会数据冲突,不会的话就更新数据页
- 数据操作
- 写redolog(prepare状态)记录数据被修改后的样子 二阶段提交
- 写binlog(同时将redo log设置为commit状态)记录整个操作过程
:: 带changebuffer的更新过程 1
^897cc2
我们假设当前k索引树的状态,查找到位置后,k1所在的数据页在内存(InnoDB buffer pool)中,k2所在的数据页不在内存中。
- Page 1在内存中,直接更新内存;
- Page 2没有在内存中,就在内存的change buffer区域,记录下“我要往Page 2插入一行”这个信息
- 将上述两个动作记入redo log中(图中3和4)。
执行这条更新语句的成本很低,就是写了两处内存(异步持久化),然后写了一处磁盘(两次操作合在一起写了一次磁盘),而且还是顺序写的。
技巧💡
changebuffer, 节省了随机读磁盘的IO消耗 。不用进行读取到内存(buffer pool),在进行变更操作,而是直接写到changebuffer内存
这里也解释了,为什么能通过redolog来找回changbuffer的数据。使用到了redolog的二阶段提交。