目录
参考文章:一文了解InnoDB存储引擎
引言
InnoDB是能够保证事务安全的MySQL存储引擎。主要特点是:
- 支持行锁;
- 支持MVCC;
- 支持外键;
- 提供一致性非锁定读;
- 被设计用来有效利用以及使用内存和CPU;
关键点
详细参考文章,以及《mysql技术内幕》第二章内容。这里主要通过关键词记录关键点。
- 内存池(缓冲池)
本质:本质上是一块内存区域,因为在读写的速度:内存>磁盘,所以用内存来弥补磁盘速度慢的缺陷。
具体:在数据库中读取页的操作时,首先将磁盘读到的页存放在缓冲池中(称为把页“FIX”到缓冲池中)。下一次读某页时,判断该页在不在缓冲池中,在的话就直接在内存中被读取;不在的话,去磁盘中读取相应的页。
内存池关联问题:如何管理这么大的缓冲内存?--- 解决:LRU(Latest Recent Used,最近最少使用算法)算法。
LRU算法简述:最频繁使用的页在LRU列表的前端,相应的使用次数最少的页在列表的尾端。当缓冲池中满了,也是首先释放LRU列表尾端的页。
朴素的LRU存在问题:对于一个最新读取到的页,这可能不是一个热点页,如果直接将其放入LRU列表首部的话,某些SQL语句可能会把缓冲池中的其他热点页刷出去了,造成了热点页的流失。最坏的情况就是常见的索引或者数据的扫描,这类操作需要访问表中的许多页,甚至全部的页,那么如果读取这些页的时候直接将其放入LRU列表前端的话,就很可能把真正需要的热点数据页从LRU列表中挤掉了。下一次访问热点数据页的时候,需要重新访问磁盘,速度会变慢。
以上问题解决:
1)InnoDB对LRU做的优化 -- midpoint insertion strategy:增加midpoint位置(默认37)。最新访问的页,将其放在LRU列表的midpoint位置,默认在LRU列表长度的5/8处。midpoint位置之前的位置为new列表(较为活跃的数据页),之后的为old列表。
2)innodb_old_blocks_time:表示页读取到mid位置后,需要等待多长时间才会被加入到LRU列表的热端。
- 后台线程
本质:负责刷新内存池中的数据,保证其中缓存的是最近的数据;此外,将已经修改的数据文件以一定频率刷新到磁盘文件;保证在数据库发生异常时,InnoDB能够恢复。