指定内存不能为written


指定内存不能为written  

近期发现,文章长度若过长,包含的信息量较大,阅读所需时间也会随之增长。考虑到大家常常利用碎片时间阅读,我得出一个结论:文章过长可能不利于大家的吸收和消化。我决定缩短文章的长度,控制在2-3K字左右,以便大家能更快速地阅读。

之前有一篇文章《简单了解InnoDB原理》,主要介绍了缓冲池(Buffer Pool)、重做日志缓冲(Redo Log Buffer)、插入缓冲(Insert Buffer)和自适应哈希索引(Adaptive Hash Index)等基本概念。今天,我们来深入探讨一下InnoDB的内存结构。

InnoDB内存结构概述

InnoDB的内存结构主要包括Buffer Pool和Log Buffer两个主要区域。Buffer Pool是MySQL或InnoDB中非常重要的一部分,位于主存中,访问数据的效率高。我们可以将其暂时理解为像Redis那样的内存数据库。

Buffer Pool

Buffer Pool大约占据了宿主机80%的内存,因为它越大,能缓存的数据就越多,更多的操作都会发生在内存,从而提高效率。由于其存储的数据类型和数据量非常多,Buffer Pool在存储时会按照某些结构进行存储,并做一些特殊处理。否则,获取数据时没有捷径,只能遍历所有数据,这样的低效率操作无法支撑MySQL的高性能需求。

Buffer Pool被分成了许多页,每页可以存放很多数据,InnoDB会对这些数据做一些操作。InnoDB使用链表来这些页和页中存储的数据,页与页之间形成了双向链表,方便从当前页跳转到下一页。使用LRU(Least Recently Used)算法淘汰不经常使用的数据。

Log Buffer

Log Buffer用于存储即将刷入磁盘的日志,如Redo Log。它是InnoDB内存的重要组成部分。Log Buffer的默认值通常为16M,可以通过配置参数innodb_log_buffer_size进行调整。

当Log Buffer较大时,可以存储更多的Redo Log。在事务提交之前,我们不需要将Redo Log刷入磁盘,只需要将其放入Log Buffer即可。较大的Log Buffer可以更好地支持较大的事务运行。如果有事务大量更新、插入或删除行,适当增大Log Buffer的大小也可以减少部分磁盘I/O操作。

Buffer Pool的LRU算法

了解了InnoDB的内存结构后,我们详细看看Buffer Pool中的LRU算法是如何实现将最近未使用的数据过期的。

优化后的LRU

优化后的链表被分成了两部分:New Sublist和Old Sublist,分别占Buffer Pool的3/4和1/4。New Sublist存放访问较频繁的页,而Old Sublist存放访问不频繁的页。Old Sublist中的数据会在Buffer Pool剩余空间不足或有新页面加入时被移除。

新页被加入到链表后,会入到New Sublist和Old Sublist的交界处,这个位置被称为MidPoint。链表的数据来源有两部分:MySQL的预读线程预先加载的数据和用户操作,例如Query查询。

默认情况下,由用户操作进入Buffer Pool的数据会被立即放到链表的最前端,即New Sublist的Head部分。而MySQL启动时预加载的数据会被放入MidPoint,只有在被用户访问后才会放到链表的最前端。这样一来,即使这些数据在链表中,但因为未被访问,会被移动到Old Sublist中,直到被清理掉。

优化Buffer Pool的配置

在实际生产环境中,我们可以通过调整某些设置来提高Buffer Pool的性能。例如,我们可以分配更多的内存给Buffer Pool,以缓存更多的数据在内存中;当内存充足时,可以创建多个Buffer Pool实例,减少并发操作带来的数据竞争;我们还可以手动执行部分数据的预读请求,以预测即将到来的大量请求;我们还可以控制Buffer Pool将数据刷写到磁盘的频率,根据MySQL的负载动态调整。

如何查看MySQL中Buffer Pool的状态呢?我们可以通过命令“show engine innodb status”来查看。这个命令会显示InnoDB的整体状态,其中包含了Buffer Pool相关的监控指标。

自适应哈希索引

自适应哈希索引是配合Buffer Pool工作的一个功能。它使得MySQL的性能更加接近于内存服务器。如果要启用自适应哈希索引,可以通过更改配置innodb_adaptive_hash_index来开启。是否启用还需要根据具体的业务情况来决定。例如,如果业务特征是有大量的并发Join查询并且使用LIKE或%等通配符,那么自适应哈希索引可能并不适用。

Change Buffer

InnoDB的内存结构是一个复杂而重要的部分,通过了解其各个组件和功能,我们可以更好地优化MySQL的性能。希望这篇文章能帮助大家更深入地理解InnoDB的内存结构和工作原理。

  指定内存不能为written