最近在对公司的 MySQL 服务器做性能优化, 一直对 innodb 的内存使用方式不是很清楚, 乘这机会做点总结.

在配置 MySQL 的时候, 一般都会需要设置 innodb_buffer_pool_size, 在将 MySQL 设置在单独的服务器上时, 一般会设置为物理内存的80%.

之前一直疑惑 MySQL 是怎么缓存数据的(不是指query cache), 直觉应该是LRU, 但如果 query 一下从磁盘上读取大量的数据的话(全表扫描或是 mysqldump), 是不是很容易就会把热数据给踢出去?

Buffer Pool 的 LRU 机制

innodb buffer pool 在内存中其实是一个 list, 维护数据的确是用 LRU, 但是做了点优化.

buffer pool 将数据切割成两块, 头部是 young page list, 尾部是 old page list. 两者的空间比例默认是5: 3, 可以通过 show variables like “innodb_old_blocks_pct” 查看, old block的比例即为 37%.

当数据第一次被从磁盘上读取, 要加入 buffer pool 时, 会先放在 old page list 的头部, 此时如果 old page list 满了,则会把它尾部的数据踢出去. 当数据在buffer pool中被再次访问的时候, 如果它在 old page list 中, 则会被转移到 young page list 的头部(如果数据已经在 young page list 中, 则只有它和头结点的距离超过一定长度时才会被转移到头部).

通过这种机制, 可以有效得避免临时的大量数据读取冲刷掉 hot page, 这些一次性的数据如果没有被访问的话,很快会被从old page list 中踢出去.

查看 buffer pool 的使用状况

使用 show engine innodb status, 可以获取 innodb 的运行信息, 查看其中 BUFFER POOL AND MEMORY 一节, 可以看到 innodb buffer的使用情况.

示例:

BUFFER POOL AND MEMORY
----------------------
Total memory allocated 11948523520; in additional pool allocated 0
Dictionary memory allocated 881470
Buffer pool size 712576
Free buffers 7638
Database pages 676994
Old database pages 250018
Modified db pages 22961
Pending reads 4
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 86737875, not young 2068799422
188.89 youngs/s, 5482.68 non-youngs/s
Pages read 390735994, created 1284180, written 17312013
972.19 reads/s, 0.30 creates/s, 36.63 writes/s
Buffer pool hit rate 975 / 1000, young-making rate 4 / 1000 not 141 / 1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 676994, unzip_LRU len: 0
I/O sum[374688]:cur[1688], unzip sum[0]:cur[0]

几个需要注意的参数:

Total memory allocated: innodb 已分配的总内存数, 单位 bytes

Buffer pool size: buffer pool 大小, 单位是 pages, MySQL 的 page 默认是 16KB, 这里 pool 的总大小就是 10G 多.

Free buffers: 还没使用的 buffer size, 单位也是 pages.

Database pages: 总共已使用的 page 数目.

Old database pages: old page list 中的 page 数目.

youngs/s: 每秒对 old page list 的访问次数(不是page的个数), 这种访问会就会把page从 old list 里移动到 new page list 的头部.

evicted without access: 放进 buffer pool 一次都没访问过就被踢出去的 page 数目. 如果发生了全表扫描, 这个数值可能就会临时变高.

补充

因为多线程对 buffer pool 进行访问的时候会发生资源竞争, MySQL 支持对 buffer pool 进行 sharding, 从而提高并发性能, 参数是innodb_buffer_pool_instances.

每个 instance 的 size = innodb_buffer_pool_size/innodb_buffer_pool_instances

官方推荐 sharding 后单个 instance 的 size 不要小于 1G*B. 比如我现在 pool 的总 size 是10 GB, 我设置的 instance 个数就是8.

上面 engine status 只能看到 buffer pool 的汇总情况, 如果想看每个 instance 的详情,
可以从 performance_schema 里拿:

SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS

References:

https://dev.mysql.com/doc/refman/5.6/en/innodb-buffer-pool.html
https://dev.mysql.com/doc/refman/5.6/en/innodb-performance-midpoint_insertion.html
https://dev.mysql.com/doc/refman/5.6/en/innodb-buffer-pool-monitoring.html
https://dev.mysql.com/doc/refman/5.6/en/innodb-multiple-buffer-pools.html

[转]MySQL innodb buffer pool的更多相关文章

  1. Mysql InnoDB Buffer Pool

    参考书籍<mysql是怎样运行的> 系列文章目录和关于我 一丶为什么需要Buffer Pool 对于InnoDB存储引擎的表来说,无论是用于存储用户数据的索引,还是各种系统数据,都是以页的 ...

  2. MySQL · 性能优化· InnoDB buffer pool flush策略漫谈

    MySQL · 性能优化· InnoDB buffer pool flush策略漫谈 背景 我们知道InnoDB使用buffer pool来缓存从磁盘读取到内存的数据页.buffer pool通常由数 ...

  3. MySQL · 引擎特性 · InnoDB Buffer Pool

    前言 用户对数据库的最基本要求就是能高效的读取和存储数据,但是读写数据都涉及到与低速的设备交互,为了弥补两者之间的速度差异,所有数据库都有缓存池,用来管理相应的数据页,提高数据库的效率,当然也因为引入 ...

  4. 理解innodb buffer pool

    今天组里有个同事说可以查看innodb buffer pool每个表和索引占的大小,为此我搜了下,还真有方法,记录下. innodb buffer pool有几个目的: 缓存数据--众所周知,这个占了 ...

  5. innodb buffer pool小解

    INNODB维护了一个缓存数据和索引信息到内存的存储区叫做buffer pool,他会将最近访问的数据缓存到缓冲区.通过配置各个buffer pool的参数,我们可以显著提高MySQL的性能. INN ...

  6. innodb buffer pool相关特性

    背景 innodb buffer pool作为innodb最重要的缓存,其缓存命中率的高低会直接影响数据库的性能.因此在数据库发生变更,比如重启.主备切换实例迁移等等,innodb buffer po ...

  7. Innodb buffer pool/redo log_buffer 相关

    InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理.在数据库系统中,由于CPU速度和磁盘速度之前的鸿沟,通常使用缓冲池技术来提高数据库的整体性能. 1. Innodb_buffe ...

  8. 14.6.3.4 Configuring InnoDB Buffer Pool Prefetching (Read-Ahead) 配置InnoDB Buffer pool 预取

    14.6.3.4 Configuring InnoDB Buffer Pool Prefetching (Read-Ahead) 配置InnoDB Buffer pool 预取 一个预读请求是一个I/ ...

  9. 14.6.3.1 The InnoDB Buffer Pool

    14.6.3.1 The InnoDB Buffer Pool InnoDB 保持一个存储区域被称为buffer pool 用于cache数据和索引在内存里, 知道InnoDB buffer pool ...

随机推荐

  1. SOLD原则

    借鉴: 1. 单一职责原则 单一职责原则 (Single Responsibility Principle,SRP) 指出,每个方法或类应当有且仅有 一个改变的理由.这意味着每个方法或类应当做一件事情 ...

  2. 10个jQuery小技巧

    收集的10个 jQuery 小技巧/代码片段,可以帮你快速开发. 1.返回顶部按钮 你可以利用 animate 和 scrollTop 来实现返回顶部的动画,而不需要使用其他插件. $('a.top' ...

  3. PHP 获取当天 凌晨 时间戳常用代码

    echo strtotime(date('Y-m-d')); 获取明天凌晨的时间戳代码:echo strtotime(date('Y-m-d',strtotime('+1 day'))); 附上测试代 ...

  4. json字符串转泛型集合对象

    Dictionary<string, object> jd = js.Deserialize<Dictionary<string, object>>(item); ...

  5. 多线程获取不到HttpContext

    问题一:多线程下获取文件绝对路径 当我们使用HttpContext.Current.Server.MapPath(strPath)获取绝对路径时HttpContext.Current为null,解决办 ...

  6. php 后端开发学习

    hello.php: <?php //设置cookies setcookie("user", "runoob", time()+3600); ?> ...

  7. Apache 配置多端口

    Apache 配置多端口,主要是以下步骤 1. 如果电脑是64位的,官网上下载WampServe,装的过程中如果出现msvcp110.dll丢失的话,解决办法如下: 1.1 首先是打开浏览器,在浏览器 ...

  8. .net DropDownList静态联动

    1.前台 <span id="spnClient" style="margin-left: 30px; margin-top: 10px"> < ...

  9. SpringMVC问题- MultipartConfig 配置问题以及解决方式

    http://www.cnblogs.com/weilu2/p/springmvc_fileupload_with_servlet_3_0.html

  10. 【转】PHP ob_start() 函数介绍

    php ob_start 与 ob_end_flush() 是 php 的缓冲输出函数. ob_start([string output_callback])- 打开输出缓冲区,所有的输出信息不在直接 ...