|1375

:: 流程

  1. 连接验证及解析、
  2. undolog,记录数据被修改前的样子
  3. 从索引中查找数据
  4. 更新数据
    • 数据操作
      4.1 数据页在内存中
      4.1.1 普通索引: 直接更新内存中的数据页
      4.1.2 唯一索引: 更新后是否会数据冲突,不会则更新
      4.2 数据页不在内存中
      4.2.1 普通索引: 将对数据页的更新操作记录到change buffer,暂时不更新到磁盘。changebuffer会在空闲时异步更新到磁盘
      4.2.2 唯一索引: 因为需要保证更新后的唯一性,所以不能延迟更新,必须把数据页从磁盘加载到内存,然后判断更新后是否会数据冲突,不会的话就更新数据页
  5. redolog(prepare状态)记录数据被修改后的样子 二阶段提交
  6. binlog(同时将redo log设置为commit状态)记录整个操作过程

:: 带changebuffer的更新过程 1

^897cc2


我们假设当前k索引树的状态,查找到位置后,k1所在的数据页在内存(InnoDB buffer pool)中,k2所在的数据页不在内存中。

  1. Page 1在内存中,直接更新内存;
  2. Page 2没有在内存中,就在内存的change buffer区域,记录下“我要往Page 2插入一行”这个信息
  3. 将上述两个动作记入redo log中(图中3和4)。
    执行这条更新语句的成本很低,就是写了两处内存(异步持久化),然后写了一处磁盘(两次操作合在一起写了一次磁盘),而且还是顺序写的。

技巧💡

changebuffer, 节省了随机读磁盘的IO消耗 。不用进行读取到内存(buffer pool),在进行变更操作,而是直接写到changebuffer内存
这里也解释了,为什么能通过redolog来找回changbuffer的数据。使用到了redolog的二阶段提交。

Footnotes

  1. mysql45讲,mysql45讲