一、概述
InnoDB 是事务安全的MySQL存储引擎,其特点是行锁设计、支持MVVC、支持外键、提供一致性非锁定读。
二、InnoDB 体系架构
2.1 后台线程
InnoDB 存储引擎是多线程的模型,后台有多个不同的线程负责处理不同的任务,不止下面四种线程。
2.1.1 Master Thread
Master Thread 是一个非常核心的后台线程,负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括脏页的刷新、合并插入缓冲、UNDO页的回收、刷新redo日志缓冲(每秒)等。
2.1.2 IO Thread
InnoDB 存储引擎大量使用了AIO (Async IO)来处理IO请求,IO Thread 负责这些IO请求的回调处理。
有四种IO Thread:write thread
、read thread
、insert buffer thread
、log thread
。write和read可有多个,通过参数设置个数,其他两个只有一个。
2.1.3 Purge Thread
事务被提交后,其所使用的Undo log可能不再需要,因此需要PurgeThread来回收已经使用并分配的undo页,可以设置多个 Purge Thread。
2.1.4 Page Cleaner Thread
作用是将脏页的刷新操作放入这个单独的线程,以减轻Master Thread的工作。
2.2 内存
2.2.1 缓冲池
InnoDB 使用缓冲池技术来提高数据库的整体性能,缓冲池的大小直接影响数据库的性能,通过innodb_buffer_pool_size
设置缓冲池大小。
在数据库中进行读取页的操作,首先将从磁盘读到的页存放在缓冲池中,这个过程称为将页“FIX”在缓冲池中。下次再读取该页时,判断是否在缓冲池中,在则命中。
对于数据库中页的修改操作,则首先修改缓冲池中的页,再以一定的频率刷新到磁盘上,使用Checkpoint的机制刷新回磁盘。
缓冲池中缓存的数据页类型有:索引页、数据页、Undo页、插入缓冲、自适应哈希索引、InnoDB存储的锁信息、数据字典信息等。其中没有Redo页缓冲。
InnoDB存储引擎中,缓冲池中页的大小默认为16KB。
InnoDB 支持多个缓冲池实例,可以增加数据库并发能力,默认是1个。
2.2.2 LRU List、Free List 和 Flush List
数据库中的缓冲池时通过LRU算法进行管理的。
InnoDB存储引擎从1.0.x版本开始支持压缩页的功能,可以压缩为1、2、4、8KB。这些页在unzip_LRU 列表中对不同压缩页大小的页分别管理。
2.2.3 重做日志缓冲(redo log)
2.2.4 额外的内存池
2.3 Checkpoint 技术
FLUSH_LRU_LIST Checkpoint
和 Async/Sync Flush Checkpoint
都在 Page Cleaner 线程
中进行。
三、InnoDB 关键特性
3.1 插入缓冲(Insert Buffer)
但一般每张表上不只一个聚集索引,更多情况下,一张表上有多个非聚集辅助索引,在进行插入操作时,对于非聚集索引叶子节点的插入不再是顺序的了,就需要离散访问非聚集索引页,这样性能比较差。
InnoDB 会判断当前一秒内发生的IO的次数是否小于5次,如果小于5次,InnoDB认为当前的IO压力很小,可以执行合并插入缓冲的操作。
Insert Buffer 的默认实现是一个B+树。
3.1.1 Change Buffer
3.1.2 Merge Insert Buffer
3.2 两次写(Double Write)
double write 可以提高数据页的可靠性。
缓冲区中每个页大小为16KB,double write buffer一次写入1MB。所以负载较大时,两个写入次数比为 1:64 。如果写入负载不大,则达不到1:64(比如1:32)。
3.3 自适应哈希索引(Adaptive Hash Index)