KEEL · 龙骨 · A CURRICULUM FOR THE AI ERA
PostgreSQL 工程课 · 课程导读 — keel 龙骨
PostgreSQL 工程课:MVCC、膨胀与复制 的参考信息:PostgreSQL 工程课 · 课程导读
你现在的起点
- 会写 SQL,会建索引,知道
EXPLAIN大概怎么看; - 听说过 MVCC、WAL、VACUUM 这些词,但说不清它们之间怎么连起来;
- 遇到过「表越用越大」「加了索引还是慢」「备库读不到刚写的表」这类问题,靠搜索和猜测解决。
如果你符合上面三条,这门课就是为你写的。
这门课不讲 SQL 语法,也不讲「什么是事务」。它讲的是 PostgreSQL 这台存储引擎和运行时到底在干什么——因为上面那三个问题,答案都不在 SQL 里。
一条能走通的学习路径
一条 UPDATE 的全景(先看清 MVCC 的物理形态)
→ MVCC 与隔离级别(谁看得见谁,RC 和 RR 差在哪一行)
→ VACUUM 与表膨胀(死元组谁来清、清不动会怎样、回卷的边界)
→ WAL、检查点与崩溃恢复(每一次写入的重放保障)
→ 索引与执行计划(规划的算术、统计怎么左右选择)
→ 锁与并发冲突(行锁记在哪、死锁怎么被发现)
→ 复制、分区与选型(数据怎么到第二台机器、什么时候该分区)
七章共享一条主线:同一张 labpg 库里的表,状态和现象逐章演进。第 00 章那两个行版本,会在第 01 章被快照解释、在第 02 章被 VACUUM 清理、在第 03 章被 WAL 保护。不要跳着读,链路是连的。
章节地图
| 章 | 关键问题 | 你会亲手验证什么 |
|---|---|---|
| 00 一条 UPDATE 改了什么 | 更新为什么不是原地改,xmin/xmax/ctid 各是什么 | 用 heap_page_items 在页里数出两个行版本,读出 HOT 更新的位标志 |
| 01 MVCC 与隔离级别 | 快照怎么建、RC 与 RR 差在哪,并发更新为什么会报错 | 两个会话手工交错,跑出 could not serialize access due to concurrent update 全文 |
| 02 VACUUM 与表膨胀 | 死元组从哪来、autovacuum 何时来、VACUUM FULL 的代价 |
一万次更新后的三条真实尺寸数字,以及老快照挡住清理的现场 |
| 03 WAL、检查点与崩溃恢复 | 写入落盘顺序、checkpoint 在干什么、synchronous_commit 各档语义 |
用 pg_waldump 拆出一条 INSERT 的日志,在独立实例上做一次真实崩溃重启 |
| 04 索引与执行计划 | 代价怎么算、统计失真如何导致选错计划 | 100 万行表上顺序扫描与索引计划的对比,Heap Fetches: 0 的来历 |
| 05 锁与并发冲突 | 行锁的实际粒度、阻塞链怎么查、死锁检测做了什么 | 制造一次真死锁并抄下全文,用 pg_blocking_pids 画出阻塞链 |
| 06 复制、分区与选型 | 物理/逻辑复制的分野、复制槽的风险、分区何时有用 | 搭一台备库制造并观察滞后,解码一次逻辑变更,跑出 200 分区的裁剪计划 |
学完这门课你能做什么
- 拿到一张「只涨不缩」的表,能判断是 HOT 没命中、老快照挡清理、还是 autovacuum 阈值没到,并给出对应的动作;
- 拿到一份「备库延迟」告警,能区分是网络问题(
sent_lsn停)还是回放跟不上(replay_lsn停),知道该动哪一端; - 拿到一条「有索引却走全表扫描」的 SQL,能看出是估计行数错了还是条件没吃到索引,并说出下一步查什么;
- 判断 pgvector 能不能顶住你的向量检索需求,而不是拍脑袋选型。
和《数据库与缓存调优》的分工
数据库与缓存调优 那门课讲的是通用方法论:慢查询怎么定位、执行计划怎么读、连接池容量怎么算、缓存怎么设计。它的示例以 MySQL / InnoDB 为主,站在「应用侧怎么把库用对」的角度。
这门课站在存储引擎与运行时的角度:页里怎么存版本、日志怎么写、锁记在哪、副本怎么追。两边解决的不是同一类问题——
- 「这条 SQL 为什么慢、加什么索引」→ 去数据库与缓存调优 01 章;
- 「并发写在什么情况下会出错、死锁日志怎么读、热点行怎么拆」→ 去数据库与缓存调优 02 章;
- 「为什么表会膨胀、VACUUM 之后为什么文件没小、崩溃后数据为什么还在、备库为什么读不到刚写的表」→ 留在本课。
两门课的结论不冲突,但同一个现象的解释在两边不一样(比如「不可重复读」和「幻读」的成因,InnoDB 靠间隙锁,PostgreSQL 靠事务级快照)。混用两边的结论是最容易犯的错,本课第 01 章专门纠正过这一点。
前置要求
- 会基本的 SQL 与
psql,知道EXPLAIN是什么; - 建议先读数据库与缓存调优 02 章 · 事务、隔离级别与锁等待,建立「隔离级别—锁—死锁」的通用概念;本课第 01、05 章会把它落到 PostgreSQL 的实现上;
- 能读英文报错信息。本课所有报错都贴原文,不做翻译,因为真实排查时你面对的也是原文。