美文网首页
MySQL架构体系设计深入剖析篇学习笔记

MySQL架构体系设计深入剖析篇学习笔记

作者: 又增加了奇奇怪怪的知识 | 来源:发表于2020-11-09 22:04 被阅读0次

    MySQL存储引擎InnoDB原理拆解以及设计深度剖析

    MySQL记录存储以Page(页)来划分。
    页头:记录页面的控制信息,共占56字节,包含页的左右兄弟页面指针、页面空间使用情况等。
    虚记录:最大虚记录:比页面最大主键还大。 最小虚记录:比页面最大主还小。
    记录堆:行记录存储区
    自由空间链表:链表关联被删除的记录用来重复利用空间
    未分配空间:页面未使用的存储空间。
    Slot区:
    页尾:存储页面的校验信息8个字节。

    页内记录维护
    1. 顺序保证
    • 物理有序:非顺序插入需要移动数据,插入效率较低,查找效率高。
    • 逻辑有序:物理无序,链表连接逻辑数据,插入效率高,查找效率低。
    • InnoDB采用的逻辑有序,在查询中有进行优化。

    page 与 page关联, 主键和主键关联组成顺序。

    1. 插入策略
    • 自由空间链表:InnoDB优先使用
    • 未使用空间:
    1. 页内查询
    • 遍历:逻辑有序
      通过最小虚记录->最小rec->逐渐递增->最大虚记录
      Slot 按照一定规律指向rec,可以对记录按照一定规律进行做类似二分加快查找。
    MySQL InnoDB存储引擎内存管理
    1. 预分配内存空间 以块形式加载
    2. 数据以页为单位加载
    3. 数据内外存交换 将内存块内容发生改变后写入磁盘,从磁盘加载新的块加载入硬盘
    4. 内存池
    5. 页面映射 磁盘动态映射到内存上
    6. 页面数据管理
      1. 空闲页
      2. 数据页
      3. 脏页:被修改后的内存页,要将其写入磁盘。
    7. 数据淘汰(数据内外存交换) 内存页都被使用的情况下或需要加载新的数据时。
      1. LRU 最长时间最久没有被使用的数据淘汰掉,使用链表结构。
      2. 保证链尾最长时间没有使用:每次访问链表数据时,将该数据放到链表头,就可以保证链表最尾为最长时间没有被使用。
      3. 为了解决避免热数据被淘汰:访问时间+频率。(redis采用方式)
      4. 两个LRU表。一级LRU做内存加载,二级LRU存放一级LRU特定等级的热数据。

    8.InnoDB采用的方式:
    Buffer Pool 预分配的内存池
    Page Buffer Pool的最小单位
    Free List 空间page组成的链表
    Flush list 脏页链表
    Page hash表 维护内存page和文件page的映射关系
    LRU 内存淘汰算法:

    LRU

    (head)LRU_new(tail):(head)LRU_old(tail)以5比3的比例Midpoint指针进行冷热分离
    LRU_new
    LRU_old
    Midpoint

    1. 页面装载: 磁盘数据到内存,插入到LRU_old头部
    2. 页面淘汰: Free list中取> LRU中淘汰 > LRU Flush,将要淘汰的数据放入 Free List
      3. old 到 new:定义热数据的移动 innodb_old_blocks_time: old区存活时间大于此值,有机会进入new区。存活时间+访问频率
    3. new 到 old:由Midpoint始终指向8/5位置来区分冷热数据,并结合
      free_page_clock:Buffer Pool淘汰页数
      LRU_new长度1/4
      当前freed_page_clock-上次移动到Header时freed_page_clock LRU_new 长度1/4

    MySQL设计思路:减少移动次数

    MySQL事务实现原理拆解以及设计深度剖析

    事务特性
    • A:原子性 全部成功或全部失败
    • I:隔离性 并行事务之间互不干扰
    • D:持久性 事务提交后数据改变是永久性的
    • C:一致性 数据中间状态对外不可见,只有最初状态和最终状态可见
    并发问题
    • 脏读: 读取到未提交的数据
    • 不可重复读: 两次读取结果不同
    • 幻读: select操作的到的结果所表征的数据状态无法支持后续的业务操作
    隔离级别
    • 读取未提交内容 RU:最低隔离级别,会读到其他事务未提交的数据(脏读)
    • 读取提交内容 :事务过程中可以读取到其他事务已提交的数据(不可重复读)
    • 可重复读 RR:每次读取相同结果集,不管其他事务是否提交(幻读)
    • 串行化:事务排队,隔离级别最高,性能最差
    MySQL事务实现原理
    • MVCC

      • 多版本并发控制:解决读写冲突,有两个隐藏列
      • 当前读:读当前版本
      • 快照读:读历史版本
        • 可见性判断:创建快照这一刻,还未提交的事务。 创建快照之后创建的事务。
        • Read View: 快照读 活跃事务列表。 列表中最小事务ID。 列表中最大事务ID。
    • undo log

      • 回滚日志
      • 保证事务原子性
      • 实现数据多版本
      • delete undo log;用于回滚,提交即清理
      • update undo log:用于回滚,同时实现快照读,不能随便删除
    • redo log

      • 实现事务持久性

      • 记录修改

      • 用于异常恢复

      • 循环写文件

        • Write Pos:写入位置
        • Check Point:刷盘位置
        • Check Point -> Write pos: 待落盘数
      • 写入流程:

        • 记录页的修改, 状态为prepare。
        • 事务提交,讲事务记录为commit状态。
      • 刷盘时机:

        • innodb_fulsh_log_at_trx_commit 0/1/2
      • 意义:

        • 体积小,记录页的修改,比写入页代价低。
        • 末尾追加,随机写变顺序写,发生改变的页不固定。

    MySQL锁实现原理拆解以及设计深度剖析

    InnoDB锁种类
    • 锁粒度:
      • 行级锁
        • 作用在索引上
        • 聚簇索引和二级索引
      • 间隙锁:锁一个范围
        • 解决可重复读模式下的幻读问题
        • GAP锁不是加在记录上
        • GAP锁锁住的位置,是两条记录之间的GAP
        • 保证两次当前读返回一致的记录。
      • 表级锁
        • RC级别全表扫描“锁表”,所有记录加锁后返回,然后由MySQL Server层进行过滤。
        • RR级别全锁,会造成性能大幅下降。
    • 类型:
      • 共享锁

      • 排它锁(写锁)
        当前读:select for update 、update 、delete,为了更新需要加行级锁。
        有没有索引/唯一索引/非唯一索引/隔离等级(RC/RR)四种情况来分析锁
        RC会出现幻读(删除时插入非唯一索引记录,删除后还可以查到)。

      • 死锁:
        并发事务,互相拥有对方需要加锁对象的锁,导致加锁失败。

    相关文章

      网友评论

          本文标题:MySQL架构体系设计深入剖析篇学习笔记

          本文链接:https://www.haomeiwen.com/subject/ziwrbktx.html