PostgreSQL Performance Farm 还没有真正落地,但项目已经出现了更具体的推进路径:借助 AWS 开源项目额度,在 EC2 上重新开展大规模 OLTP 测试,并更新 OSDL 时期留下的测试工具,尤其是 DBT-5。当前设想是从 r5b.4xlarge 实例和多块 EBS 卷入手,评估一种类似 TPC-E、I/O 与计算压力相对均衡的负载。
这件事的价值不只是得到一个 TPS 数字。一个可重复运行的 Performance Farm,应该能回答 PostgreSQL 开发者经常遇到的几个问题:某次提交是否造成性能回退,瓶颈来自 CPU、存储还是锁竞争,以及不同 PostgreSQL、内核和实例配置之间的差异是否稳定存在。
为什么考虑 TPC-E 类负载
TPC-C 常被用来衡量 OLTP 性能,但它并不覆盖所有数据库压力形态。来源摘要提出采用 TPC-E 类工作负载,理由是它在 I/O 与计算需求之间更均衡,适合用来检验 PostgreSQL 在 EC2 上的综合表现。
这里需要注意“类似 TPC-E”与“正式 TPC-E 成绩”的区别。前者可以借鉴交易模型、表规模和事务组合,用于工程回归测试;后者则涉及严格的规范、审计和披露要求。Performance Farm 更现实的目标是建立稳定的内部基线,而不是发布未经认证的官方基准成绩。
DBT-5 是这条路线上的重要资产。它来自较早期的 OSDL 测试工作,但多年没有进行大规模更新。现代化工作至少需要处理以下问题:
- 让构建、数据生成和运行过程适配当前 Linux 与 PostgreSQL 版本。
- 将云实例、EBS 卷和数据库参数写入机器可读的测试清单。
- 分离数据装载、预热、稳态测试和冷却阶段。
- 同时采集 TPS、延迟分位数、WAL、检查点、CPU、I/O 和锁等待指标。
- 保存原始数据,使不同提交、实例类型和存储布局能够重新比较。
多块 EBS 卷带来的机会与变量
计划中的起点是 r5b.4xlarge,并尽可能连接多块块设备。多卷布局能够提高可用的总吞吐量和 IOPS,也可以把数据、WAL、临时文件或备份流量拆开。不过,卷数增加并不自动等于数据库更快。
测试至少要固定这些条件:
- EC2 实例型号、虚拟 CPU 数量、内存和 NUMA 拓扑。
- EBS 卷类型、容量、预置 IOPS、吞吐量和卷数量。
- 文件系统、挂载参数、RAID 条带大小与块设备队列参数。
- PostgreSQL 版本、编译选项、扩展及全部非默认参数。
- 数据集大小、连接数、预热时间和测试持续时间。
还要避免一个常见误判:当实例级 EBS 带宽已经饱和时,继续增加卷不会带来线性收益。相反,如果测试时间太短,缓存、突发额度或检查点尚未进入稳定状态,结果可能显得异常乐观。
可以这样实践:先建立可重复的 EC2 基线
下面不是来源中已经公布的 Performance Farm 实现,而是一套可以改造的最小实验流程。示例假设测试机运行 Ubuntu,已经安装 PostgreSQL 客户端,并且数据库可通过环境变量访问。它使用 pgbench 做基础校验,不等同于 DBT-5 或 TPC-E 类工作负载。
安装观测工具和 pgbench:
sudo apt-get update
sudo apt-get install -y postgresql-client sysstat fio jq
export PGHOST=127.0.0.1
export PGPORT=5432
export PGUSER=postgres
export PGDATABASE=perf
初始化一个明显大于共享缓冲区的数据集。将比例因子和并发数改成适合实例内存与目标测试规模的值:
createdb "$PGDATABASE"
pgbench --initialize --scale=500 "$PGDATABASE"
mkdir -p results
pgbench \
--client=64 \
--jobs=16 \
--time=900 \
--progress=10 \
--report-latencies \
"$PGDATABASE" 2>&1 | tee results/pgbench.txt
测试期间,在另一个终端采集主机和 PostgreSQL 指标:
iostat -xz 10 90 > results/iostat.txt &
vmstat 10 90 > results/vmstat.txt &
psql -X -v ON_ERROR_STOP=1 -Atc "
SELECT now(), checkpoints_timed, checkpoints_req,
buffers_checkpoint, buffers_backend
FROM pg_stat_bgwriter;
" > results/bgwriter-before.txt
如果要单独测量挂载点的存储能力,可以使用 fio。下面的命令会在指定目录创建测试文件;运行前必须把 TEST_DIR 改成专用测试挂载点,并确认其中没有需要保留的数据:
export TEST_DIR=/mnt/benchmark
mkdir -p "$TEST_DIR"
fio --name=oltp-randrw \
--directory="$TEST_DIR" \
--filename=fio-test.bin \
--size=20G \
--rw=randrw \
--rwmixread=70 \
--bs=8k \
--ioengine=libaio \
--iodepth=32 \
--numjobs=4 \
--direct=1 \
--runtime=300 \
--time_based=1 \
--group_reporting=1 \
--output-format=json \
--output=results/fio.json
rm -f "$TEST_DIR/fio-test.bin"
fio 结果只能描述块存储的一部分能力,不能替代数据库测试。PostgreSQL 还会受到 WAL 刷盘、后台写入、检查点、锁、缓存命中率和执行计划影响。
让每次运行都留下可比较的证据
性能农场最难的部分通常不是启动压测,而是保证几周后仍能解释结果。可以在每次运行前生成一份环境快照:
{
echo "timestamp=$(date --iso-8601=seconds)"
echo "kernel=$(uname -r)"
echo "postgres=$(psql -X -Atc 'SHOW server_version')"
echo "instance_type=$(curl -fsS --max-time 2 http://169.254.169.254/latest/meta-data/instance-type || true)"
echo "commit=${GIT_COMMIT:-unknown}"
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT
} > results/environment.txt
psql -X -Atc "SELECT name || '=' || setting FROM pg_settings ORDER BY name" \
> results/postgresql-settings.txt
在启用了 IMDSv2 的 EC2 环境中,上述元数据请求需要改为先获取令牌。生产化脚本还应记录 AMI、EBS 参数、挂载选项、数据库初始化方式和测试工具版本,避免把基础设施变化误判为 PostgreSQL 回归。
从一次压测走向 Performance Farm
AWS 额度解决了大规模测试最直接的资源门槛,但长期运行仍需要严格控制成本与实验设计。建议按以下顺序推进:
- 用单一实例和固定卷布局建立稳定基线,连续重复测试并计算波动范围。
- 更新 DBT-5 的构建和运行流程,同时保留原始事务与延迟数据。
- 分别改变连接数、数据规模和存储布局,不要在一次实验中同时修改多个变量。
- 将实例、卷和数据库参数纳入版本控制,并设置自动关机和预算告警。
- 只有当预热、稳态区间和重复次数固定后,才比较 PostgreSQL 提交或版本。
Performance Farm 是否成功,不取决于某次跑出多高的吞吐量,而取决于结果能否复现、解释和用于定位回退。以 r5b.4xlarge 和多卷存储完成系统定型,再逐步引入 DBT-5 与 TPC-E 类负载,是一条务实的启动路线;真正需要守住的边界,则是成本、基准合规性以及云环境中的性能波动。