• InnoDB:一条update语句执行过程


    存储引擎InnoDB下执行一条update的语句要经过哪些步骤呢?假设我们执行如下SQL,本文宏观上将执行器和存储引擎视为一体(执行器和存储引擎交互)。

    update user_info set name='岩枭' where id=1 and name='萧炎';
    
    • 1

    1、Buffer Pool

    要执行更新操作,首先要拿到where条件里定位的数据。存储引擎会先在Buffer Pool里找一找有没有这条数据,有则开干,没有的话只能去磁盘读取,然后加载到Buffer Pool。

    试想一下,现在磁盘上有一个user.txt文件(简化下only one row)保存了一条用户信息,需要把里面的用户信息修改一下,是不是也需要用程序先读到内存里,处理完再写回磁盘。在这个过程中,需要读取这个用户信息,就可以直接从内存里获取。

    2、undo log

    执行更新之前,先给undo log写条日志,记录一下原数据信息,万一程序处理异常,事务是需要回滚的,那就需要undo log将数据回滚到更新之前。

    试想一想,现在要开始更新从user.txt里加载到内存的数据了,稳妥起见,是不是先打个日志,记录一下更新之前,原来的数据是什么。

    3、脏数据

    现在把Buffer Pool里的数据进行修改,将’萧炎’,改成’岩枭’,这就产生了所谓的脏数据,因为内存数据已经更新了,但是磁盘数据并未更新。

    4、Redo Log

    更新内存数据后,再给Redo Log写条日志,记录一下对数据进行了怎样的修改,这样当MySQL宕机后,还能从Redo Log里恢复。Redo Log也有自己的buffer,通常的配置是提交事务时,将Redo Log进行刷盘。

    所以没有提交事务时,即使MySQL宕机了也没关系,因为数据都在内存里,客户端也会收到异常。提交事务之后,即使MySQL宕机了还是没关系,MySQL可以根据Redo Log将数据恢复回来。

    5、binlog

    归档日志,上述步骤完成后,会在binlog里记录一下逻辑日志,简单理解为对哪个数据页的哪条数据进行了怎样的修改。然后将binlog的相关信息写到Redo Log里并打一个commit标记,此次事务就完成了。

    6、数据落盘

    经过上述步骤后,MySQL服务器内部的IO线程会在某个时刻把内存的数据同步写回磁盘,这样磁盘数据就是最新的数据了。

    总结:

    其实MySQL也可以看成是一个应用(业务)系统,一条update语句对于MySQL而言就是处理一个业务,为了支持撤销,保证宕机后可恢复,这个应用系统做了很多保障工作。

  • 相关阅读:
    qt-C++笔记之两个窗口ui的交互
    [python 刷题] 12 Integer to Roman & 13 Roman to Integer
    【Apache Shiro】超详细笔记-1:功能、架构、集成Spring、认证
    【小程序开发实战】使用WxJava实现手机号获取
    P1381 单词背诵【双指针】
    研究生必备科研工具,你都用了吗
    Promise 对象详解
    docker 入门教程
    华为OD-C卷-开源项目热榜[100分]Python3-100%
    不同表格式下的小文件治理方式(开源RC file/ORC/Text非事务表、事务表、Holodesk表格式..)
  • 原文地址:https://blog.csdn.net/weixin_43275277/article/details/127859984