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

  • 相关阅读:
    Google Analytics:为链接点击设定事件追踪的方法
    HTTP状态码大全
    jquery插件的编写
    2016.2.27日(开学)学习总结
    关于单文件上传的封装
    单文件的文件上传详细解释
    php中对象的串行化
    PDO的事物处理机制
    MySQL操作类的封装(PHP)
    smarty的简单介绍
  • 原文地址:https://www.cnblogs.com/kenLoong/p/15473664.html
Copyright © 2011-2022 走看看