主题
PostgreSQL 面试高频题总索引
本文件汇总 19 章节的面试题,按章节归类、按高频程度排序,方便冲刺复习。 每题正文请跳转到对应章节文档的「面试高频题」小节查看完整答案。
✅ 链接可用性:所有跳转锚点已经按照各章节实际标题(一次次
grep校准过)重写, 在 GitHub 网页或 VSCode Markdown 预览里点击即可直达。💻 使用建议:
- 先
git clone整个仓库到本地(GitHub 在线浏览容易因为 LFS / 渲染缓存导致锚点偶尔失灵)。- 用 VSCode / Cursor / IDE 打开本目录,按
Ctrl/Cmd + Click跟随链接,体验最好。- 配合 [Markdown All in One] 或 [Markdown Preview Enhanced] 插件可以在侧边栏看到目录树,更易跳转。
🔥 难度与频率图例
- ⭐ 入门必会(基础概念 / 命令)
- ⭐⭐ 进阶常考(原理理解 / 选型)
- ⭐⭐⭐ 大厂高频(PG vs MySQL 对比 / 生产细节)
- ⭐⭐⭐⭐ 资深岗位 / 字节阿里腾讯一面必问(深入内核 / 故障排查)
第 1 章 · PostgreSQL 是什么 & 为什么火
详细答案见
01_intro.md§ 1.10 面试高频题
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | PostgreSQL 与 MySQL 的核心区别?分别适合什么场景? | ⭐⭐⭐ | 对象-关系 / 标准 SQL / 索引种类 / MVCC 实现 |
| 2 | PostgreSQL 的设计哲学是什么?为什么号称「世界上最先进的开源数据库」? | ⭐⭐ | 标准遵循 / 扩展性 / ACID 正确性 |
| 3 | 为什么大厂越来越多用 PG 替代 MySQL? | ⭐⭐⭐ | JSONB / pgvector / 协议许可 / 云原生 |
| 4 | PG 是单进程还是多进程模型?和 MySQL 线程模型有何差异? | ⭐⭐ | postmaster / backend / 共享内存 |
| 5 | PG 的版本发布节奏?当前主流生产版本是哪些? | ⭐ | 一年一个大版本 / LTS 5 年 / PG 17 |
| 6 | PG 有哪些杀手级扩展?分别解决什么问题? | ⭐⭐⭐ | PostGIS / pgvector / TimescaleDB / Citus |
第 2 章 · psql 与基础 SQL
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | PG 的「Database / Schema / Table」三级结构与 MySQL 的「Database / Table」二级结构有何不同? | ⭐⭐⭐ | search_path / public schema |
| 2 | psql 中 \d / \dt / \df / \du 分别查什么? | ⭐ | 元命令 / system catalog |
| 3 | RETURNING 子句的作用和适用场景? | ⭐ | INSERT/UPDATE/DELETE 返回行 |
| 4 | search_path 的作用?同名表在不同 Schema 中如何解析? | ⭐⭐⭐ | schema 解析顺序 / 多租户 |
| 5 | PG 的 text 和 varchar(n) 性能上有差异吗?为什么官方推荐 text? | ⭐⭐ | 字符串实现 / 长度校验 |
| 6 | PG 中如何查看一张表的所有索引、约束、统计信息? | ⭐⭐ | \d+ / pg_indexes / pg_stats |
第 3 章 · 数据类型详解
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | JSON 和 JSONB 的存储与查询差异?什么场景必须用 JSONB? | ⭐⭐⭐⭐ | 二进制 / GIN 索引 / 操作符 |
| 2 | timestamp 和 timestamptz 的区别?踩过的时区坑有哪些? | ⭐⭐⭐ | UTC 存储 / 客户端时区转换 |
| 3 | 数组类型的常见操作符(@> <@ &&)有哪些?什么时候用 GIN? | ⭐⭐⭐ | 包含 / 重叠 / 反向索引 |
| 4 | numeric / decimal / real / double precision 怎么选? | ⭐ | 精确计算 / 浮点 / 金融场景 |
| 5 | 范围类型 tstzrange + EXCLUDE 排他约束怎么实现「会议室时间不冲突」? | ⭐⭐⭐⭐ | 范围重叠 / GiST 索引 |
| 6 | UUID 作为主键的优劣?uuid_generate_v4 与 gen_random_uuid 哪个好? | ⭐⭐ | 随机性 / 索引膨胀 / 性能 |
| 7 | 自定义复合类型 / 枚举类型在业务中怎么用? | ⭐⭐ | CREATE TYPE / 类型扩展 |
第 4 章 · 约束、视图与序列
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | SERIAL 和 GENERATED ALWAYS AS IDENTITY 的区别?官方为什么推荐后者? | ⭐⭐⭐ | 序列权限 / 标准 SQL / 安全性 |
| 2 | 物化视图 vs 普通视图,刷新策略如何选择?CONCURRENTLY 是什么? | ⭐⭐⭐ | 缓存查询结果 / 唯一索引前提 |
| 3 | 外键的级联策略 CASCADE / RESTRICT / SET NULL 各自适用什么场景? | ⭐⭐ | 引用完整性 |
| 4 | 排他约束 EXCLUDE USING gist 解决了什么问题? | ⭐⭐⭐⭐ | 范围冲突 / 与 UNIQUE 区别 |
| 5 | 序列被多事务并发使用,会不会重复?为什么有时会出现「跳号」? | ⭐⭐⭐ | nextval 不回滚 / cache |
| 6 | CHECK 约束能用复杂表达式吗?写一个「邮箱格式」的检查。 | ⭐⭐ | 正则 / 表达式约束 |
第 5 章 · 高级查询(CTE / 窗口函数 / upsert)
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | CTE 与子查询的本质区别?PG 12 之后 CTE 的执行行为有什么变化? | ⭐⭐⭐⭐ | MATERIALIZED / inlining / 优化器 |
| 2 | 递归 CTE 怎么写?怎么实现「评论树 / 组织架构」遍历? | ⭐⭐⭐ | WITH RECURSIVE / UNION ALL |
| 3 | 窗口函数 ROW_NUMBER / RANK / DENSE_RANK 的区别? | ⭐⭐ | 分组排序 / 同分处理 |
| 4 | INSERT ... ON CONFLICT DO UPDATE 与 MySQL INSERT ... ON DUPLICATE KEY 的差异? | ⭐⭐⭐ | upsert / EXCLUDED 伪表 |
| 5 | LATERAL JOIN 是什么?解决了什么 SQL 表达不了的问题? | ⭐⭐⭐⭐ | 引用前表 / Top-N per group |
| 6 | GROUPING SETS / ROLLUP / CUBE 的区别?什么时候用? | ⭐⭐ | OLAP / 多维聚合 |
| 7 | 用 SQL 找出每个分类下销量 Top 3 的商品,写两种实现。 | ⭐⭐⭐ | 窗口函数 / LATERAL |
第 6 章 · 索引体系(B-Tree / GIN / GiST / BRIN)
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | B-Tree 和 GIN 索引的差异?分别适合什么数据? | ⭐⭐⭐⭐ | 等值范围 / 多值倒排 |
| 2 | 什么场景该用 GiST?和 GIN 怎么取舍? | ⭐⭐⭐ | 几何 / 范围 / 全文检索 |
| 3 | BRIN 索引的原理?什么数据形态适合 BRIN? | ⭐⭐⭐⭐ | 块范围摘要 / 时序追加 |
| 4 | 部分索引(Partial Index) 是什么?举个生产例子。 | ⭐⭐⭐ | WHERE 条件 / 软删除标记 |
| 5 | 覆盖索引 INCLUDE 与 MySQL 覆盖索引的区别? | ⭐⭐⭐ | Index-Only Scan / VM 配合 |
| 6 | 为什么 PG 没有「聚簇索引」?CLUSTER 命令到底做了什么? | ⭐⭐⭐⭐ | 堆表 / 一次性物理排序 |
| 7 | CREATE INDEX CONCURRENTLY 的代价是什么?为什么生产必须加? | ⭐⭐⭐ | 不阻塞写 / 双扫表 |
| 8 | 怎么判断索引是否被使用?怎么排查无用索引? | ⭐ | pg_stat_user_indexes / idx_scan |
第 7 章 · 事务与隔离级别
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | PG 默认隔离级别为什么是 READ COMMITTED 而不是 REPEATABLE READ? | ⭐⭐⭐⭐ | 性能取舍 / 与 MySQL 对比 |
| 2 | PG 的 RR 隔离级别能完全防止幻读吗?和 MySQL 的实现有何不同? | ⭐⭐⭐⭐ | 快照 / 无 Gap Lock |
| 3 | SSI(Serializable Snapshot Isolation) 怎么实现真·SERIALIZABLE? | ⭐⭐⭐⭐ | 谓词锁 / SIREAD / 写偏序检测 |
| 4 | SELECT ... FOR UPDATE / FOR SHARE / SKIP LOCKED 各自的语义? | ⭐⭐⭐ | 行锁模式 / 队列消费 |
| 5 | PG 中 SAVEPOINT 的实现原理?嵌套事务怎么模拟? | ⭐⭐ | 子事务 / xid 子节点 |
| 6 | PG 中如何避免「丢失更新」?给三种方案。 | ⭐⭐⭐ | FOR UPDATE / 乐观锁 / SERIALIZABLE |
| 7 | 长事务(Long Transaction)的危害?怎么监控? | ⭐⭐⭐ | 阻塞 vacuum / 表膨胀 / pg_stat_activity |
第 8 章 · MVCC 与 VACUUM
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | xmin / xmax / cmin / cmax 分别是什么?怎么决定一行对当前事务可见? | ⭐⭐⭐⭐ | 元组头 / 可见性算法 |
| 2 | PG 的 MVCC 与 MySQL InnoDB 的 MVCC 实现有什么本质区别? | ⭐⭐⭐⭐ | 多版本元组 vs Undo 链 |
| 3 | HOT 更新(Heap-Only Tuple) 是什么?解决了什么问题?触发条件? | ⭐⭐⭐⭐ | 索引膨胀 / 同页 / 不更新索引列 |
| 4 | 死元组(Dead Tuple)是怎么产生的?为什么 DELETE 后表大小不变? | ⭐⭐ | 标记删除 / 等待 vacuum |
| 5 | VACUUM 与 VACUUM FULL 的差异?什么时候用 FULL? | ⭐⭐⭐ | 在线回收 vs 重写表 / 排他锁 |
| 6 | autovacuum 不工作怎么排查?关键参数有哪些? | ⭐⭐⭐ | naptime / scale_factor / cost_limit |
| 7 | 事务 ID 回卷(XID Wraparound) 是什么?怎么预防? | ⭐⭐⭐⭐ | 32 位 XID / freeze / 数据库不可写 |
| 8 | 怎么定位表 / 索引膨胀严重的表?给个查询语句。 | ⭐⭐⭐ | pgstattuple / pg_stat_user_tables |
第 9 章 · 存储与物理结构
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | PG 一个 Page 默认多大?里面是怎么组织的? | ⭐⭐⭐ | 8KB / page header / line pointer / tuple |
| 2 | TOAST 是什么?什么时候触发?四种 TOAST 策略有何不同? | ⭐⭐⭐⭐ | 大字段 / 切片 / 压缩 / out-of-line |
| 3 | FSM 和 VM 是什么?分别解决什么问题? | ⭐⭐⭐ | 空闲空间 / 可见性 / index-only scan |
| 4 | PG 的堆表 + 索引分离 vs InnoDB 的索引组织表,各有什么取舍? | ⭐⭐⭐⭐ | 二次回表 / HOT / 二级索引代价 |
| 5 | PGDATA 目录下都有哪些关键子目录?分别放什么? | ⭐ | base / global / pg_wal / pg_xact |
| 6 | 表空间 TABLESPACE 的作用?什么场景需要单独建? | ⭐⭐ | 多盘 / 冷热分离 |
第 10 章 · WAL 与 Checkpoint
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | WAL 的两阶段写入流程是什么?为什么先写日志再写数据页? | ⭐⭐⭐⭐ | WAL-first / fsync / 持久性 |
| 2 | LSN 是什么?有哪些常见用途? | ⭐⭐ | 日志位置 / 复制位点 / 备份点 |
| 3 | wal_level 的 minimal / replica / logical 区别? | ⭐⭐⭐ | 复制 / 逻辑解码 |
| 4 | Checkpoint 何时触发?参数怎么调?过于频繁有什么副作用? | ⭐⭐⭐⭐ | timeout / max_wal_size / IO 抖动 |
| 5 | PG 的崩溃恢复流程?从哪里开始重放 WAL? | ⭐⭐⭐⭐ | 最近 checkpoint / redo / 一致点 |
| 6 | WAL 文件能不能随便删?删错了怎么办? | ⭐⭐⭐ | 归档 / pg_wal 清理 / 灾难恢复 |
| 7 | full_page_writes 是什么?为什么重要? | ⭐⭐⭐⭐ | 半写问题 / torn page / Checkpoint 后首次修改 |
第 11 章 · 锁机制
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | PG 一共有几种表级锁?兼容性矩阵记得吗? | ⭐⭐⭐⭐ | 8 种 / ACCESS SHARE → ACCESS EXCLUSIVE |
| 2 | 行级锁有几种?FOR NO KEY UPDATE 和 FOR UPDATE 区别? | ⭐⭐⭐ | 4 种 / 外键引用兼容 |
| 3 | PG 死锁怎么排查?日志中出现 deadlock detected 怎么定位? | ⭐⭐⭐⭐ | pg_locks / pg_stat_activity / 锁链 |
| 4 | 咨询锁(Advisory Lock)是什么?典型应用场景? | ⭐⭐⭐ | 应用级互斥 / 长任务串行化 |
| 5 | 为什么生产环境慎用 LOCK TABLE?有哪些替代方案? | ⭐ | ACCESS EXCLUSIVE / 短时窗口 |
| 6 | PG 没有 Gap Lock,那它怎么防幻读? | ⭐⭐⭐⭐ | 快照 RR / SSI 谓词锁 |
| 7 | SKIP LOCKED 实现任务队列的优势是什么? | ⭐⭐⭐ | 并发消费 / 不阻塞 |
第 12 章 · 服务端编程(PL/pgSQL / 触发器)
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | 存储过程(PROCEDURE)和函数(FUNCTION)的区别?分别什么时候用? | ⭐⭐ | 事务控制 / 返回值 |
| 2 | 触发器的 BEFORE / AFTER / INSTEAD OF、行级 / 语句级分别什么场景? | ⭐⭐⭐ | 数据修正 / 审计 / 视图更新 |
| 3 | 在触发器里写复杂业务逻辑有哪些坑? | ⭐⭐⭐⭐ | 性能 / 递归触发 / 调试困难 |
| 4 | LISTEN / NOTIFY 是什么?能替代 Kafka 吗? | ⭐⭐⭐ | 轻量消息 / 同库通信 / 无持久化 |
| 5 | PL/pgSQL 中怎么处理异常?EXCEPTION WHEN ... THEN ... 怎么写? | ⭐⭐ | 异常块 / 子事务代价 |
| 6 | 函数的 IMMUTABLE / STABLE / VOLATILE 三个 volatility 有什么影响? | ⭐⭐⭐ | 优化器 / 索引使用 / 缓存 |
第 13 章 · 权限与安全
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | PG 的 ROLE / USER / GROUP 是什么关系? | ⭐ | 角色统一 / LOGIN 属性 |
| 2 | pg_hba.conf 里 trust / md5 / scram-sha-256 / cert 的区别? | ⭐⭐⭐ | 认证方式 / 安全推荐 |
| 3 | 行级安全 RLS 怎么用?多租户场景怎么落地? | ⭐⭐⭐⭐ | POLICY / 租户隔离 |
| 4 | 权限粒度可以细到什么程度?列级权限怎么用? | ⭐⭐⭐ | GRANT 列 / SELECT (col) |
| 5 | 怎么让一个只读账号「真·只读」?避开 SECURITY DEFINER 函数风险。 | ⭐⭐⭐ | DEFAULT PRIVILEGES / 避免越权 |
| 6 | 如何审计 PG 的 DDL / DML 操作? | ⭐⭐⭐⭐ | event trigger / pgaudit 扩展 |
第 14 章 · 备份与恢复
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | pg_dump 和 pg_basebackup 的本质区别?分别适合什么场景? | ⭐⭐⭐ | 逻辑 / 物理 / 跨版本 |
| 2 | pg_dump 的 -Fp -Fc -Fd -Ft 四种格式的差异? | ⭐ | plain / custom / directory / tar |
| 3 | PITR 是怎么实现的?需要哪些前置配置? | ⭐⭐⭐⭐ | archive_mode / restore_command / recovery target |
| 4 | 物理备份过程中,pg_basebackup 怎么保证备份一致性? | ⭐⭐⭐⭐ | START / STOP backup / WAL 包含 |
| 5 | 误删一张大表如何恢复?给两种方案。 | ⭐⭐⭐ | PITR / pg_dump 选择性恢复 |
| 6 | 备份策略「全量 + WAL 归档」中,归档文件怎么管理才不爆盘? | ⭐⭐⭐ | archive_cleanup / pg_archivecleanup |
第 15 章 · 复制与高可用
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | 流复制 vs 逻辑复制 的核心区别?分别什么场景用? | ⭐⭐⭐⭐ | 物理 WAL vs 解码 / 跨版本 / 表级订阅 |
| 2 | 同步复制有哪几种模式?remote_write / remote_apply 的差异? | ⭐⭐⭐⭐ | synchronous_commit / 数据零丢失 |
| 3 | 主从延迟(replay_lag)怎么排查?常见原因? | ⭐⭐⭐⭐ | 大事务 / 单线程 apply / 网络 / 长查询冲突 |
| 4 | 主库宕机如何 failover?Patroni 的工作原理? | ⭐⭐⭐⭐ | DCS / etcd / 自动选主 |
| 5 | 逻辑复制的 publication / subscription 怎么搭?跨大版本升级怎么用? | ⭐⭐⭐ | CREATE PUBLICATION / CREATE SUBSCRIPTION |
| 6 | 热备 hot standby 的从库读时遇到 recovery conflict 是什么? | ⭐⭐⭐⭐ | 长查询 / hot_standby_feedback / vacuum 冲突 |
| 7 | 怎么判断从库是否真正追上主库? | ⭐⭐ | pg_stat_replication / replay_lsn |
第 16 章 · 分区与分库分表
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | PG 声明式分区有几种类型?分别适合什么场景? | ⭐⭐ | RANGE / LIST / HASH |
| 2 | 分区裁剪是什么?怎么验证执行计划用到了分区裁剪? | ⭐⭐⭐ | partition pruning / EXPLAIN |
| 3 | 分区表上的全局唯一约束能加吗?为什么有限制? | ⭐⭐⭐⭐ | 必须包含分区键 / 局部索引 |
| 4 | 分区数过多有什么副作用? | ⭐⭐⭐ | 计划开销 / 锁压力 / pg_partman 管理 |
| 5 | Citus 解决了 PG 原生分区无法解决的什么问题? | ⭐⭐⭐⭐ | 跨节点分布 / 协调器 / 分布式查询 |
| 6 | 分区表如何高效切换冷热数据? | ⭐⭐ | DETACH PARTITION / 归档 |
第 17 章 · 性能调优
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | shared_buffers 设多大合适? 和 OS Page Cache 怎么配合? | ⭐⭐⭐⭐ | 25% 内存 / 双层缓存 |
| 2 | work_mem 调高有什么风险? 怎么按会话精细控制? | ⭐⭐⭐⭐ | 每个排序节点独立 / OOM 风险 |
| 3 | effective_cache_size 起什么作用?设错会怎样? | ⭐⭐⭐ | 优化器估算 / 影响 Index Scan 选择 |
| 4 | pg_stat_statements 怎么用?最关心哪几列? | ⭐⭐⭐ | total_exec_time / mean_exec_time / calls |
| 5 | EXPLAIN (ANALYZE, BUFFERS) 中每一行节点怎么读? | ⭐⭐⭐⭐ | actual time / shared hit/read / loops |
| 6 | Hash Join / Merge Join / Nested Loop 优化器是怎么选的? | ⭐⭐⭐⭐ | 行数估算 / 内存 / 排序代价 |
| 7 | 慢查询日志开启后定位问题流程? | ⭐⭐ | log_min_duration_statement / pgbadger |
| 8 | 一条 SQL 突然变慢,排查步骤? | ⭐⭐⭐⭐ | 统计信息 / 计划变化 / 锁等待 / 缓存冷 |
第 18 章 · 常用扩展生态(PostGIS / pgvector / TimescaleDB)
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | PostGIS 中「附近 1 公里的商家」怎么写 SQL?走什么索引? | ⭐⭐⭐ | ST_DWithin / GiST / geography |
| 2 | pgvector 支持哪些距离度量?HNSW 与 IVFFlat 索引怎么选? | ⭐⭐⭐⭐ | <-> <#> <=> / 召回率 / 构建代价 |
| 3 | TimescaleDB 的 hypertable 与原生 PG 分区有什么区别? | ⭐⭐⭐ | chunk 自动管理 / 连续聚合 |
| 4 | CREATE EXTENSION 背后做了什么?为什么需要超级用户? | ⭐⭐⭐ | 安装脚本 / system catalog |
| 5 | pg_cron vs OS crontab 调度任务的差异? | ⭐⭐ | 库内调度 / 高可用切换 |
| 6 | 想自己写一个扩展,大致流程? | ⭐⭐⭐⭐ | C 函数 / control 文件 / pg_ctl install |
第 19 章 · 综合实战项目
详细答案见
19_project.md§ 9. 面试高频题
| # | 题目 | 难度 | 关键词 |
|---|---|---|---|
| 1 | 你做的项目里 PG 库表是怎么设计的?为什么这么拆? | ⭐⭐ | 范式 / 反范式 / JSONB |
| 2 | 项目中遇到过最严重的一次慢查询是什么?怎么定位并解决? | ⭐⭐⭐⭐ | 真实经历 / EXPLAIN / 索引重建 |
| 3 | 项目里如何做到「读写分离」?延迟容忍怎么定? | ⭐⭐⭐ | 流复制 / 路由层 / 强一致读 |
| 4 | 上线后表膨胀到几百 GB 怎么处理? | ⭐⭐⭐⭐ | VACUUM FULL / pg_repack / 在线重建 |
| 5 | 怎么保证项目里 DDL 变更不锁表? | ⭐⭐⭐⭐ | CONCURRENTLY / 短事务 / lock_timeout |
| 6 | 如果让你从 MySQL 迁到 PG,你会怎么规划? | ⭐⭐⭐⭐ | pgloader / 双写 / 切流 / 回滚预案 |
📚 推荐刷题顺序
第一遍按章节顺序刷,建立体系;第二遍按下面的「话题串联」刷,覆盖跨章节的综合题:
「MVCC 串」:Ch7 隔离级别(Q1/Q2/Q3)→ Ch8 MVCC(Q1/Q2/Q3)→ Ch9 存储(Q4 堆表)→ Ch11 锁(Q6 防幻读)。 理解 PG「多版本元组 + 快照可见性」的完整闭环,搞清为什么 PG 不需要 Undo Log 也能 MVCC。
「索引串」:Ch6 索引(Q1/Q2/Q3/Q4 部分索引/Q5 覆盖)→ Ch9 存储(Q3 VM 与 index-only scan)→ Ch17 性能(Q5 EXPLAIN 解读)。 建立从「数据结构 → 物理布局 → 执行计划」的纵向链路,能讲清楚一个索引到底是怎么被用上的。
「VACUUM 串」:Ch8 MVCC(Q4 死元组 / Q5 VACUUM / Q6 autovacuum / Q7 XID 回卷)→ Ch7 长事务(Q7)→ Ch19 表膨胀(Q4 pg_repack)。 掌握 PG 运维中最容易踩坑的一条线,特别是「为什么 DELETE 完磁盘没释放」。
「WAL & 复制串」:Ch10 WAL(全部)→ Ch14 PITR(Q3/Q4)→ Ch15 流复制 vs 逻辑复制(Q1/Q2/Q3/Q6)。 从「单机持久性」走到「多机高可用」,把 LSN 这条贯穿所有恢复 / 复制场景的「时间线」搞透。
「锁 / 并发串」:Ch11 锁机制(全部)→ Ch7 行锁语义(Q4 FOR UPDATE / SKIP LOCKED)→ Ch17 慢 SQL 排查(Q8 锁等待)→ Ch19 DDL 不锁表(Q5)。 把 PG 的 8 种表锁 + 4 种行锁 + 谓词锁在生产场景里跑一遍,重点理解「不阻塞读」的设计。
「JSONB / 扩展生态串」:Ch3 JSONB(Q1/Q3 数组)→ Ch6 GIN 索引(Q1)→ Ch18 pgvector / PostGIS(Q1/Q2)→ Ch1 杀手扩展(Q6)。 这是 PG 区别于 MySQL 的「杀手锏」面试加分项;准备一个真实项目故事(哪怕是周边小项目)讲半结构化 / 向量 / 地理场景,效果最佳。
💡 冲刺建议:每个「串」准备 1 ~ 2 个自己亲手做过的小实验(哪怕是本地 docker 跑的), 面试时拿出来讲,远比照本宣科背答案有说服力——尤其是 MVCC、PITR、
SKIP LOCKED这种「能动手演示」的题。