mysql之InnoDB内存管理
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内存管理的更多相关文章
- 【MySQL】InnoDB 内存管理机制 --- Buffer Pool
InnoDB Buffer Pool 是一块连续的内存,用来存储访问过的数据页面 innodb_buffer_pool_size 参数用来定义 innodb 的 buffer pool 的大小 是 M ...
- jemalloc优化MySQL、Nginx内存管理
上一篇文章<TCMalloc优化MySQL.Nginx.Redis内存管理>,下面来看下jemalloc jemalloc源于Jason Evans 2006年在BSDcan confer ...
- mysql之innodb日志管理
本文从两个方面进行阐述,常规的日志文件(不区分存储引擎),第二就是讲innodb存储引擎的事务日志. 一.基本日志文件 1.1.基本日志文件分类:错误日志(error log)慢查询日志日志(slow ...
- TCMalloc优化MySQL、Nginx内存管理
TCMalloc的全称为Thread-Caching Malloc,是谷歌开发的开源工具google-perftools中的一个成员. 与标准的glibc库的Malloc相比,TCMalloc库在内存 ...
- MySQL 之 innodb 日志管理 -- 1. 基本日志文件
1.基本日志文件分类 错误日志(error log) 慢查询日志日志(slow query log) 二进制日志(binlog) 查询日志(general log) 2.错误日志 主要包括mysql的 ...
- innodb源码解析 - mem0_.c - 基本内存管理
The basic element of the memory management is called a memoryheap. A memory heap is conceptually ast ...
- MySQL InnoDB 日志管理机制中的MTR和日志刷盘
1.MTR(mini-transaction) 在MySQL的 InnoDB日志管理机制中,有一个很重要的概念就是MTR.MTR是InnoDB存储擎中一个很重要的用来保证物理写的完整性和持久性的机制. ...
- MySQL系列:innodb源代码分析之内存管理
在innodb中实现了自己的内存池系统和内存堆分配系统,在innodb的内存管理系统中,大致分为三个部分:基础的内存块分配管理.内存伙伴分配器和内存堆分配器.innodb定义和实现内存池的主要目的是提 ...
- MySQL InnoDB技术内幕:内存管理、事务和锁
前面有多篇文章介绍过MySQL InnoDB的相关知识,今天我们要更深入一些,看看它们的内部原理和机制是如何实现的. 一.内存管理 我们知道,MySQl是一个存储系统,数据最后都写在磁盘上.我们以前也 ...
随机推荐
- C标准库 二
http://www.utas.edu.au/infosys/info/documentation/C/CStdLib.html现在C语言(C99)标准库函数的24个头文件列表如下: assert.h ...
- Java Web应用软件保护方法
1 代码混淆概述目前针对Java源文件方法主要有以下几种方法:本地编译技术.数字水印技术.ClassLoader加密技术以及代码混淆技术.Java本地编译是指将Java应用程序编译成本地应用程序,如W ...
- [MAC OS] NSButton tag 获取
@IBAction func switchContentLayout(_ sender: Any) { let button : NSButton = sender as! NSButton;}
- NLP十大里程碑
NLP十大里程碑 2.1 里程碑一:1985复杂特征集 复杂特征集(complex feature set)又叫做多重属性(multiple features)描写.语言学里,这种描写方法最早出现在语 ...
- Java多媒体编程应用
1. 声音文件的播放 1.1 在Applet中播放声音 在Applet中,可以使用AudioClip来播放声音,它非常简单,只有三个方法:play().loop()和stop(). 例1.1 利用Au ...
- 前端要给力之:URL应该有多长?
URL到底应该有多长?我为什么要提这个问题呢?有许多优化指南里都写着:要尽量减小COOKIE.缩短URL,以及尽可能地使用GET请求等等,以便优化WEB页面的请求和装载.但是,这种所谓“尽可能”.“尽 ...
- 关于css优先级
css的优先级从低到高依次是:内部样式表的优先级为(1,0,0,0),id选择器优先级为(0,1,0,0),class选择器为(0.0,1,0),tag标签为(0.0,0,1).除此之外,!impor ...
- 【Docker】基于docker+etcd+confd + haproxy构建高可用、自发现的web服务
各个工具介绍 (1)Docker:Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux机器上,也可以实现虚拟化,docker ...
- 交叉编译git
git依赖openssl.zlib. 首先编译openssl ./Configure linux-armv4 shared 修改Makefile,CC.RANLIB.MAKEDEPPROG为对应的交叉 ...
- Cognos审核模块的导入与设置
Cognos审核模块:就是指针对Cognos在运行过程中的对象被执行和访问的日志记录做了一个对象包,在该包里面我们可以从报表里面看到一些日志记录.以方便我们对Cognos的执行记录进行查看,下面我来说 ...