[NOTE-MySQL]InnoDB存储引擎

InnoDB 是事务安全的 MySQL 存储引擎。完整支持ACID事务,行锁设计,支持MCC,一致性非锁定读,支持外键,最有效利用内存和CPU。

InnoDB体系架构

InnoDB有多个内存块,组成一个大的内存池,负责如下工作:

维护所有进程/线程需要访问的多个内部数据结构。

缓存磁盘上的数据,方便快速的读取,并且对磁盘文件的数据进行修改之前在这里缓存。

重做日志(redo log)缓冲

….

后台线程

后台线程主要作用是刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据。将已修改的数据文件刷新到磁盘文件,保证数据库发生异常情况InnoDB能恢复到正常的运行状态。

InnoDB默认后台线程有7个:

4个IO thread
由配置文件innodb_file_io_threads参数控制,默认为4,insert buffer thread、log thread、read thread、write thread。

1个master thread
由几个循环组成:
主循环loop、后台循环background loop、刷新循环flush loop、暂停循环suspend loop。

主循环:每秒钟的操作和没10秒的操作。

每一秒的操作包括:
日志缓冲刷新到磁盘,即使这个事务还没有提交(总是)
合并插入缓冲(可能)看发生的IO次数是否小于5次,小于才合并插入缓冲
至多刷新100个InnoDB的缓冲池中的脏页到磁盘(可能)看脏页比例
如果当前没有用户活动,切换到background loop(可能)

每10秒操作:
刷新100个脏页到磁盘(可能)是否小于200次IO操作
合并至多5个插入缓冲(总是)
将日志缓冲刷新到磁盘(总是)
删除无用的Undo页(总是)full purge时,判断之前删除的行,是否可以删除。
刷新100个或者10个脏页到磁盘(总是)小于70%只刷新10 否则刷新100
产生一个检查点(总是) fuzzy echkpoint,不把脏页写入磁盘,而是将最老的日志序列号的页写入磁盘。

后台循环background loop:当前没有用户活动或者数据库关闭时
删除无用的Undo页(总是)
合并20个插入缓冲(总是)
跳回到主循环(总是)
不断刷新100个页,直到符合条件(可能,跳转到flush loop中完成)

如果flush loop中没什么事情可做,会切换到suspend loop

1个锁(lock)监控线程

1个错误监控线程

内存

缓冲池 buffer pool:
由innodb_buffer_pool_size决定大小,占最大块内存,存放各种数据的缓存。

InnoDB总是将数据库文件按页(每页16K)读取到缓冲池,然后按最近最少使用算法来保留在缓冲池中的数据。
如果数据库文件需要修改,总是首先修改再缓冲池中的页,然后再按照一定的频率将缓冲池脏页刷新到文件。

通过show engine innodb status可以查看使用情况

缓冲池中缓存的数据页类型有:索引页、数据页、undo页、插入缓冲insert buffer、自适应哈希索引、InnoDB存储的所信息、数据字典信息等。不只是缓存索引页和数据页。

重做日志缓冲池 redo log buffer:
由innodb_log_buffer_size决定大小,不需要太大,理论上每一秒都会将重做日志缓冲刷新到日志文件。

额外内存池 additional memory pool:
InnoDB引擎中,对内存的管理是通过一种称为内存堆的方式进行的。在对一些数据结构本身分配内存时需要从额外的内存池中申请,当该区域内存不够时,会从缓冲池中申请。

0条留言