前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL中的InnoDB 体系结构(中)

MySQL中的InnoDB 体系结构(中)

作者头像
jeanron100
发布2019-03-07 14:31:48
1.3K0
发布2019-03-07 14:31:48
举报

这是学习笔记的第 1894 篇文章

InnoDB的缓存池管理技术

在开始这部分内容之前,我们需要理清buffer和cache的差别,因为在数据库层面会有大量的buffer和cache的术语,我们在学习的时候非常容易混淆。

Buffer的本意是缓冲,cache是缓存,计算机术语里面有buffer cache, page cache,和数据库里的含义是相似的。

计算机领域中处理磁盘IO读写的时候,基于cpu,memory,disk有这样一个示意图:

其中page cache是文件系统层面的缓存,数据库层面最直观的就是第一次查询数据的时候会慢一些,之后就会快得多,整个过程是把磁盘里的数据加载到这个缓存里面。

另外一部分是buffer cache,其实指的是磁盘等块设备的缓冲,比如内存里的数据要写入磁盘文件,是一个异步的过程,而且为了防止断电丢失数据库,会按照一定的策略把数据刷新落盘。如果结合最开始的InnoDB体系结构图,其实整体要表达的含义是类似的。

怎么理解MySQL里面的缓存池管理呢,我们可以先使用show engine innodb status看一下缓冲池和内存的输出内容,按照关键字“BUFFER POOL AND MEMORY”查看,输出如下:

----------------------

BUFFER POOL AND MEMORY

----------------------

Total large memory allocated 33533460480 #由innodb分配的总内存为32G

Dictionary memory allocated 14596467

Buffer pool size 1965840 #缓冲池分配的页数

Free buffers 1633878 #缓冲池空闲页数

Database pages 326446 #LRU列表中分配的数据页数,包含young sublist和old sublist

Old database pages 120340 #LRU中的old sublist部分页的数量

Modified db pages 0 #脏页的数量

Pending reads 0 #挂起读的数量

Pending writes: LRU 0, flush list 0, single page 0 #挂起写的数量

Pages made young 9, not young 0 #LRU列表中页移动到LRU首部的次数,因为该服务器在运行阶段改变没有达到innodb_old_blocks_time阀值的值,因此not young为0

0.00 youngs/s, 0.00 non-youngs/s #表示每秒young和non-youngs这两类操作的次数

如果理解了上面的输入含义,也就基本理解了缓冲池的一些基本含义。

这里要隆重介绍下InnoDB里的LRU技术,也是在数据库的缓存设计中都会使用的算法。

LRU本质是尽可能让数据页在缓存中存在,提高访问效率,但是缓存是有限的,怎么能够减少重复的页加载频率呢,InnoDB的LRU是一种定制化的算法,首先它会有一个列表,我们叫LRU LIST,上面存放了一些数据页,这里就是Database pages 326446 ,大约是5G左右,除此之外可用的也页为:Free buffers 1633878 ,大约是25G左右,如果你比较细心,拿出笔算一下,其实会发现Free buffers +Database pages的值和Buffer pool size的大小是不相等的,其实还有其他的一些其他缓冲池的页被分配利用,比如自适应哈希索引,Lock信息等,它们的管理不是基于LRU的。

回到LRU算法,InnoDB在LRU列表中加入了参考点,也叫midpoint。传统的LRU算法当访问到的页不在缓冲区是直接将磁盘页数据调到缓冲区队列;而InnoDB并不是直接插入到缓冲区队列的队头,而是插入LRU列表的midpoint位置。这个算法称之为midpoint insertion stategy。默认配置插入到列表长度的5/8处,和数学中的黄金分割(0.618)很接近,midpoint由参数innodb_old_blocks_pct控制,我们来简单验算验证一下,可以看到是很接近的值:

mysql> select 5/8,1-120340/326446 ,100-@@innodb_old_blocks_pct;

+--------+-----------------+-----------------------------+

| 5/8 | 1-120340/326446 | 100-@@innodb_old_blocks_pct |

+--------+-----------------+-----------------------------+

| 0.6250 | 0.6314 | 63 |

+--------+-----------------+-----------------------------+

midpoint之前的列表称之为new列表,也叫young sublist或者sublist of new block区域,里面的数据可以理解为热数据。

之后的列表称之为old列表,也叫old sublist或者sublist of old block区域,它们的关系可以参考如下图所示。

但是有了参照点怎么有效的管理呢,一些全表扫描的表如果进入sublist of new block区域,整个LRU就会是性能的瓶颈了,而且mid位置的页也不是永久的,这种情况也叫缓存污染。为了解决这个问题,InnoDB存储引擎引入了innodb_old_blocks_time来表示页读取到mid位置之后需要等待多久才会被加入到LRU列表的热端。可以通过设置该参数保证热点数据不轻易被刷出,这个参数值默认为1000(毫秒)。

所以这个时候反过来看”BUFFER POOL AND MEMORY”部分的输出就不难理解了,如果你在线上环境查看InnoDB的状态输出信息,会看到有多个BUFFER POOL的输出,BUFFER POOL会从0开始,

----------------------

INDIVIDUAL BUFFER POOL INFO

----------------------

---BUFFER POOL 0

Buffer pool size 245730

Buffer pool size, bytes 0

Free buffers 204625

Database pages 40414

Old database pages 14898

Modified db pages 0

Pending reads 0

这个是通过参数 innodb_buffer_pool_instances开启了多个缓存池,把需要的数据页可以通过hash算法指向不同的缓存池里面,可以进行并行的内存读写,在高IO负载的情况下性能提升明显。

InnoDB中的脏页管理

前面熟悉了InnoDB对于LRU的管理方式之后,有些同学可能有些迷茫,说还有FLUSH LIST,FREELIST这些和LRU LIST是什么关系呢,很多同学从入门到放弃就是因为这样的而一些关联关系没搞明白。

我们在InnoDB status里面输出的内容:

Free buffers 204625

其实这个是由FREE LIST来维护的。

对于脏页的管理,InnoDB有一个专门的列表FLUSH LIST,它的大小不是无限大或者动态的,在MySQL 5.6中引入了新参数innodb_lru_scan_depth来控制LRU列表中可用页数量,默认值为1000,即16M,它会影响现成Page Cleaner 刷新脏页的数量,从使用率和性能来说,不是越大越好。

为什么会需要FLUSH LIST来维护脏页的数量呢,主要目的是使InnoDB尽可能保持一个较新的状态,在系统崩溃之后能够快速的恢复,这个对于数据状态的记录中是通过Checkpoint LSN来维护的,我们下一小节会细说Checkpoint的技术。

而对于脏页的刷新比例,是由参数innodb_max_dirty_pages_pact来控制的(默认是75,而根据谷歌的压测推荐是80)

这几个LIST之间的关系类似于这样的形式:

其中buffer pool中的最小单位是页,分为三种类型

1) free page :此page未被使用,此种类型page位于FREE LIST中

2) clean page:此page被使用,对应数据文件中的一个页面,但是页面没有被修改,此种类型page位于LRU LIST中

3) dirty page:此page被使用,对应数据文件中的一个页面,但是页面被修改过,此种类型page位于LRU LIST和FLUSH LIST中

如果要查看Page的一些状态数据,可以使用如下的命令:

mysql> show global status like '%buffer_pool_pages%';

+-----------------------------------------+------------+

| Variable_name | Value |

+-----------------------------------------+------------+

| Innodb_buffer_pool_pages_data | 254103 |

| Innodb_buffer_pool_pages_dirty | 3340 |

| Innodb_buffer_pool_pages_flushed | 270022533 |

| Innodb_buffer_pool_pages_free | 7998 |

| Innodb_buffer_pool_pages_LRU_flushed | 0 |

| Innodb_buffer_pool_pages_made_not_young | 6324461464 |

| Innodb_buffer_pool_pages_made_young | 424446968 |

| Innodb_buffer_pool_pages_misc | 11 |

| Innodb_buffer_pool_pages_old | 93638 |

| Innodb_buffer_pool_pages_total | 262112 |

+-----------------------------------------+------------+

隔几秒钟再去查看,会发现页的数量就会有很明显的变化。

其中,脏页的比率计算可以参考如下的公式:

缓存池中的页就是在这三种状态中进行变换和调整,总体来说,FLUSH LIST是一种定量的管理方式,追求多快好省,而FREE LIST和LRU LIST是一种动态平衡的状态,大小要远远高于FLUSH LIST.

,

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 杨建荣的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • InnoDB的缓存池管理技术
  • InnoDB中的脏页管理
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档