美文网首页linux
MySQL-InnoDB内存数据对象

MySQL-InnoDB内存数据对象

作者: agile4j | 来源:发表于2018-10-26 22:02 被阅读1次

作者:刘仁鹏
参考资料:《MySQL技术内幕:InnoDB存储引擎》


1.序言

  • InnoDB允许有多个缓冲池实例,每个页根据哈希值平均分配到不同的缓冲池实例中,以减少数据库内部的资源竞争,可以通过参数innodb_buffer_pool_instances来进行配置
  • 可通过SHOW ENGIN INNODB STATUS或INNODB_BUFFER_POOL_STATUS来观察缓冲的状态
SHOW ENGINE INNODB STATUS\G

SELECT POOL_ID, POOL_SIZE, FREE_BUFFERS, DATABASE_PAGES FROM INNODB_BUFFER_POOL_STATUS\G

<center>图:InnoDB内存数据对象</center>


nnnn.png-94.8kBnnnn.png-94.8kB

2.具体实现

1.LRU List、Free List、Flush List

LRU列表

  • 数据库中的缓冲池是通过LRU(Latest Recent Used)算法来进行管理的。即:最频繁使用的页在LRU列表的前端,最少使用的页在LRU列表的尾端
  • 缓冲池中页的默认大小为16KB
  • InnoDB对传统LRU算法做了优化,加入了midpoint位置(midpoint insertion strategy)。即新读取到的页,并不直接放到LRU列表的首部,而是放到midpoint位置
  • 默认配置下,该位置在LRU列表长度的5/8处,midpoint位置可由参数innodb_old_blocks_pct控制
  • 这么做的目的是为了避免批量数据查询操作将LRU列表中的真实热点数据刷出
  • 为进一步解决批量操作刷出热点数据的问题,InnoDB还提供了innodb_old_blocks_time来表示页读取到mid位置后,需要等待多久才会被加入到LRU列表的热端。因此可在批量操作前将该值设大,操作完毕后再将该值设小。

Free列表

  • 当需要从缓冲池中分页时,会首先从Free列表中查找是否有可用的空闲页。如有,则将该页从Free列表中删除,放入LRU列表中。否则,淘汰LRU列表末尾的页,将该内存空间分配给新的页。
  • 观察方式:
SHOW ENGINE INNODB STATUS\G

SELECT POOL_ID, HIT_RATE, PAGES_MADE_YOUNG, PAGES_NOT_MADE_YOUNG FROM information_schema.INNODB_BUFFER_POOL_STATUS\G

SELECT TABLE_NAME, SPACE, PAGE_NUMBER, PAGE_TYPE FROM INNODB_BUFFER_PAGE_LRU WHERE SPACE = 1;
  • InnoDB支持压缩页的功能,将原本16KB的页压缩到1KB、2KB、4KB、8KB
  • 对于压缩页(非16KB的页),是通过unzip_LRU列表进行管理的。可通过SHOW ENGINE INNODB STATUS命令的unzip_LRU len查看。注意,unzip_LRU len是包含于LRU len的
  • unzip_LRU列表对不同大小的压缩页进行分别管理,通过伙伴算法分配内存

Flush列表

  • 在LRU列表中的页被修改后,称该页为脏页,即缓冲池中的页和磁盘上的页的数据产生了不一致,这时数据库会通过CHECKPOINT机制将脏页刷新回磁盘,而Flush列表中的页即为脏页列表
  • 注意:脏页既存在于LRU列表中,也存在在Flush列表中。LRU列表用来保证可用性,Flush列表用来保证一致性,二者互不影响
  • 通过元数据表INNODB_BUFFER_PAGE_LRU查看脏页时要加OLDEST_MODIFICATION > 0的查询条件

2.重做日志缓冲

  • InnoDB存储引擎首先将重做日志信息放到这个缓冲区,然后按一定频率刷新到重做日志文件
  • 重做日志缓冲大小默认为8M,可通过参数innodb_log_buffer_size控制。确保每秒产生的事务量在这个缓冲大小之内即可
  • 重做日志在以下三种情况下会将缓存刷到磁盘:
  1. Master每秒刷一次
  2. 每个事务提交时刷一次
  3. 重做日志缓冲剩余空间小于1/2时刷一次

3.额外的内存池

  • 在对一些数据结构本身的内存进行分配时,需要从额外的内存池中进行申请,当该区域内存不够时,会从缓冲池中申请
  • 例如:
  1. 每个缓冲池中的帧缓冲
  2. 对应的缓冲控制对象(这些对象记录了一些诸如LRU、锁、等待等信息)
  • 在申请了很大的InnoDB缓冲池时,也应考虑相应的增加额外内存池的大小

相关文章

  • MySQL-InnoDB内存数据对象

    作者:刘仁鹏参考资料:《MySQL技术内幕:InnoDB存储引擎》 1.序言 InnoDB允许有多个缓冲池实例,每...

  • Hibernate-ORM框架基础

    对象保存在内存中,内存不能永久保存数据,如果要永久保存就需要对象持久化(将对象存储到数据库中).关系型数据库存放关...

  • 第七天

    数组 数组是引用数据类型中的对象数据类型(特殊对象)创建一个数组,也要开辟一个堆内存,堆内存中存储数据对象中的键值...

  • 基于C++的通过内存映射实现进程间的数据交换

    VC++ 通过内存映射实现进程间的数据交换,创建内存映像对象,从内存映射对象读数据,将文件的视图映射到一个进程的地...

  • 浅谈内存管理及僵尸对象

    //--------------------内存管理 内存管理范围: 管理任何继承NSObject的对象,基本数据...

  • [转]深入探索C++对象模型(2)

    上一章讲过了关于类对象内存分布,对于nostatic数据将会放在对象内存空间中,static数据成员和nostat...

  • 对象

    对象数据类型数组Array、对象object、正则Regexp 、new Date()对象数据类型存储在堆内存中开...

  • 垃圾回收器GC

    内存溢出:无法为对象分配到内存内存泄漏:代码问题,一些无用的对象无法被GC回收(数据库连接) 如何判断对象是否已经...

  • InnoDB

    MySQL-InnoDB 架构 CheckPoint 已经被flush到页上的LSN。 刷盘策略 缩短数据库恢复时...

  • 面试题|Java|Redis

    Redis内存模型 Redis内存分配 数据 :Redis存储的数据对象 字符串、哈希、列表、集合、有序集合 进程...

网友评论

    本文标题:MySQL-InnoDB内存数据对象

    本文链接:https://www.haomeiwen.com/subject/whxrtqtx.html