浅谈MySQL(三)InnoDB存储引擎

一、InnoDB体系架构

1、如下图所示,InnoDb存储引擎有多个内存块,这些内存块组成了一个大的内存池,负责维护所有进程、缓存磁盘上的数据,方便快速读取,同时对磁盘上的文件的数据修改之前在这里缓存、重做日志缓冲。

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

2、后台线程

a)Master Thread:核心后台线程,负责将缓冲池中的数据异步刷新到磁盘。

b)IO Therad:负责处理IO请求的回掉处理。

c)Purge Thread:回收已经使用并分配的undo页。

d)Page Cleaner Thread:新版本引入的,将脏页刷新操作放在单独的线程中完成。

3、内存

a)缓冲池:

虽然InnoDB存储引擎是基于磁盘存储的,但为了提高整体性能通常使用缓冲池技术,缓冲池简单的说就是一块内存区域。在数据库中进行读取页的操作,首先将磁盘的读到的页放入缓冲池中,下一次再读相同的页时,首先判断该页是否存在缓冲池。若在缓冲池中,称该页在缓冲池被命中,直接读取,否则读取磁盘。

对于数据库中页的修改,首先修改在缓冲池中的页,然后在一定频率刷新到磁盘上。需要注意的是,页从缓冲池刷新回磁盘的操作并不是在每次页发生更新时触发,而是通过一种成为Checkpoint的机制刷新回磁盘,这样是为了提高数据库整体性能。

所以,缓冲池的大小直接影响着数据库的整体性能。32位操作系统最大设置3G,但可以通过PAE来获得最大64G的内存支持,当然还是建议使用64位系统。可以用命令查看当前数据库设置的缓冲池大小
mysql> show variables like “innodb_buffer_pool_size”;
+————————-+———–+
| Variable_name           | Value     |
+————————-+———–+
| innodb_buffer_pool_size | 134217728 |
+————————-+———–+
1 row in set (0.01 sec)
可以看到,当前数据库设置的缓冲池才100多M,太小了。

下图很好的显示了Innodb存储引擎中内存的结构情况,缓冲池中缓存的数据类型也有多种。

InnoDb允许有多个缓冲池实例,每个页根据哈希值平均分配到不同的缓冲池实例中,这样可以有效的减少数据库内部的资源竞争,增加数据库的并发处理能力,可以通过参数innodb_buffer_pool_instances来进行配置,该默认配置为1.这些设置都可以通过修改配置文件修改。

b)LRU List、Free List、Flush List

缓冲池是一个很大的内存区域,其中存放着各种类型的页,那么InnoDB是如何管理的呢?

通常缓冲池是通过LRU(最近最少使用)算法来进行管理的,即最常使用的页放在LRU列表最前面,而最少使用的页放在后面,当缓冲池满时,首先释放列表最后的页。

在InnoDB存储引擎中,缓冲池中页的默认大小是16KB,同样使用LRU算法对缓存管理,但InnoDB存储引擎对传统的LRU算法进行了一些优化,这里就不做详细介绍,有兴趣的朋友可以自行百度或翻阅相关书籍进行查看。当数据库刚启动时,LRU列表是空的,这时所有的页都存放在Free列表中,当需要从缓冲池分页时,首页从Free表中查找是否有可以使用的页,并将该页从free表中删除,直到Free表中没有,才开始LRU的算法管理缓冲池。

在LRU列表中的页被修改后,称该页为脏页,即缓冲池中的页和磁盘上的页数据不一致,这时数据库会通过checkpoint机制将脏页刷新回磁盘,而Flush列表中的也即为脏页列表,脏页既存在LRU列表也存在与Flush列表。LRU列表用来管理缓冲池中的页可用性,Flush列表用来管理将页刷新回磁盘。

c)重做日志缓冲

InnoDB存储引擎内存区域中除了缓冲池还有重做日志缓冲,意味着首先将重做日志信息先放入到这个缓冲区,然后按一定频率将其刷新到重做日志文件,这个缓冲一般不需要设置很大,一般情况下每一秒都会将重做缓冲日志刷新到日志文件,用户只需要保证每秒产生的事务量在这个缓冲大小内即可。该配置为innodb_log_buffer_size;一般情况下8M足矣。

d)额外的内存池这里不做介绍,有兴趣的可以自己查阅资料。

 

                                                   你们的支持是我前进的动力,感谢阅读!

发表评论