美文网首页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内存数据对象

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