Appearance
第3章:页、记录与缓冲池
数据页与记录
数据库通常按固定大小页管理外部存储,每页容纳多条记录。变长记录可以采用槽目录:记录 ID 指向页号和槽号,槽再记录实际偏移;页内压缩移动记录时可只更新槽。
堆文件把记录放在可用页中,按键排序文件便于某些范围访问,但插入维护更贵。逻辑主键和物理记录位置不必相同,记录移动是否改变引用取决于具体布局。
行存与列存
行存把一条记录的多个属性放在一起,适合取得或修改少量完整记录。列存集中存放同一列,便于压缩、批量扫描和只读少数属性的分析查询。
例如十列、每列 8 B 的宽表,查询只用两列。理想无额外开销时,列存读入的数据可接近行存的五分之一。但元数据、过滤、编码和缓存会改变实际比例,不能把列数比直接当作所有查询加速比。
缓冲池
缓冲池把磁盘页缓存到内存帧中,页表记录页号到帧的映射。pin 表示当前使用者不能容忍该帧被替换,dirty 表示内容已修改,需要按持久化规则处理。
pin 与锁或 latch 不相同:pin 防止被驱逐,latch 保护内存结构的短期并发访问,事务锁保护逻辑并发语义。只 pin 一个页不代表别人不能修改它。
替换与写回
LRU、Clock 等策略决定替换候选。顺序扫描可能把热点页挤出,因此生产系统会考虑扫描识别、冷热分离或更复杂策略。
脏页不能简单丢弃。若采用 WAL,写回数据页前,要先确保覆盖其修改的日志已持久化。否则掉电后可能留下新数据,却没有用于恢复该修改的日志。
故障边界
内存中的 dirty 标志和持久化到设备的数据是不同状态。操作系统缓存、设备缓存和实际介质还可能存在不同持久边界,数据库需要使用正确的同步接口和存储假设。
一页被写入也不代表整个事务原子提交;一个事务可能跨很多页,页写回顺序与事务提交顺序不必一致。
练习
- 记录变长后在页内移动,槽目录如何保持记录 ID 稳定?
- 为什么 pin、latch 和事务锁不能互相替代?
- 将一个未提交事务修改的页写回磁盘,会对恢复提出什么要求?