1. 课程导入与容量成本全景
PostgreSQL 的容量问题很少以“磁盘满了”这一种形式出现。更常见的情况是:磁盘还有 30% 空间,但查询延迟从 20ms 涨到 300ms;或者存储成本每月增长 8%,而业务数据量只增长了 2%。这说明容量治理的对象不只是“数据体积”,而是由数据增长、索引膨胀、WAL 与复制、连接与内存、备份与归档共同构成的资源体系。本章先建立一张全景图:容量为什么增长、成本由哪些维度构成、治理目标如何定义,以及后续 29 章按什么路线推进。
一、容量增长的驱动因素
把 PostgreSQL 的容量增长拆开看,可以归为五类驱动因素,它们对存储、内存、IO 和成本的影响路径并不相同。
1. 业务数据自然增长。这是最直观的一类。以一张订单表为例,假设日均新增 50 万行,单行平均 400 字节(含行头与对齐),则每日净增约 200MB,一年约 70GB。若表上有 3 个 B-tree 索引,每个索引条目约 30 字节,则索引每日再增约 45MB。数据与索引的比例通常在 1:0.3 到 1:1 之间,取决于索引数量和列宽。
2. 更新与删除导致的膨胀。PostgreSQL 的 MVCC 机制不会原地更新,UPDATE 会写入新版本行,旧版本由 VACUUM 回收。如果 autovacuum 跟不上,死元组会持续占用页面空间。一张 100GB 的表,若长期有 30% 死元组未回收,实际占用可能达到 130GB 以上,而有效数据仍是 100GB。索引同样会膨胀,B-tree 页分裂后即使删除大量数据,页面也不会自动归还操作系统。
3. WAL 与复制流量。WAL 的生成量与写入事务量成正比。高写入场景下,WAL 可能达到数据文件增速的 2 到 5 倍。若配置了流复制或逻辑复制,WAL 还需保留到备库确认,pg_wal 目录可能堆积数十 GB。逻辑复制槽若长期未消费,WAL 会无限增长,这是生产环境常见的容量事故。
4. 连接与内存占用。每个后端连接约占用 5 到 10MB 基础内存,加上 work_mem、维护操作和缓存,数百连接可能消耗数 GB 内存。连接数增长不会直接增加磁盘,但会推高内存规格,进而影响实例成本。
5. 备份、归档与临时文件。全量备份、WAL 归档、pg_basebackup 副本、排序与哈希溢出的临时文件,都会占用存储。一个 500GB 的实例,若保留 7 天全备加连续归档,备份侧存储可能达到 1TB 以上。
二、成本构成维度
容量成本可以分成直接成本与隐性成本两层。直接成本包括:实例规格(CPU/内存)、存储容量与 IOPS、备份存储、跨区流量、以及只读副本。以云上 RDS 为例,一个 8 核 32GB、500GB SSD 的实例,月成本可能在 3000 到 5000 元;若存储涨到 2TB,存储费用可能翻倍。隐性成本则包括:查询变慢导致的业务损失、膨胀引发的锁等待与故障、以及 DBA 手动清理膨胀所消耗的人力。
一个实用的判断指标是单位业务量成本:用月总成本除以月订单数或月活跃用户数。如果这个比值持续上升,说明容量治理没有跟上业务增长。另一个指标是容量增速与业务增速的比值,健康状态下应接近 1:1,若长期大于 1.5:1,就需要排查膨胀、索引冗余或 WAL 堆积。
三、治理目标与课程路线图
本课程的治理目标可以概括为三句话:增速可控、空间可回收、成本可解释。增速可控指数据与索引增长与业务增长匹配;空间可回收指膨胀、冗余索引、过期分区能够被识别并释放;成本可解释指每一笔存储和实例费用都能归因到具体表、索引或配置项。
后续章节按四条主线推进。第一条是度量与基线:如何用 pg_stat_user_tables、pgstattuple、pg_relation_size 等工具建立容量基线,识别增长最快的对象。第二条是膨胀治理:autovacuum 调优、VACUUM FULL 与 pg_repack 的取舍、索引重建策略。第三条是存储与分区:分区表设计、冷热分离、归档与清理、表空间规划。第四条是成本优化与复盘:实例规格选择、只读副本与连接池、备份策略压缩、以及月度容量复盘机制。