2-MySQL原理-InnoDB架构与内存管理

专栏目录

  1. 1-MySQL原理-设计架构
  2. 2-MySQL原理-InnoDB架构与内存管理
  3. 3-MySQL原理-InnoDB架构与数据一致性
  4. 4-MySQL原理-SQL执行原理
  5. 5-MySQL原理-存储引擎与索引结构
  6. 6-MySQL原理-索引匹配原则
  7. 7-MySQL原理-事务底层实现
  8. 8-MySQL原理-MySQL回表与解决方案
  9. 9-MySQL原理-执行计划最全详解
  10. 10-MySQL原理-索引失效索引匹配最全详解

InnoDB架构

2-MySQL原理-InnoDB架构与内存管理_第1张图片

后台线程

主要作用:

  • 负责刷新内存池中的数据,保证缓冲池的内存缓冲的是最近的数据(数据加载 和 脏页问题处理)
  • 已修改的数据文件刷新到磁盘文件(有的数据在内存中发生改变回写到磁盘里 回写有很多方式)
  • 保证数据库发生异常的情况下InnoDB能恢复到正常状态。(数据库最重要的功能)

Master Thread 。负责将缓冲池的数据异步刷新到磁盘,保证数据的一致性,包括

  • 脏页的刷新
  • 合并插入缓存(INSERT BUFFER)(数据插入,需要把新插入的数据合并)
  • UNDO页的回收(存放在page)
  • Master Thread具有最高的线程优先级别,内部由多个循环组成:主循环(loop),后台循环(backgroup loop),刷新循环(flush loop),暂停循环(suspend loop),Master Thread根据数据库运行状态在以上循环切换。

IO Thread InnoDB大量使用异步IO(AIO)来处理请求,来提高数据库性能。

  • 有4类IO线程。
    • write
    • read
    • insert buffer
    • log
  • 除了write和read,其他线程都是只有一个,通过show variables like 'innodb_%io_threads'来查看write和read的线程数
  • 通过show engine innodb status来查看IO线程的情况

Purge Thread。事务被提交后,undolog就不需要了,Purge Thread用来回收已经分配的undo log页。

注意:Purge Thread需要离散地读取undo页。

Page Cleaner Thread 1.2以后引入,将Master Thread中刷新脏页的工作移至该线程。

内存池

主要工作:

  • 维护所有进程/线程需要使用的多个内部数据结构(通过数据结构保证功能的实现)
  • 缓存磁盘上的数据,方便快速地读取,同时对磁盘文件数据修改之前在这里缓存
  • 重做日志缓存(等会聊一下)

InnoDB内存池主要有以下部分

2-MySQL原理-InnoDB架构与内存管理_第2张图片

缓冲池

InnoDB是基于磁盘存储的,并将其中的记录按照页的方式进行管理。
而缓冲池就是一块内存区域,主要缓冲数据页和索引页
InnoDB中对页的读取操作,首先判断该页是否在缓冲池中,若在,直接读取该页,若不在则从磁盘读取页数据,并存放在缓冲池中。如果没有空间了,那么就进行LRU
对页的修改操作,首先修改在缓冲池中的页,再以一定的频率(Checkpoint机制)刷新到磁盘。
参数:innodb_buffer_pool_size设置缓冲池大小

LRU List 、Free List、FlushList

缓冲池是一个很大的内存区域,存储各种各样的页,页的默认大小是16KB。

缓冲池的数据页由下面3个列表组成,列表的item都是页。

  • LRU List 主要存储数据页
  • Free List 存储空闲的页
  • Flush List 存储脏页
LRU List

LRU List使用LRU(Lastest Recent Used)算法:

  • 使用最频繁的放在列表前端

  • 使用最少的放在末端

  • 当缓冲池不够的时候,优先释放末端的页

  • 新页进入缓冲池后,放在末端开始37%的位置,这个位置称为midpoint。通过

    show variables like 'innodb_old_blocks_pct'
    

    来查看。

    • midpoint前的称为new,是最活跃的数据
    • 后的称为old,是最不活跃的数据
    • 如果缓冲池已满,删除列表末端的页
    • 页从old升级为new,称为page made yound
    • 页没有从old升级为new(应该指一直在old中,直至被删除),称为page not made yound
Free List

数据库启动时,由于缓冲池是空的,这时页都存储在Free列表中(注意Free列表中的页都是没有数据的,或者数据已没有用)

当需要放新的一页到缓冲池:
* 首先查看Free列表是否有空闲的页
* 如果有,使用
* 如果没有。从LRU列表中删除末端页。

Flush List

当数据被修改后,会直接写重做日志和修改缓冲池数据,然后直接返回事务执行成功,这时候数据还没有落到硬盘的。(如果这时候数据库宕机,可以通过重做日志来恢复数据)。
所以就会存在一种状态,就是缓冲池的数据和硬盘的数据不一致。这时候缓冲池的这一页称为脏页(注意是缓冲池的数据比硬盘新)。
脏页就存放在Flush List中,脏页也会存储在LRU List中。
Mysql会定期把Flush List的脏页同步到硬盘,这个操作叫Checkpoint。

----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 137428992
Dictionary memory allocated 102398
Buffer pool size   8191
Free buffers       7891
Database pages     300
Old database pages 0
Modified db pages  0
Pending reads      0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 266, created 34, written 36
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 300, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]

通过show engine innodb status命令可以查看InnoDB的当前状态。

  • BUFFER POOL AND MEMORY 是缓冲池信息
  • Buffer pool size 8191 是缓冲池总大小,单位是页数量
  • Free buffers 7891 Free List的大小
  • Database pages LRU List的大小
  • Old database pages LRU List中old部分的大小
  • Modified db pages Flush List的大小
  • LRU len: 300, unzip_LRU len: 0 LRU List的大小和压缩数据列表的大小

你可能感兴趣的:(#,MySQL,mysql,架构,数据库)