MYSQL InnoDB结构

187 阅读5分钟

InnoDB

几个重要特性

  • 插入缓冲(Insert Buffer)【性能提升】
  • 两次写(Double Write)【可靠性提升】
  • 自适应哈希索引(Adaptive Hash Index)
  • 异步IO(Async IO)
  • 刷新邻接页(Flush Neighbor Page)

体系结构

内存:多个内存块构成了一个大的内存池子

  • 存储了进程/线程需要访问的数据结构
  • 缓存磁盘数据方便读取,磁盘数据修改之前也先在内存修改:缓冲池的设计目的为了协调CPU速度与磁盘速 度的鸿沟。
  • Redo log 缓冲

存储引擎内存分布:buffer pool, redo log buffer, additional log buffer(额外内存池)

  1. Buffer Pool Buffer Pool 占据最大内存空间,引擎按照每页16k将文件读取到缓冲池中,使用LRU算法保留最近使用的数据;肮页(发生过数据修改的数据页)按照一定的频率flush到磁盘。缓冲页类型包括:索引页,数据页,undo页面,插入缓冲(insert buffer),自适应哈希索引(adaptive hash index),锁信息(lock info)页面。

InnoDB 允许有多个缓冲池,这样每个页可以通过hash平均分配到不同的pool,减少数据库内 部的资源竞争,增加数据库的并发处理能力。

  1. LRU list,free List and Flush List 通过LRU算法管理每个页面,但是并非完全LRU算法,而是新插入页面放到差不多末尾37%(为midpoint insertion strategy)位置。前63%成为new pages。pages made young显示了LRU列表中页移动到前端的次数,innodb_old_blocks_time减少热点数据页被刷新出去。若发生Buffer pool hit rate的值小于95%这种情况,观察是否是由于全表扫描引起的LRU列表被污染的问题。

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

  1. Redo log buffer InnoDB存储引擎首先将 重做日志信息先放入到这个缓冲区,然后按一定频率将其刷新到重做 日志文件。

  2. Insert Buffer:数据结构就是一棵B+树。 InnoDB 中有插入缓冲信息,但是Insert Buffer 和数据页一样在buffer pool是有物理空间的。 creat table t (id int auto_increment, name varchar(30), primary key(id),key(name)) name字段是非聚集索引(secondary index)插入时候性能并不好,因为数据是离散的。

insert_buffer.jpeg 首先对于非聚集索引的插入或更新操作,不是每一次直接插入到索引页中,而是先判断插入的非聚集索引页是否在缓冲池中。若在,则直接插入;若不在,则先放入到一个Insert Buffer对象中。给外部的感觉好像是树已经插入非聚集的索引的叶子节点,而其实是存放在其他位置。以一定的频率和情况进行Insert Buffer和辅助索引页子节点的merge(合并)操作,通常会将多个插入操作一起进行merge,这就大大的提升了非聚集索引的插入性能。只有满足下面两个必要条件时,InnoDB存储引擎才会使用Insert Buffer来提高插入性能:

  • 索引是非聚集索引
  • 索引不是唯一(unique)的 类似的还有Delete Buffer, Purge buffer
  1. Double Write Buffer两次写缓冲 一个16k页面只写了4k,称为写失效(parital page write),而redo log并不能恢复一个已经损坏了的页。解决这个:宕缓冲池刷新脏页时候不直接写入磁盘, 而是先copy脏页到doublewrite buffer,dw buffer分两次写入到ci pan 。

5.额外的内存池 是每个缓冲池中的帧缓冲(frame buffer)还有对应的缓冲控制对象(buffer control block),这些对象 记录了一些诸如LRU、锁、等待等信息,而这个对象的内存需要从额 外内存池中申请。

Checkpoints 技术

Checkpoint 解决一下问题:

  • 缩短数据库的恢复时间
  • 缓冲池不够用时,将脏页刷新到磁盘
  • 重做日志不可用时,刷新脏页 两种check point:
  1. Sharp Checkpoint:发生在数据库关闭时将所有的脏页都刷新回磁盘,运行时执行sharp严重影响性能
  2. Fuzzy Checkpoint:差不多以每秒或每十秒的速度从缓冲池 的脏页列表中刷新一定比例的页回磁盘,不会阻塞用户的查询

线程

  • 后台线程负责刷新数据保证数据新鲜
  • 将提交的修改刷新到磁盘
  • 保证数据异常情况下innodb 能正常使用

默认情况下默认后台线程有七个:四个IO(read,insert,write,log)线程,一个master线程,一个log线程,一个lock锁监控线程,一个错误监控线程

Master Thread:最高优先级线程

InnoDB存储引擎的主要工作都是在一个 单独的后台线程Master Thread中完成的;内部由多个循环 (loop)组成:主循环(loop)、后台循环(backgroup loop)、刷新 循环(flush loop)、暂停循环(suspend loop)。

  1. LOOP 主线程的操作:日志刷新到磁盘,合并插入缓冲,刷新100个脏页到磁盘,没有活动切换到backup loop;实际上有两大部分的操作——每秒钟的操作和每10秒的操作,每秒操作这几个的一部分,具体看情况,十秒钟操作完成所有操作。

  2. Backup Loop 若当前没有用户活动(数据库空闲 时)或者数据库关闭(shutdown),就会切换到这个循环。 操作:删除无用的Undo页(总是),合并20个插入缓冲(总是),跳回到主循环(总是),不断刷新100个页直到符合条件(可能,跳转到flush loop中完 成)。