zoukankan      html  css  js  c++  java
  • [MySQL] update语句的redo log过程

    update语句是如何执行 , 如何将执行后的新数据持久化在磁盘中
    可以假设两种情境:

    1. 假设MySQL在更新之后只更新内存中的数据就返回,然后再某一时刻进行IO将数据页持久化。这样所有操作都是在内存中,可以想象此时的MySQL性能是特别高的。但是,如果在更新完内存又还没有进行持久化的这段时间,MySQL宕机了,那么我们的数据就丢失了。

    2. 另外一种情况:每次MySQL将内存中的页更新好后,立刻进行IO,只有数据落盘后才返回。此时我们可以保证数据一定是正确的。但是,每一次的操作,都要进行IO,此时MySQL的效率变得非常低。

    我们来看看MySQL是如何做到保证性能的情况下,还保证数据不丢的。

    update 表 set a = 1 where id = 1;

    如何保证数据一致性

     

    重做日志(redo log)

    这里要介绍一个很重要的日志模块,称为rodo log(重做日志)。重做日志是InnoDB引擎特有的。

    重做日志在更新数据的时候,会记录在哪个数据页更新了什么数据,并且只要成功的在重做日志记录了这次更新,不需要将内存中的数据页写回磁盘,就可以认为这次更新已经完成了。

    1. MySQL里有一个名词,叫WAL技术,WAL的全称是Write-Ahead-Logging,它的关键点就是先写日志,再写磁盘,也就是说只要保证了日志的落盘,数据就一定正确。此时只要保存了日志,就算此时MySQL宕机了,没有将数据页写回磁盘,也可以在之后利用日志进行恢复。

    但是,InnoDB的redo log是固定大小的,比如可以配置为一组4个文件,每个文件的大小是1GB。固定大小也就造成了一个问题,redo log是会被写满的。

    2. InnoDB采取了循环写的方式。注意看,这里有两个指针。write_pos表示当前写的位置,只要有记录更新了,write_pos就会往后移动。而check_point表示检查点,只要InnoDB将check_point指向的修改记录更新到了磁盘中,check_point将会往后移动。

    如果我们把这一行数据所在的内存页更新好了,并且写入了rodo log中,此时将返回修改成功的提示。然后在rodo log中表现为记录了在某一个内存页的更新记录

    此时在磁盘中,数据a未改变,在内存中,a改为了1,在rodo log中记录了这个内存页的更新记录,write_pos往后移动。

    3. 只有成功的写回了磁盘,check_point才可以往后移动。这个设计,使得rodo log是可以无限重复使用的。

  • 相关阅读:
    内存泄漏检测工具
    RGB 颜色 代码 转换器
    索引 扫描及查找 1
    IIS7中Integrated和classic的区别
    HTTP请求上下文之终结:HttpContext类
    vs2010 快捷键大全
    IIS 7.0 中的 HTTP 状态代码
    JSON Date Format
    如何使用 MasterPage(注意母板页和子页面的执行顺序)
    B树、B树、B+树、B*树
  • 原文地址:https://www.cnblogs.com/taoshihan/p/13259897.html
Copyright © 2011-2022 走看看