InnoDB架构
后台线程
主要作用:
- 负责刷新内存池中的数据,保证缓冲池的内存缓冲的是最近的数据(数据加载 和 脏页问题处理)
- 已修改的数据文件刷新到磁盘文件(有的数据在内存中发生改变回写到磁盘里 回写有很多方式)
- 保证数据库发生异常的情况下InnoDB能恢复到正常状态。(数据库最重要的功能)
Master Thread 。负责将缓冲池的数据异步刷新到磁盘,保证数据的一致性,包括
- 脏页的刷新
- 合并插入缓存(INSERT BUFFER)(数据插入,需要把新插入的数据合并)
- UNDO页的回收(存放在page)
- Master Thread具有最高的线程优先级别,内部由多个循环组成:主循环(loop),后台循环(backgroup loop),刷新循环(flush loop),暂停循环(suspend loop),Master Thread根据数据库运行状态在以上循环切换。
IO Thread InnoDB大量使用异步IO(AIO)来处理请求,来提高数据库性能。
- 有4类IO线程。
- write
- read
- insert buffer
- log
- 除了write和read,其他线程都是只有一个,通过
show variables like 'innodb_%io_threads'
来查看write和read的线程数 - 通过
show engine innodb status
来查看IO线程的情况
Purge Thread。事务被提交后,undolog就不需要了,Purge Thread用来回收已经分配的undo log页。
注意:Purge Thread需要离散地读取undo页。
Page Cleaner Thread 1.2以后引入,将Master Thread中刷新脏页的工作移至该线程。
内存池
主要工作:
- 维护所有进程/线程需要使用的多个内部数据结构(通过数据结构保证功能的实现)
- 缓存磁盘上的数据,方便快速地读取,同时对磁盘文件数据修改之前在这里缓存
- 重做日志缓存(等会聊一下)
InnoDB内存池主要有以下部分
缓冲池
InnoDB是基于磁盘存储的,并将其中的记录按照页的方式进行管理。
而缓冲池就是一块内存区域,主要缓冲数据页和索引页。
InnoDB中对页的读取操作,首先判断该页是否在缓冲池中,若在,直接读取该页,若不在则从磁盘读取页数据,并存放在缓冲池中。如果没有空间了,那么就进行LRU
对页的修改操作,首先修改在缓冲池中的页,再以一定的频率(Checkpoint机制)刷新到磁盘。
参数:innodb_buffer_pool_size设置缓冲池大小
LRU List 、Free List、FlushList
缓冲池是一个很大的内存区域,存储各种各样的页,页的默认大小是16KB。
缓冲池的数据页由下面3个列表组成,列表的item都是页。
- LRU List 主要存储数据页
- Free List 存储空闲的页
- Flush List 存储脏页
LRU List
LRU List使用LRU(Lastest Recent Used)算法:
- 使用最频繁的放在列表前端
- 使用最少的放在末端
- 当缓冲池不够的时候,优先释放末端的页
- 新页进入缓冲池后,放在末端开始37%的位置,这个位置称为midpoint。通过
show variables like 'innodb_old_blocks_pct'
来查看。
- midpoint前的称为new,是最活跃的数据
- 后的称为old,是最不活跃的数据
- 如果缓冲池已满,删除列表末端的页
- 页从old升级为new,称为page made yound
- 页没有从old升级为new(应该指一直在old中,直至被删除),称为page not made yound
Free List
数据库启动时,由于缓冲池是空的,这时页都存储在Free列表中(注意Free列表中的页都是没有数据的,或者数据已没有用)
当需要放新的一页到缓冲池:
* 首先查看Free列表是否有空闲的页
* 如果有,使用
* 如果没有。从LRU列表中删除末端页。
Flush List
当数据被修改后,会直接写重做日志和修改缓冲池数据,然后直接返回事务执行成功,这时候数据还没有落到硬盘的。(如果这时候数据库宕机,可以通过重做日志来恢复数据)。
所以就会存在一种状态,就是缓冲池的数据和硬盘的数据不一致。这时候缓冲池的这一页称为脏页(注意是缓冲池的数据比硬盘新)。
脏页就存放在Flush List中,脏页也会存储在LRU List中。
Mysql会定期把Flush List的脏页同步到硬盘,这个操作叫Checkpoint。
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 137428992
Dictionary memory allocated 102398
Buffer pool size 8191
Free buffers 7891
Database pages 300
Old database pages 0
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 266, created 34, written 36
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 300, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]
通过show engine innodb status
命令可以查看InnoDB的当前状态。
- BUFFER POOL AND MEMORY 是缓冲池信息
- Buffer pool size 8191 是缓冲池总大小,单位是页数量
- Free buffers 7891 Free List的大小
- Database pages LRU List的大小
- Old database pages LRU List中old部分的大小
- Modified db pages Flush List的大小
- LRU len: 300, unzip_LRU len: 0 LRU List的大小和压缩数据列表的大小