EasonYou / my-blog

It's my blog recording front-end
2 stars 0 forks source link

MySQL日志与事务 #8

Open EasonYou opened 4 years ago

EasonYou commented 4 years ago

整体架构

image

事务的基本概念

  1. 原子性 要么所有操作全部成功,要么全部失败回滚,不可能执行其中的一部分操作
  2. 一致性 失败后事务最终没有提交,所做的修改不会保存到数据库中
  3. 隔离性 事务所做的修改在最终提交前,对其他事务是不可见的
  4. 持久性 一旦事务提交,所做的修改就会永久保存到数据库中

以下从缓冲池和日志的角度,描述事务的提交

InooDB体系架构

InnoDB存储引擎有多个内存块,组成一个大的内存池,负责如下工作

其中,后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓存是最近的数据。此外将已修改的数据文件刷新到磁盘,同事保证数据库发生异常的情况下InnoDB能回复到正常运行状态

后台线程

  1. Master Thread 非常核心的后台线程,负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性

  2. IO Thread InnoDB存储引擎大量使用了AIO(Async IO异步IO)来处理IO请求,以提高性能。而IO Thread主要负责这些IO请求的回调处理

  3. Purge Thread 回收已提交事务后,不需要的undolog

内存

缓冲池

LRU List、FreeList和Flush List

  1. LRU

    • 缓冲池通过LRU(Lastest Recent Used,最近最少使用)算法进行管理
    • 最频繁使用的夜放在LRU列表的前端,最少使用的放在尾端
    • 不能存储新读的页时,首先释放LRU尾端的页(页的大小默认为16kb)
    • InnoDB的LRU算法不是朴素的LRU算法,加入了midpoint位置
    • 默认midpoint位置为5/8处,midpoint之前是old列表、之后是new列表(活跃的热点数据在new列表)
    • 为了防止热点数据从LRU列表中擦除,引入了innodb_old_blocks_time表示读取到mid位置后等待多久才会被加入到LRU列表的热端
  2. Free list

    • 当数据库刚启动,LRU列表是空的,此时页都存放在Free列表中
    • 会先从Free列表中查找是否有可用的空闲页,如有,则放到LRU列表中,否则根据LRU算法淘汰列表末尾的页(不活跃的部分),分配给新页
    • InnoDB的策略是尽量使用内存,因此对于一个长期运行的库来说,未被使用的页很少
  3. Flush list

    • Flush列表中的页都为脏页列表,但脏页也存在于LRU列表中
    • LRU列表用来管理缓冲池中页的可用性,Flush列表用来管理将页刷新回磁盘,二者互不影响

redo log

redo log buffer

redo log file

checkpoint技术

checkpoint本身是缓冲池 解决了以下问题

  1. 缩短数据库的回复时间
  2. 缓冲池不够用时,将页刷新到磁盘
  3. 重做日志不可用时,刷新脏页

具体来说

redo log与bin log

image

总结

本文大致描述了事务、缓冲池、checkpoint、日志之间的关联,但还有许多细节需要深究。例如redo log以及undo log的关系、checkpoint的运行机制等等。

参考文档

  1. MySQL技术内幕(InnoDB存储引擎)
  2. 高性能MySQL