Mysql Innodb体系结构

Innodb体系结构

  • Innodb存储引擎主要包括内存池以及后台线程。
  • 内存池:多个内存块组成一个内存池,主要维护进程/线程的内部数据、缓存磁盘数据,修改文件前先修改内存、redo log
  • 后台线程:刷新内存池中的额

内存

缓冲池

  • Innodb的数据以页的形式存储在磁盘,所以采用内存做为缓存页数据。
  • 读页数据时,先将磁盘上的页数据“FIX”到缓冲池,下次读便可直接从缓冲池中读。
  • 修改数据时,先修改缓冲池中的页数据,而后刷新到磁盘,并非每次都刷新而是经过Checkpoint机制刷新到磁盘。
  • 数据页类型:索引页、数据页、undo页、插入缓冲(insert buffer)、自适应哈希索引、锁信息、数据字典信息等
  • 缓存池经过LRU算法管理。

LRU、Free List、Flush List

  • 普通LRU:最频繁的处于列表前端,最少使用处于尾端,先释放列表尾端的页。
  • Innodb LRU:在LRU队列中加入midpoint位置,默认值5/8,表示新读取的页加入到列表的5/8位置。midpoint以后列表成为old表,以前称为new表。即列表尾端到表尾37%为old表,其他为new表。new表存放活跃数据。
  • Free List:数据库启动时LRU表为空,页均存放在Free List中。须要使用时从该表中获取。
  • Flush List管理缓存中被修改过的页。
  • unzip_LRU,压缩页大小为一、二、四、8KB,其仍是属于LRU管理。unzip_LRU对不一样大小页分开管理,采用伙伴算法分配内存。

redo log buffer

redo log先都写入该buffer,然后按必定频率刷新到磁盘(1s/次),默认8M。其刷到磁盘主要一下几个状况:php

  1. Master Thread每秒执行一次。
  2. 事物提交时。
  3. redo log buffer剩余空间小于1/2。

额外的内存池

对一些数据结构自己的内存分配是从额外内存池分配。html


线程

Master Thread

负责将缓存池中的数据异步刷新到磁盘,包括脏页。合并插入缓存(INSERT BUFFER)、UNDO页的回收等。前端

IO Thread

Innodb中大量使用AIO处理写请求,IO Thread则主要处理这些请求的回调,包括write、read、insert buffer和log IO Thread。linux

Purge Thread

主要用来回收undo log,Innodb1.1以前由Master Thread负责。算法

Page Cleaner Thread

清理已提交事物的UNDO log。数据库


Checkpoint

事务型数据库通常采用Write Ahead Log策略,当事物提交时先写redo log然后修改内存中的页。当数据库宕机对于还未写入磁盘的修改数据能够经过redo log恢复。Checkpoint做用在于保证该点以前的全部修改的页均已刷新到磁盘,这以前的redo log在恢复数据时能够不须要了。windows

Sharp Checkpoint

发生在数据库关闭时,将全部脏页写入磁盘,数据库运行时通常不使用。缓存

Fuzzy Checkpoint

只刷新部分部分脏页。数据结构

  1. Master Thread Checkpoint:Master Thread异步已必定频率刷新必定比例脏页。
  2. Flush_LRU_LIST Checkpoint:为了保证LRU中有必定数量的空闲页,Page Clear Thread将对LRU中尾端页进行移除,若是存在脏页则作刷新。
  3. Async/Sync Flush Checkpoint:为了保证redo log循环使用(覆盖),对于须要将redo文件中不可用的脏页进行刷新到磁盘。
  4. Dirty Page too much Checkpoint:脏页数量太多。

Master Thread工做方式

Innodb 1.2.x以前

主要包括主loop、background loop、flush loop和suspend loop。其中的参数能够配置。异步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
while ( true ){
 
     //差很少1s一次
     for ( int  in  0..9){
         刷新日志缓存到磁盘
         //1s内的统计值
         if  IO < 5
             合并插入缓存
         if  脏页比例 > 预约值
             刷新部分脏页(不超过100)
         if   没有用户活动
             进入background loop{
                 删除无用undo页
                 合并20个插入缓冲
                 可能跳到flush loop{
                     可能跳到suspend loop
                 }
                 跳回主loop
             }
         sleep 1s;
     }
     //差很少10s一次
     if  IO < 200  //10s内
         刷新100个脏页到磁盘
     合并最多5个插入缓冲
     刷新日志缓冲
     删除无用undo
     刷新100或10个脏页
}

  

Innodb 1.2.x

Master Thread中的脏页刷新功能彻底由Page Cleaner Thread执行。

  

nnodb关键特性

插入缓冲

  • 当插入数据须要更新非汇集索引时,若是每次都更新则须要进行屡次随机IO,所以将这些值写入缓冲对相同页的进行合并提升IO性能。
  • 插入非汇集索引时,先判断该索引页是否在缓冲池中,在则直接插入。不然写入到Insert Buffer对象。
  • 条件:二级索引,索引不能是unique(由于若是是unique则必须保证惟一性,此时得检查全部索引页,仍是随机IO了)
  • Change Buffer:包括Insert Buffer、Delete Buffer、Purge Buffer,update操做包括将记录标记为已删除和真正将记录删除两个过程,对应后两个Buffer。
  • Insert Buffer内部是一颗B+树
  • Merge Insert Buffer三种状况:
    1. 对应的索引页被读入缓冲池。
    2. 对应的索引页的可用空间小于1/32,则强制进行合并。
    3. Master Thread中的合并插入缓冲。

两次写

在对脏页刷新到磁盘时,若是某一页还没写完就宕机,此时该页数据已经混乱没法经过redo实现恢复。innodb提供了doublewrite机制,其刷新脏页步骤以下:

1. 先将脏页数据复制到doublewrite buffer中(2MB内存)
2. 将doublewrite buffer分两次,每次1MB写入到doublewrite磁盘(2MB)中。
3. 立刻同步脏页数据到磁盘。对于数据混乱的页则能够从doublewrite中读取到,该页写到共享表空间。

  

自适应哈希索引

InnoDB存储引擎会监控对表上索引的查找,若是观察到创建哈希索引能够带来速度的提高,则创建哈希索引,因此称之为自适应(adaptive) 的。自适应哈希索引经过缓冲池的B+树构造而来,所以创建的速度很快。并且不须要将整个表都建哈希索引,InnoDB存储引擎会自动根据访问的频率和模式 来为某些页创建哈希索引。

异步IO

linux和windows中提供异步IO,其能够对连续的页作合并连续页的IO操做使随机IO变顺序IO。

刷新邻接页

刷新页时判断相邻页是否也是脏页。

相关文章
相关标签/搜索