在 MySQL/PostgreSQL Buffer Pool 里面有一个 Pin 操作 — PostgreSQL 叫 Pin, MySQL InnoDB 叫 buf_block_fix / io_fix. 这些操作本质上都是把一个 page “pin” buffer pool 的某个位置上.
为什么在其他系统里很少见到这种代码? 答案是 PG 和 InnoDB 的 buffer pool 都用了同一种架构 — Slot-based Buffer Manager. 这种架构直接决定了 Pin 这个操作必须存在.
Slot-based Buffer Manager 结构
启动时, buffer pool 被切成 N 个固定大小的 slot (InnoDB 是 16KB, PG 是 8KB). slot 总数 N 在启动后不再变化.
数据结构上分三层:
- Slot / 描述符: 启动时静态分配, 地址永不变 (buf_block_t / BufferDesc)
- Frame / 页面内存: 启动时静态分配, 地址永不变 (buf_block_t->frame / BufferBlocks[i*BLCKSZ])
- Page Identity: 当前 slot 装的是哪个磁盘 page ((space_id, page_no) / (rel, fork, …