zoukankan      html  css  js  c++  java
  • Mysql-持久性实现

    Mysql数据增删改的一个大致过程如下:

    • 先从索引中找到数据所在的表空间ID以及在表空间中的数据页的页号
    • 然后通过表空间ID+页号作为Key,去缓存页哈希表中查找Buffer Pool是否已经加载了这个缓存页。如果已经加载了缓存页,就直接读取这个缓存页。
    • 如果没有这个缓存页,就需要从磁盘表空间中加载数据页到内存,此时需要从Free链表获取一个空闲页加入LRU链表中,加载的数据页就会放到这个空闲的缓存页中。
    • 接着在对应的缓存页中执行增删改操作,被修改过的缓存页就变成了脏页,会加入Flush链表中。
    • 最后,后台线程会在一些时机将LRU链表尾部的冷数据和Flush链表中的脏页刷盘。

    这个过程有个最大的问题就是,数据修改且事务已经提交了,但只是修改了Buffer Pool中的缓存页,数据并没有持久化到磁盘,如果此时数据库宕机,那数据不就丢失了!

    但是也不可能每次事务一提交,就把事务更新的缓存页都刷新回磁盘文件里去,因为缓存页刷新到磁盘文件里是随机磁盘读写,性能是很差的,这会导致数据库性能和并发能力都很差。

    所以此时就引入了一个 redo log 机制,在提交事务的时候,先把对缓存页的修改以日志的形式,写到 redo log 文件里去,而且保证写入文件成功才算事务提交成功。而且redo log顺序写入磁盘文件,每次都是追加到磁盘文件末尾去,速度是非常快的。之后再在某个时机将修改的缓存页刷入磁盘,这时就算数据库宕机,也可以利用redo log来恢复数据。

    随机磁盘读写:一个事务里的SQL可能牵涉到多个数据页的修改,而这些数据页可能不是相邻的,也就是属于随机IO。显然操作随机IO,速度会比较慢。

    参考:https://juejin.cn/post/6976060698757595150

  • 相关阅读:
    斜率dp cdq 分治
    POJ2449 (k短路)
    BZOJ1576 (最短路+并查集)
    SWUST0249 (凸包面积)
    道路修建 (网络流)
    HDU3930 (原根)
    ZOJ2006 (后缀自动机)
    Codechef2015 May
    后缀自动机
    Digit (数位DP)
  • 原文地址:https://www.cnblogs.com/kenLoong/p/15473664.html
Copyright © 2011-2022 走看看