deepwzh的技术笔记
  • Golang
  • Python
  • Cpp
杂项
前端开发
  • 计算机网络
  • 操作系统
  • 数据库
云原生
Devops
AIGC
关于作者
  • Golang
  • Python
  • Cpp
杂项
前端开发
  • 计算机网络
  • 操作系统
  • 数据库
云原生
Devops
AIGC
关于作者
  • 数据库
  • Redis
  • NewSQL
  • Mysql

    • Mysql
    • 缓存池
    • Innodb
    • 数据库事务
    • Mysql

缓存池

概述

作用

  • 加速读: 数据读取先查缓存,没有再查磁盘
  • 加速写:数据修改后,先写入缓存, 再找时间再统一写入磁盘

原理

局部性原理

  • 空间局部性:某页被访问,其相邻页也可能会被访问 -> 预读机制
  • 时间局部性:某页最近被访问过,将来也很可能会被访问 -> LRU
  • 目的是减少磁盘 IO 次数,尽可能的让读写落到内存中
  • 按数据页读取,存到内存中

有关预读

https://www.cnblogs.com/geaozhang/p/7397699.html

线性预读

线性预读是以 extend 为单位的。通过判断当前的 extend 中的数据是否是连续访问的,并以此来预测是否有必要把下一个 extend 提前从磁盘文件中读取出来,加载到 buffer pool 中。

相关配置

  • innodb_read_ahead_threshold: 当一个 extend 中,大于等于 innodb_read_ahead_threshold 个 page 是被连续访问的时候,就预先加载下一个 extend 的数据。默认值是 56,最大值 64

数据结构

缓存池结构

缓存池实例结构

缓存池实现上有三种链表结构

  • Free 链表:管理空白页
  • LRU 链表:管理已经有数据的页
  • Flush 链表:管理脏页,脏页同时也会在 LRU 链表中
  • 读取数据未命中缓存,会向 Free 链表要一页,加入到 LRU 链表中
  • 内存中的页被修改,会扔到 Flush 链表一份
  • Flush 链表的页被回存了,会在 Flush 链表中删除

淘汰策略

缓存大小有限,需要一定的淘汰策略

基础淘汰策略:LRU(最近最少使用)

冷热数据分离

原有纯 LRU 方案可能会存在以下问题:

  • 预读失效:预读会加载相邻页,有可能相邻页并没有再被访问,却挤掉了被频繁访问的页
  • 缓冲池污染: 存在扫描的 sql 请求,此请求得到的数据不会被频繁使用,占用页巨多,却将其他的缓存页给挤掉了

因此引入了 冷热数据分离的设计:

  • 当数据页第一次被加载到缓冲池中的时候,先将其放到冷数据区域的链表头部,1s(由 innodb_old_blocks_time 参数控制) 后该缓存页被访问了再将其移至热数据区域的链表头部。
  • Mysql 中优化为热数据区的后 3/4 部分被访问后才将其移动到链表头部去,对于前 1/4 部分的缓存页被访问了不会进行移动。

配置

  • innodb_buffer_pool_chunk_size
  • innodb_buffer_pool_instances
  • innodb_buffer_pool_size

可在线配置

修改缓存池总大小,单位字节,必须为 innodb_buffer_pool_chunk_size*innodb_buffer_pool_instances 的倍数。

SET GLOBAL innodb_buffer_pool_size=8589934592;

使用 Innodb_buffer_pool_resize_status 报告缓冲池大小调整的进展

mysql> SHOW STATUS WHERE Variable_name ='InnoDB_buffer_pool_resize_status';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| Innodb_buffer_pool_resize_status |       |
+----------------------------------+-------+
1 row in set (0.01 sec)

只可离线配置

innodb_buffer_pool_chunk_size

[mysqld]
innodb_buffer_pool_chunk_size = 134217728

监控

查看统计信息

show engine innodb status

应用

参考资料

MySQL 源码学习(六):线性预读-云社区-华为云

关于 MySQL buffer pool 的预读机制 - GeaoZhang - 博客园

MySQL 中的这个池子--缓冲池(buffer pool),真的强! - 掘金

https://cloud.tencent.com/developer/article/1779059

MySQL · 特性分析 · innodb buffer pool 相关特性

[玩转 MySQL 之十]InnoDB Buffer Pool 详解

Prev
Mysql
Next
Innodb