[TOC]
05-缓存池
0-概念辨析
Locks & Latches
Locks:- 逻辑上的锁,如表上的锁
latche(mutex)- 具体的锁,对表加锁具体就是加一个个
latche
- 具体的锁,对表加锁具体就是加一个个
page table & page directory
page directory:记录几号页在磁盘的哪个位置上
page table:内存池里面的页的索引
内存池管理
磁盘上文件分页,内存上的也会分页,叫做frame

怎么索引内存页:

内存开辟一块空间作为缓存
存储引擎怎么管理磁盘空间和内存空间的流动
内存空间是磁盘空间的一部分
缓存作用
-
缓存数据
-
修改数据后会放到缓存里面,不会立即放到磁盘里
-
空间控制
- 把经常管理的数据放到内存里
- 将页写到磁盘的哪里
-
时间控制
- 什么时候把内存读到磁盘里
- 什么时候写回去
- 如何最小化用户的等待时间
用户执行读取的流程

1-放置策略
global policy:统一安排数据页放到哪
local policy:为每个事务有单独的策略
buffer poll
多种缓存池:
- 多缓存池
- 每个database有缓存池
- 每个页类型加缓存池:文件页是不一样的,存索引存数据存元数据都有不同的内存池

分配方法
根据ID:

根据哈希:

2-提前扫描
根据查询计划预先读取页:
顺序扫描
读取索引上的一段
假设执行
SELECT * FROM A
WHERE val BETWEEN 100 and 250根据二叉树的性质,直接读取后面的页

扫描时共享
如果我发现两个SQL语句在读同一个表,会执行同步扫描
比如执行:
SELECT * FROM A JOIN B;
SELECT * FROM B JOIN A;语句都会扫描A表和B表
如果两个语句一起执行:会只执行一次
如何不在一起来:那么先看看之前扫描是结果
两个一起执行,会一起执行相同的部分

Q1扫描3个后,Q1Q2一起扫,扫到最后Q2再扫前3个。
旁路缓存
一般用于sorting和join
有些数据只用一次,扫描的数据不会放到缓存,直接等待垃圾回收啥的。
OS缓存
OS也有读磁盘的缓存
OS不知道缓存什么时候要,执行什么策略、、、
一般会冲突,没法优化,不要操作系统处理。
OS is not your friend
3-缓存替换策略
缓存满了,必须踢掉一部分
目标:
- 准确性
- 精度
- 速度
- 元数据开销
LRU
最近最少使用
驱逐很久很久没有使用的
效率较低
面试常考
时间轮(CLOCK)
驱逐差不多最老的,比如说第二老的
一个环形的数据结构,ref表示有人读了
当时针转到时,ref-=1
当时针读到0时会驱逐掉(缓存不一定满了)

一年不联系的联系人就删掉吧
缺点:
- 对于scan sharing没用,新的可能永远不会使用
LRU-K
与CLOCK记一下上次访问时间不同,LRU-K会记录上K次访问时间
本地化
按照事务/语句驱逐
举个例子:
跟自己相关的驱逐,和自己不相关的就保留
给指示
告诉缓存池这个很重要(机器学习、人工)
priority hint

所有数据库会让根节点一开机就读取,永远不会消失
脏页
已经改动但是还没有存储的页,内存和磁盘不一致
- 如果不是脏页,就会该怎么搞怎么搞
- 是脏页,清理时写回磁盘
- tradeoff:
- 如果不会用就写回去
- 如果会经常用到就暂不写回去
- write allowed log:记录那个页还没有写进去,到时候把数据刷回去。如果数据库卡住了就说明数据库在刷脏。数据库和日志必须持久化一个
其他缓存池
- 排序+连接缓冲:热点查询语句缓存
- 查询缓存:热点查询结果缓存
- 维护缓冲区:
- 日志缓冲区:log缓存,log频率很高
- 字典缓存:
结论
数据库缓存一定比OS好,因为数据库比OS更了解自己要做什么
- 驱逐
- 分配创建
- 预先拉取
