InnoDB缓冲池是通过LRU算法来管理page的。频繁使用的page放在LRU列表的前端,最少使用的page在LRU列表的尾端,缓冲池满了的时候,优先淘汰尾端的page。

InnoDB中的LRU结构

InnoDB引擎中page的默认大小为16KB,InnoDB对传统的LRU算法做了一些优化

LRU列表被分成两部分,midpoint点之前的部分称为new列表,之后的部分称为old列表,new列表中的页都是最为活跌的热点数据。midpoint的位置通过参数innodb_old_blocks_pct来设置。

参数innodb_old_blocks_pct默认值为37,表示新读取的page将被插入到LRU列表左侧的37%(差不多3/8的位置)。

mysql> show variables like 'innodb_old_blocks%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| innodb_old_blocks_pct | 37 |
| innodb_old_blocks_time | 0 |
+------------------------+-------+

为什么不采用传统的LRU算法?

若直接将读取到的page放到LRU的首部,那么某些SQL操作可能会使缓冲池中的page被刷出。常见的这类操作为索引或数据的扫描操作。这类操作访问表中的许多页,而这些页通常只是在这次查询中需要,并不是活跃数据。如果放入到LRU首部,那么非常可能将真正的热点数据从LRU列表中移除,在下 一次需要时,InnoDB需要重新访问磁盘读取,这样性能会低下。

同时,InnoDB进一步引入了另一个参数来管理LRU列表,这个参数就是innodb_old_blocks_time,用于表示page放到midpoint位置后需要等待多久才会被加入到LRU列表的new端成为热点数据。

LRU中page的变化

数据库启动时,LRU列表是空的,即没有任何page,这时page都存放在Free列表中。当需要从缓冲池中分页时,首先从Free列表中查找是 否有可用的空闲页,若有则将page从Free中删除,放入到LRU中。否则,根据LRU算法,淘汰LRU列表末尾的页分配给新的页。

当页从old部分进入到new部分时,此时发生的操作为page made young。因为innodb_old_blocks_time参数导致page没有从old移动到new部分称为page not made young。可以通过命令show engine innodb status来观察LRU列表及Free列表的状态。

----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 4395630592; in additional pool allocated 0
Dictionary memory allocated 28892957
Buffer pool size 262143
Free buffers 0
Database pages 258559
Old database pages 95424
Modified db pages 36012
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 72342127, not young 0
8.82 youngs/s, 0.00 non-youngs/s
Pages read 72300801, created 339791, written 13639066
8.56 reads/s, 0.35 creates/s, 3.79 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 258559, unzip_LRU len: 0
I/O sum[459]:cur[1], unzip sum[0]:cur[0]

Buffer pool size表示缓冲池共有262143个page,即262143 * 16K,约为4GB
    Free buffers表示当前Free列表中page的数量
    Database pages表示LRU列表中page的数量
    Old database pages表示LRU列表中old部分的page数量
    Modified db pages表示的是脏页(dirty page)的数量
    Pages made young表示LRU列表中page移动到new部分的次数
    youngs/s, non-youngs/s表示每秒这两种操作的次数
    Buffer pool hit rate表示缓冲池的命中率,该值若小于95%,需要观察是否全表扫描引起LRU污染
    LRU len表示LRU中总page数量

可以看到Free buffers与Database pages的和不等于Buffer pool size,这是因为缓冲池中的页还会被分配给自适应哈希索引,Lock信息,Insert Buffer等页,这部分页不需要LRU算法维护。

脏页(dirty page)

LRU列表中的page被修改后,称该页为脏页,即缓冲池中的页和磁盘上的页的数据产生了不一致。这时InnoDB通过Checkpoint机制将 脏页刷新回磁盘。而Flush列表中的页即为脏页列表。脏页既存在于LRU列表中,又存在于Flush列表中,二者互不影响。Modified db pages显示的就是脏页的数量。

重做日志缓冲

InnoDB引擎首先将重做日志信息先放到重做日志缓冲区(redo log buffer),然后按一定频率刷新到重做日志文件。重做日志缓冲不需要设置很大,一般每一秒都会刷新redo log buffer,配置的大小只需要保证每秒产生的事务在这个缓冲区大小之内即可。通过参数innodb_log_buffer_size为设置:

mysql> show variables like 'innodb_log_buffer%';
+------------------------+----------+
| Variable_name | Value |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+

在下列情况下会将重做日志缓冲中的内容刷新到磁盘重做日志文件中:

Master Thread每一秒中刷新一次
    每个事务提交时会刷新
    当重做日志缓冲区空间小于1/2时

额外内存池

额外的内存池用来对一些数据结构本身的内存进行分配,例如缓冲控制对象(buffer control block)记录的LRU,锁,等待等信息。额外的内存池不够时会从缓冲池中进行申请。因此,在申请了很大的InnoDB缓冲池时,额外的内存池也要适当 的调大。通过参数innodb_additional_mem_pool_size来设置大小。查看通过如下命令:

mysql> show variables like '%pool_size';
+---------------------------------+------------+
| Variable_name | Value |
+---------------------------------+------------+
| innodb_additional_mem_pool_size | 67108864 |
| innodb_buffer_pool_size | 4294967296 |
+---------------------------------+------------+

原文来自:http://my.oschina.net/jockchou/blog/478082

mysql之InnoDB内存管理的更多相关文章

  1. 【MySQL】InnoDB 内存管理机制 --- Buffer Pool

    InnoDB Buffer Pool 是一块连续的内存,用来存储访问过的数据页面 innodb_buffer_pool_size 参数用来定义 innodb 的 buffer pool 的大小 是 M ...

  2. jemalloc优化MySQL、Nginx内存管理

    上一篇文章<TCMalloc优化MySQL.Nginx.Redis内存管理>,下面来看下jemalloc jemalloc源于Jason Evans 2006年在BSDcan confer ...

  3. mysql之innodb日志管理

    本文从两个方面进行阐述,常规的日志文件(不区分存储引擎),第二就是讲innodb存储引擎的事务日志. 一.基本日志文件 1.1.基本日志文件分类:错误日志(error log)慢查询日志日志(slow ...

  4. TCMalloc优化MySQL、Nginx内存管理

    TCMalloc的全称为Thread-Caching Malloc,是谷歌开发的开源工具google-perftools中的一个成员. 与标准的glibc库的Malloc相比,TCMalloc库在内存 ...

  5. MySQL 之 innodb 日志管理 -- 1. 基本日志文件

    1.基本日志文件分类 错误日志(error log) 慢查询日志日志(slow query log) 二进制日志(binlog) 查询日志(general log) 2.错误日志 主要包括mysql的 ...

  6. innodb源码解析 - mem0_.c - 基本内存管理

    The basic element of the memory management is called a memoryheap. A memory heap is conceptually ast ...

  7. MySQL InnoDB 日志管理机制中的MTR和日志刷盘

    1.MTR(mini-transaction) 在MySQL的 InnoDB日志管理机制中,有一个很重要的概念就是MTR.MTR是InnoDB存储擎中一个很重要的用来保证物理写的完整性和持久性的机制. ...

  8. MySQL系列:innodb源代码分析之内存管理

    在innodb中实现了自己的内存池系统和内存堆分配系统,在innodb的内存管理系统中,大致分为三个部分:基础的内存块分配管理.内存伙伴分配器和内存堆分配器.innodb定义和实现内存池的主要目的是提 ...

  9. MySQL InnoDB技术内幕:内存管理、事务和锁

    前面有多篇文章介绍过MySQL InnoDB的相关知识,今天我们要更深入一些,看看它们的内部原理和机制是如何实现的. 一.内存管理 我们知道,MySQl是一个存储系统,数据最后都写在磁盘上.我们以前也 ...

随机推荐

  1. 如何精简Unity中使用的字体文件

    在游戏开发过程中,为了UI界面美观和显示效果一致性的考虑,大部分游戏都会使用动态字体来表现文字.尤其在这个看脸的时代,一种字体已经无法满足UI同学对美观的需求,因此我们常常发现若干个小则两三兆,大则十 ...

  2. zookeeper 伪分布式安装

    1 下载zookeeper安装包 下载地址 http://apache.fayea.com/zookeeper/ 我下载的是zookeeper-3.4.6.tar.gz 2 解压缩 将zookeepe ...

  3. Python3.6学习笔记(三)

    面向对象编程 面向对象编程 Object Oriented Programming 简称 OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程 ...

  4. Android Protobuf应用及原理

    前言 之前一直忙于移动端日志SDK Trojan的开源工作,已十分稳定地运行在饿了么团队App中,集成了日志加密和解密功能.哎呀,允许我卖个狗皮膏药,不用不知道,用了就知道,从此爱不释手,Trojan ...

  5. Expectation Maximization-EM(期望最大化)-算法以及源码

    在统计计算中,最大期望(EM)算法是在概率(probabilistic)模型中寻找参数最大似然估计的算法,其中概率模型依赖于无法观测的隐藏变量(Latent Variable).最大期望经常用在机器学 ...

  6. scala的一些特殊用法

    1.创建多行字符串,只要把多行字符串放在3个双引号间("""...""")即可.这是Scala对于here document,或者叫here ...

  7. 3D几何图形生成的DEMO

    3D几何图形生成的DEMO 可以生成以下几种图形: [1] 平面(Plane)图形的生成算法 [2] 立方体(Box)图形的生成算法 [3] 球(Sphere)图形的生成算法 [4] 圆锥(Cone) ...

  8. 游戏:贪吃虫(GreedyMaggot)

    该游戏类似于贪吃蛇,但可以在二维平面上以任意方向前进.当吃到食物手,食物会从虫头向虫尾移动,移到虫尾后,贪吃虫长度会增加.本来给它取名为贪吃蛆的,并且工程的英文名Maggot就是蛆的意思,后来想想有点 ...

  9. windows server 2008 远程桌面(授权、普通用户登录)~ .

    大家好,因公司上ERP系统,用户端需要远程到服务器,但大家都知道微软默认只有2个,所以没有办法达到我公司的要求. 在网上找了很久也没有找到合适的文章,要不就这里说一点,那里说一点,没有一个全的,还有很 ...

  10. Unity3D游戏开发最佳实践20技巧(三)

    [文本] 38.假设你有非常多的剧情文本.那么把他们放到一个文件中面. 不要把他们放到Inspector的字段中去编辑. 这些须要做到不打开Unity,也不用保存Scene就能够方便的改动. 39.假 ...