阅读innodb made young相关文档

This commit is contained in:
asahi
2024-11-23 16:54:15 +08:00
parent 5362e59e11
commit 4ce97c08b5

View File

@@ -137,11 +137,48 @@ midpoint将LRU列表分为了两部分
- 当innodb读取页到缓冲池中时新读取的页将会被插入到midpoint位置。页可能因为如下原因被读取
- 由用户发起的操作例如sql查询
- 由innodb执行的read ahead操作
- 当访问old部分的页时`made young`即将页从old部分移动到young部分的头部。如果对old部分页的访问是由用户发起的操作那么那么该页面会被移动到young部分的头部
- 当访问old部分的页时`made young`即将页从old部分移动到young部分的头部。
- `如果old部分的页是因为用户发起的查询被读取到缓冲池那么该页马上会被访问并且该页会被made young`
- `如果该页是被因为innodb的read ahead被读取到缓冲池中那么该页可能不会马上被访问甚至知道该页被淘汰也不会被访问`
- 随着数据库的运行LRU中的young部分和old部分页面都会向LRU列表尾部移动这被称为`老化`。当其他页面触发`made young`操作时:
- 如果发生`made young`操作那么young部分和old部分的节点都会向后移动发生老化
- 如果由新页面被插入到midpoint那么只有old部分的节点会发生老化
> #### table scan导致的问题
> 默认情况下因用户发起的查询操作而被读取的页面挥别马上移动到LRU young部分。例如mysqldump操作或不带where条件的select都会发起table scan而table scan会读取大量数据到缓冲区中此时会对缓冲区中旧的页进行淘汰。通常table scan读取到缓冲区的新数据后续可能并不会被用到
>
> table scan会快速的将原本处于young部分的页面向后推动到old部分通常这些页都是被频繁使用的。
如上所述table scan会将大量页读取到缓冲池中但是这些页只会在短期内被很快的访问过几次访问会导致该页被made young移动到young部分只会就不会再用到这样会导致大量原本被访问的页被淘汰。
为了解决该问题innodb引入了`innodb_old_blocks_time`在第一次访问了位于old区域的页后的`innodb_old_blocks_time`时间范围内再次访问该页并不会导致该页被移动到LRU的young部分。`innodb_old_blocks_time`的默认值为1000增加该值将会使old部分的页触发`made young`的条件变得更苛刻old部分老化和淘汰的速度也会更快。
#### youngs/s & non-youngs/s
- youngs/s: `youngs/s`该指标代表每秒平均的`因访问old页从而导致made young的访问次数`,如果相同的页发生多次访问,那么所有的访问将都会被计入
- non-youngs/s: 该指标代表`访问old页且没有导致made young的访问次数`,如果相同页发生多次访问,那么所有的访问都会被计入
如果在没有大量扫描发生的情况下youngs/s的指标值仍然很小那么可以考虑适当降低`innodb_old_blocks_time`的值让更多的页更快进入young部分。同样可以适当增加old部分的百分比从而可以令old页更慢移动到LRU尾端更有可能被made young。
如果在发生大量扫描的情况下non-youngs/s的指标值仍然不高那么可以考虑增加`innodb_old_blocks_time`的值延长old页不触发made young的时间窗口
#### buffer pool hit rate
buffer pool hit rate代表缓冲池中页的命中率如果命中率高则代表该缓冲池运行良好。如果命中率较低则需要考虑是否应增加`innodb_old_blocks_time`的值避免table scan导致缓冲池被污染。
#### FreeList
当数据库实例刚启动时LRU里列表中并没有任何页此时页都存放在Free List中。当要从缓冲池中获取页时首先查看Free List中是否有空闲的页`如果有则从FreeList中获取并将该页添加到LRU的midpoint位置``若Free List中没有空闲的页那么将根据LRU算法淘汰LRU尾部的页将淘汰页的内存空间分配给新的页。`
#### Flush List
LRU中被修改的页称其为`脏页`在缓冲池中的数据被修改之后并不会马上就刷新到磁盘中而是会通过checkpoint将脏页刷回到磁盘中。
FlushList即是脏页的列表需要注意的是脏页既存在于LRU中又存在于FlushList中LRU和FlushList都管理的是指向该内存页的指针LRU管理缓冲而FlushList管理脏页回刷二者互不影响。
### redo log buffer
innodb存储引擎的内存区域中除了有缓冲池之外还存在redo log buffer。innodb首先会将redo log放入到这个缓冲区然后会按照一定频率将其刷新到redo log文件。
redo log缓冲区大小并不需要很大通常每隔1s会将redo log buffer中的内容刷新到文件中。`innodb_log_buffer_size`负责控制该缓冲区域大小,该参数默认值为`8M`。(mysql 8中实际测试为`16M`)
redo log buffer在如下场景下会被刷新到文件中
- master thread每秒将缓冲刷新到磁盘文件中
- 每个事务提交时都会将redo log buffer刷新到磁盘文件中
- 当redo log buffer剩余空间小于一般时redo log buffer刷新到磁盘文件中