什么是数据库的“缓存池”?( 五 )


什么是数据库的“缓存池”?

文章插图
 
12、动态调整 Buffer Pool 的大小到此为止,本文已经详细的介绍了 Buffer Pool 的内存结构,它的数据是如何存放的,如何刷磁盘的,又是如何加载的,以什么样的形式存在的等等知识点,下面我们继续挖掘,将 Buffer Pool 的相关知识点一次说个够 。我们现在来讨论下 Buffer Pool 的大小能否动态调整 。
假设我们现在的 Buffer Pool 的大小是 2GB大小,现在想将其扩大到 4GB,现在说一下如果真的要这么做,我们的 MySq 需要做哪些事情 。首先,MySQL 需要向操作系统申请一块大小为 4G 的连续的地址连续的内存空间,然后将原来的 Buffer Pool 中的数据拷贝到新的 Buffer Pool 中 。
这样可能吗?如果原来的是8G,扩大到 16G,那这个将原来的数据复制到新的 Buffer Pool 中是不是极为耗时的,所以这样的操作 MySQL必然是不支持的 。但实际上这样的需求是客观存在的,那 MySQL是如何解决的呢?
为了处理这种情况,MySQL设计出 chunk (http 协议中也有使用到这个思想,所以我们会发现很多技术的优秀思想都是在相互借鉴)机制来解决的
# 什么是chunk机制chunk是 MySQL 设计的一种机制,这种机制的原理是将 Buffer Pool 拆分一个一个大小相等的 chunk 块,每个 chunk 默认大小为 128M(可以通过参数innodb_buffer_pool_chunk_size 来调整大小),也就是说 Buffer Pool 是由一个个的chunk组成的假设 Buffer Pool 大小是2GB,而一个chunk大小默认是128M,也就是说一个2GB大小的 Buffer Pool 里面由16个 chunk 组成,每个chunk中有自己的缓存页和描述数据,而 free 链表、flush 链表和 lru 链表是共享的
什么是数据库的“缓存池”?

文章插图
 
如果说有多个 Buffer Pool,那就是这样
什么是数据库的“缓存池”?

文章插图
 
说到这里好像还是没有说到 MySQL到底是如何通过 chunk 机制来调整大小的 。实际上是这样的,假设现在 Buffer Pool 有 2GB,里面有16个chunk,现在想要扩大到 4GB,那么这个时候只需要新申请一个个的 chunk 就可以了 。
这样不但不需要申请一块很大的连续的空间,更不需要将复制数据 。这样就能达到动态调整大小了(不会还有人问:这只是扩大,怎么缩小呢?gun) 。不得不说 MySQL真机智 。
13、生产环境如何设置 Buffer Pool 大小Buffer Pool 是不是越大越好,理论上是的 。那如果一个机器内存是16GB那分配给 Buffer Pool 15GB,这样很显然是不行的,因为操作系统要占内存,你的机器上总会运行其他的进行的吧?那肯定也是需要占用内存的 。根据很多实际生产经验得出得比较合理的大小是机器内存大小的(50%~60%) 。
最后一起来看看你的 INNODB 的相关参数,命令是show engine innodb status
show engine innodb status;---------------------- Buffer PoolAND MEMORY------------------------Buffer Pool 的最终大小Total memory allocated--Buffer Pool 一共有多少个缓存页 Buffer Poolsize-- free 链表中一共有多少个缓存也是可以使用的Free buffers-- lru链表中一共有多少个缓存页Database pages -- lru链表链表中的冷数据区一共有多少个缓存页Old database pages-- flush链表中的缓存页的数量Modified db pages-- 等待从磁盘上加载进来的缓存页的数量Pending reads -- 即将从lru链表中刷入磁盘的数量,flush链表中即将刷入磁盘的缓存页的数量Pending writes: LRU 0, flush list 0, single page 0-- lru链表的冷数据区的缓存页被访问之后转移到热数据区的缓存页的数量,以及冷数据区里1s之内被访问但是没有进入到热数据区的缓存页的数量Pages made young 260368814, not young 0-- 每秒从冷数据转移到热数据区的缓存页的数量,以及每秒在冷数据区被访问但是没有进入热数据区的缓存页的数量332.69 youngs/s, 0.00 non-youngs/s-- 已经读取创建和写入的缓存页的数量,以及每秒读取、创建和写入的缓存页的数量Pages read 249280313, created 1075315, written 32924991 359.96 reads/s, 0.02 creates/s, 0.23 writes/s-- 表示1000次访问中,有多少次是命中了BufferPool缓存中的缓存页,以及每1000次访问有多少数据从冷数据区转移到热数据区,以及没有转移的缓存页的数量 Buffer Poolhit rate 867 / 1000, young-making rate 123 / 1000 not 0 / 1000-- lru链表中缓存页的数量LRU len: 8190-- 最近50s读取磁盘页的总数,cur[0]表示现在正在读取的磁盘页的总数I/O sum[5198]:cur[0],14、结束语本篇文章我们详细讨论了 Buffer Pool 的内存结构,从 free 链表到 lru 链表,从 Buffer Pool 到 chunk,从磁盘中加载一个数据页到 Buffer Pool 到最后该数据页又被刷回到磁盘中的一整个过程,他的每一步都做了什么 。


推荐阅读