InnoDB是事务安全的MySQL存储引擎,类似于Oracle数据库的架构

InnoDB存储引擎概述

  • InnoDB存储引擎同MySQL数据库一样,在GUN GPL2 下发行。
  • MySQL 5.5开始是默认的表存储引擎
  • 第一个完整支、持ACID事务的MySQL存储引擎
  • 高性能、高可用、高可扩展存储引擎
  • 特点为:
    -- 行锁设计
    -- 支持MVCC
    -- 支持外键
    -- 提供一致性非锁定读
    -- 最有效地利用以及使用内存和CPU

InnoDB存储引擎的版本

从MySQL 5.1版本时,MySQL数据库允许存储引擎开发商以动态方式加载引擎,存储引擎的更新可以不受MySQL数据库版本的限制。MySQL 5.6版本中将InnDB 升级为1.2.x版本

InnoDB各版本区别

  • 老版本InnoDB:支持ACID、行锁设计、MVCC
  • InnoDB1.0.x:增加了compress和dynamic页格式
  • InnoDB1.1.x:增加了LinuxAIO、多回滚段
  • InnoDB1.2.x:增加了全文索引支持、在线索引添加

InnoDB体系架构

image.png
InnoDB存储引擎有多个内存卡,这些内存块组成了一个大的内存池,负责:

  • 维护所有进程/线程需要访问的多个内部数据结构
  • 缓存磁盘上的数据,方便快速地读取,同时在对磁盘文件的数据修改之前在这里缓存
  • 重做日志(redo logo)缓冲

后台线程

InnoDB存储引擎是多线程的模型,负责处理不同的任务

Master Thread

核心后台线程,将缓冲池中的数据同步刷新到磁盘,保证数据的一致性,包括脏页的刷新、合并插入缓冲、UNDO页的回收等

IO Thread

InnoDB存储引擎中大量使用了AIO来处理写IO请求,IO Thread 的工作主要是负责这些IO的回调(call back)处理

Purge Thread

事务被提交后,其所使用的undolog可能不再需要,因此需要Purge Thread 来回收已经使用并分配的undo页,减轻Master Thread的工作

Page Cleaner Thread

脏页的刷新操作放到改线程中来完成,减轻Master Thread的工作及对于用户查询线程的阻塞

内存

缓冲池

InnoDB存储引擎是基于磁盘存储的,在数据库系统中,由于CPU速度与磁盘速度之间速度差距大,通常使用缓冲池技术来提高数据库的整体性能。
缓冲池简单来说就是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库性能的影响。

  • 读取操作:首先将从磁盘读到的页存放在缓冲池中,这个过程称为将页“FIX”在缓冲池中。下一次再读相同的页时,首先判断该页是否在缓冲池中。若在,则直接读取,否则读取磁盘上的页
  • 修改操作:首先修改缓冲池中的页,然后再以一定的频率刷新到磁盘上。页从缓冲池刷新回磁盘的操作并不是在每次页发生更新时触发,为了提高数据库的整体性能通过Checkpoint的机制刷新回磁盘
    缓冲池的大小直接影响着数据库的整体性能
//查看缓冲池大小
SHOW VARIABLES LIKE'innodb_buffer_pool_size'

image.png

缓冲池内存对象

image.png
缓冲池中缓冲的数据页类型有:索引页、数据页、undo页、插入缓冲、自适应哈希索引、InnoDB存储的锁信息、数据字典信息等。
可以允许有多个缓冲池实例,每个页根据哈希值平均分配到不同缓冲池实例中。减少数据库内部的资源竞争,增加数据库的并发处理能力

//查看数据库缓冲池实例
SHOW VARIABLES LIKE 'innodb_buffer_pool_instances'

image.png

//观察每个缓冲池实例对象运行状态
show engine innodb status

image.png

LRU List、Free List和Flush List

InnoDB存储引擎对内存区域的管理

LRU List

数据库中的缓冲池是通过LRU(Latest Recent Used,最近最少使用)算法来进行管理的。即最频繁使用的页在LRU列表的最前端,而最少使用的页在LRU列表的尾端。当缓冲池不能存放新读取到的页时,将首先释放LRU列表中尾端的页。
InnoDB存储引擎中,缓冲池中页大小默认为16KB
LRU 列表加入了midpoint位置。新读取的页放入到LRU列表的midpoint位置,参数由innodb_old_pct控制。(如果放入LRU列表的首部,那么可能会造成热点数据页从LRU列表中移除,在下一次读取该页时,需要再次访问磁盘)

Free List

当数据库刚启动时,LRU列表是空的,即没有任何的页。页都存放在Free列表中。当需要从缓冲池中分页时,先从Free列表中那个查找是否有可用的空闲页,若有则将该页从Free列表中删除,放入到LRU列表中。否则根据LRU算法,淘汰LRU列表末尾的页,将该内存空间分配给新的页。






这个家伙很懒,啥也没有留下😋