【问题标题】:can some one please explain innodb buffer pool behavior....?有人可以解释一下innodb缓冲池的行为......吗?
【发布时间】:2016-01-19 11:21:38
【问题描述】:

我有我的innodb_buffer_pool_size =1G innodb_old_blocks_time = 5000 innodb_old_blocks_pct = 37

innodb 引擎的初始状态

BUFFER POOL AND MEMORY
Total memory allocated 1098907648; in additional pool allocated 0
Dictionary memory allocated 58256
Buffer pool size   65536
Free buffers       64932
Database pages     603
Old database pages 242
Modified db pages  0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 603, created 0, written 2
6.00 reads/s, 0.00 creates/s, 0.50 writes/s
Buffer pool hit rate 995 / 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: 603, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]

之后

select count(*) from tenMillion;


BUFFER POOL AND MEMORY
Total memory allocated 1098907648; in additional pool allocated 0
Dictionary memory allocated 404498
Buffer pool size   65536
Free buffers       873
Database pages     64660
Old database pages 23888
Modified db pages  3
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 0, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 64660, created 0, written 20
1085.69 reads/s, 0.00 creates/s, 0.31 writes/s
Buffer pool hit rate 955 / 1000, young-making rate 0 / 1000 not 0 / 1000
Pages read ahead 1081.34/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 64660, unzip_LRU len: 0
I/O sum[0]:cur[0], unzip sum[0]:cur[0]

这是正确的行为..? 因为我希望它只占用 37% 的数据库页面,因为整个缓存应该在旧块中

当我的 innodb _old_blocks_time 为 5000 毫秒并且表大小超过 37(我的 innodb_old_blocks_pct)百分比时,如何最初填充 innodb 空闲缓冲区(重新启动服务器后)被填满,或者因为没有年轻人,也不需要驱逐,所以如果它被填满超过我的 innodb 缓冲池的 37%?

请解释

【问题讨论】:

  • 如果您还用文字解释实际行为是什么以及从您发布的输出中可以看到的位置会更好
  • 输出来自mysql 5.5
  • 您写的只是预期的 37%。但是我在哪里看到它占用更多?它实际上是多少?
  • 在show engine innodb status的输出中;数据库页面最初在查询后大约 65000 个,它的 jst 700 什么是我所期望的是它最初应该只占用 37% 的空闲缓冲区

标签: mysql innodb


【解决方案1】:

在“old_blocks”和“37%”的日子之前,会发生这种情况:

  1. 当你的同事在几 GB 的大桌子上做一个无辜的 COUNT(*) 时,你会很高兴地在你的 buffer_pool 中缓存 1GB 的东西。
  2. 噗!现在,您的所有查询运行速度都变慢了——因为他的查询从 buffer_pool 中删除了所有缓存的块。 (他们会逐渐回来。)

现在,

  1. 您正在愉快地徒步旅行......
  2. COUNT(*) 出现了,但他的“表扫描”仅限于缓冲池的 37%。
  3. (如果有人碰巧触摸了该表的某些部分,触摸的块将从“旧”提升,从而移动到其他 63%。)
  4. 您的查询继续运行良好,因为您仍然拥有大部分已缓存的内容。
  5. 又一个COUNT(*) 出现了——嗯,它会在 37% 中乱七八糟,仍然不会(太多)干扰您的“正常”查询。

注意:Buffer pool hit rate 995 / 1000 -- 这从 99.5%(非常好)下降到 95.5%(仍然非常好)。

Old database pages 23888(共 65536 人)证实了我所说的仅限于 37% 的人。

这是 2009 年末发布的 5.1.41 和 5.5.0 版本中所说的:

InnoDB 缓冲池分为两个子列表: 一个新的子列表 包含查询大量使用的块和旧的子列表 包含较少使用的块,并且从这些块中驱逐候选者 采取。在缓冲池的默认操作中,读取时一个块 in 在中点加载,然后立即移动到 一旦访问发生,新的子列表。在桌子的情况下 扫描(例如对 mysqldump 操作执行),每个块由 扫描最终移动到新子列表的头部,因为 从每个块访问多行。这甚至发生在一个 一次性扫描,其中块不被其他人使用 查询。块也可以由预读后台线程加载 然后通过单次访问移动到新子列表的头部。 这些效果可能是不利的,因为它们会推动 从新子列表到旧子列表中的其他查询大量使用 子列表,他们将被驱逐。

InnoDB 现在提供了两个启用 LRU 算法的系统变量 调音:

innodb_old_blocks_pct

Specifies the approximate percentage of the buffer pool used for the old block sublist. The range of values is 5 to 95. The default

值为 37(即池的 3/8)。

innodb_old_blocks_time

Specifies how long in milliseconds (ms) a block inserted into the old sublist must stay there after its first access before it can be

移至新的子列表。默认值为 0:插入的块 进入旧子列表立即移动到新子列表的第一个 访问它的时间,无论插入访问后多久 发生。如果该值大于 0,则块保留在旧 子列表,直到访问发生在第一个之后至少那么多毫秒 使用权。例如,值 1000 会导致块留在旧的 子列表在第一次访问后 1 秒后变为 有资格移至新的子列表。

请参阅 InnoDB 缓冲池。 (错误 #45015)

【讨论】:

  • 但怀疑它是否满足我的问题是当我将 innodb _old_blocks_time 设置为 5000 毫秒并且表大小大于37(我的 innodb_old_blocks_pct)百分比很想知道是否只有 37 pct 会被填满,或者因为没有年轻人也不需要驱逐,所以如果它会被填满超过我的 innodb 缓冲池的 37 pct....?
  • 当你重新启动 mysqld 时,buffer_pool 是空的(除了一些开销)。只有当您执行某些查询时才会放入其中。在较新的版本中有一种方法可以使用上次正常关闭时的内容预加载 buffer_pool。在我看来,这具有可疑的价值。这与“old_blocks”无关。
  • “old”和“new”还与“LRU”(最近最少使用)算法有关,用于决定在需要加载某个块时从完整的 buffer_pool 中弹出哪个块。 所有 对数据和索引的操作都在 buffer_pool 中的块上执行。 (我满足你的问题了吗?)
猜你喜欢
  • 2021-05-16
  • 1970-01-01
  • 1970-01-01
  • 2011-01-23
  • 2011-11-22
  • 2016-12-12
  • 2012-12-02
  • 1970-01-01
相关资源
最近更新 更多