ITPub博客

首页 > 数据库 > PostgreSQL > 数据库教程FGMT65‑PostgreSQL性能优化之基准测试

数据库教程FGMT65‑PostgreSQL性能优化之基准测试

原创 PostgreSQL 作者:mfkqwyc86 时间:2026-10-21 11:24:26 0 删除 编辑

数据库教程FGMT65‑PostgreSQL性能优化之基准测试


## 前言


数据库性能基准测试是PostgreSQL性能调优工作的前置核心环节,很多运维人员在做数据库优化时,跳过基准测试直接调整参数,最终导致优化效果无法量化,无法区分性能变化来自参数调整、业务负载波动还是硬件层面的差异。风哥教程本文将围绕PostgreSQL基准测试完整流程展开,从基准测试基础理论、测试指标定义、主流压测工具原理,再到多套工具落地实战,完整覆盖基准测试从环境准备、数据初始化、压测执行、指标采集、结果对比分析全链路操作。


本套风哥教程面向PostgreSQL数据库运维、DBA、数据库性能调优工程师,阅读本文前,读者需要掌握PostgreSQL基础运维操作、Linux操作系统基础命令,理解操作系统CPU、内存、IO、网络基础原理。本文整体结构分为四大模块,第一部分为前言与大纲介绍,帮助读者理清学习脉络;第二部分为基准测试理论知识,讲解基准测试核心概念、负载模型、评价指标、测试环境隔离原则、主流压测工具选型对比;第三部分为实战操作,依次完成环境准备、pgbench压测实战、sysbench压测实战、BenchmarkSQL压测实战,包含大量可直接执行的操作命令、配置文件修改、监控采集脚本、压测结果解读;第四部分为总结,梳理基准测试常见坑点与标准化测试流程。


在数据库性能优化工作中,基准测试的核心价值,是建立一套可复现的性能基线。没有基线,所有性能调优都属于主观猜测。当我们更换硬件、调整数据库参数、升级内核、修改业务SQL、调整索引结构之后,只有通过相同负载模型下的基准测试,才能量化吞吐量、响应延迟的变化,判断优化动作是否有效。很多人会混淆压力测试与基准测试,压力测试偏向于寻找系统崩溃临界点,而基准测试,是在固定环境、固定数据集、固定负载模型下,获取稳定、可重复的性能指标,用来做横向、纵向对比。基准测试要求环境干净、负载单一,尽可能排除外部干扰,这也是风哥在实施基准测试时最看重的基本原则。


## 一、基准测试理论


### 1.1 基准测试核心概念


基准测试,英文Benchmark,是在标准化可控环境下,使用固定的业务负载模型对数据库系统施加压力,采集系统与数据库各项性能指标,以此评估数据库系统吞吐能力、响应延迟、资源消耗特征的一套标准化测试流程。基准测试的首要要求是**可复现**,两次测试之间,硬件环境、操作系统配置、数据库参数、数据量、测试脚本、并发连接数必须保持一致,得到的结果才具备对比意义。


基准测试分为两大类,一类是微基准测试,另一类是业务场景基准测试。微基准测试,用来单独测试数据库某一个能力点,比如单条点查询性能、批量写入性能、索引扫描性能、大事务提交性能,负载模型简单,用来定位数据库单点能力上限,适合参数调优阶段使用。业务场景基准测试,模拟真实业务混合负载,读写混合,包含查询、更新、删除、事务提交,贴近线上真实业务模型,用来评估整套数据库在业务负载下的综合性能,一般上线前容量评估、架构选型时使用。


做基准测试有一条黄金原则:测试环境尽可能贴近生产环境。如果生产是64G内存、8CPU服务器,测试环境也必须匹配硬件规格;操作系统版本、内核参数、磁盘阵列配置、文件系统、数据库版本、插件、表结构、数据分布特征都要对齐。如果测试环境硬件规格低于生产,压测结果只能做定性参考,不能用来做容量评估。本文所有环境、参数配置,全部基于64G内存,8CPU的服务器规格,主机分别为fgedu-net-cn1作为数据库服务端,fgedu-net-cn2作为压测客户端,压测客户端与数据库服务端分离,避免压测程序抢占数据库服务器CPU资源,干扰测试结果。


风哥 itpux-com


### 1.2 基准测试核心评价指标


在PostgreSQL基准测试中,我们重点关注四大类指标:吞吐量、响应延迟、资源利用率、错误率。


吞吐量,单位通常为TPS(每秒事务数)或者QPS(每秒查询数)。TPS代表数据库每秒成功完成的事务数量,事务是一组原子性SQL操作,适合OLTP事务型业务;QPS代表每秒执行的SQL语句数量,适合只读查询场景。吞吐量越高,代表数据库在当前负载下处理请求的能力越强。但不能单独只看TPS,必须结合延迟一起分析,高TPS伴随延迟暴涨,说明系统已经进入瓶颈区。


响应延迟,分为平均延迟、中位数延迟、95分位延迟、99分位延迟。平均延迟容易被大量低延迟请求拉低,掩盖少数慢请求问题,性能分析中,95分位、99分位延迟价值远高于平均值。95分位延迟含义:95%的请求,响应时间小于该数值,剩余5%请求延迟高于该值。OLTP业务对尾延迟极其敏感,线上业务用户感知,往往由99分位延迟决定。


资源利用率:CPU使用率、内存使用量、磁盘IO(读IOPS、写IOPS、读写吞吐量、磁盘await)、网络带宽。压测过程中,持续监控资源指标,定位系统瓶颈。CPU瓶颈特征:CPU使用率持续接近100%,us或者sy占比高;IO瓶颈特征:磁盘await升高,util接近100%,CPU空闲;内存瓶颈:大量swap交换,page out频繁,数据库缓存命中率下降。


错误率:压测过程中事务失败、SQL报错、连接断开的比例。基准测试有效数据,必须建立在错误率接近0的前提下,如果压测出现大量事务回滚、连接超时,此时TPS、延迟数据没有参考价值,需要排查环境问题,重新执行测试。


### 1.3 负载模型与行业标准TPC规范


行业最知名的联机事务处理基准规范是TPC-C,模拟仓库订单交易业务模型,包含新订单、支付、订单状态查询、发货、库存查询五类事务,读写混合,有事务、锁、并发冲突,是OLTP数据库最经典的负载模型。BenchmarkSQL工具就是基于TPC-C模型实现,适合评估PostgreSQL混合事务负载能力。


除TPC-C之外,还有TPC-H面向OLAP分析型查询,大量复杂多表关联、聚合计算,适合数仓场景;TPC-DS是新一代大数据分析基准。针对PostgreSQL OLTP日常基准测试,风哥日常优先使用pgbench做轻量快速基准测试,sysbench做通用读写压测,BenchmarkSQL做标准TPC-C复杂事务压测。


在设计压测负载时,要区分只读负载、只写负载、读写混合负载。只读负载压力主要消耗CPU与内存,大量访问shared buffers;写入负载会产生WAL日志,触发刷脏页,压力落在磁盘IO上;读写混合负载,同时存在查询、修改,会产生行锁竞争,是最贴近线上OLTP业务的负载类型。


风哥教程 113257174


### 1.4 基准测试环境隔离与避坑原则


基准测试环境必须做隔离,任何额外后台任务都会污染测试结果。在压测执行前,需要关闭服务器不必要的定时任务:系统日志轮转、备份任务、监控采集高频脚本、病毒扫描、定时统计任务。PostgreSQL数据库侧,关闭自动vacuum,压测阶段手动控制vacuum时机,防止vacuum后台进程随机占用IO与CPU,造成两次压测结果波动。


操作系统层面,关闭透明大页,调整磁盘调度算法,关闭不必要的服务。测试前清理操作系统页缓存与数据库shared buffers缓存,保证每一轮测试的初始状态一致。但是要区分两种测试场景:冷启动测试,数据库缓存为空,模拟数据库刚启动,数据全部从磁盘读取;热启动测试,数据已经加载到内存缓存,模拟数据库长时间稳定运行场景。线上绝大多数业务都是热缓存场景,所以日常基准测试优先执行热压测。


测试执行时,单变量原则,每次基准测试,只能修改一个变量。例如,第一次基线测试,使用默认参数;第二次测试,仅调整shared_buffers,其余所有条件保持不变。如果同时修改数据库参数、并发数、数据量,最后无法判断性能变化到底由哪一项改动引起,这是基准测试最容易踩的大坑。


### 1.5 主流压测工具选型对比


PostgreSQL生态内常用三款压测工具:pgbench、sysbench、BenchmarkSQL。


pgbench是PostgreSQL原生自带压测工具,不需要额外安装,轻量易用,支持自定义SQL脚本,内置简单TPC-B负载模型,适合快速基线采集、微基准测试、参数快速验证。优点:原生适配,部署简单;缺点:内置负载模型相对简单,复杂事务场景能力弱。


sysbench是跨数据库通用压测工具,支持PostgreSQL、MySQL等多种数据库,lua脚本驱动,灵活自定义负载。支持点查询、范围查询、插入、更新等多种读写模型,适合做读写分离、单表压测场景。优点:灵活,跨数据库;缺点:需要手动编译安装,原生没有完整TPC-C事务模型。


BenchmarkSQL,专门实现TPC-C标准负载模型,多仓库业务模型,包含多表关联、事务、锁冲突,模拟真实电商订单OLTP业务。优点:负载模型最贴近标准TPC-C;缺点:依赖Java环境,部署复杂,压测资源消耗大,测试耗时更长。


三款工具不是互相替代,而是互补。快速验证参数,用pgbench;单表读写场景,用sysbench;需要标准OLTP混合事务基准,使用BenchmarkSQL。


风哥数据库教程 itpux-com


## 二、实战操作


### 2.1 环境规划与操作系统配置


本次测试环境一共两台服务器:

fgedu-net-cn1:数据库服务端,64G内存,8CPU;

fgedu-net-cn2:压测客户端,用来运行压测程序,避免压测进程占用数据库服务器资源。

数据库实例名:fgedudb;数据库用户名:fgedu;数据库名称:fgedudb;数据库数据目录:/fgedudb/data;WAL日志目录:/fgedudb/wal。


所有操作使用root用户执行系统配置,数据库相关操作切换为fgedu用户。

第一步,操作系统基础优化,两台服务器都执行。


```

# 关闭透明大页

echo never > /sys/kernel/mm/transparent_hugepage/enabled

echo never > /sys/kernel/mm/transparent_hugepage/defrag


# 修改磁盘调度算法,假设数据盘为sdb

echo deadline > /sys/block/sdb/queue/scheduler


# 调整内核参数,编辑/etc/sysctl.conf

cat >> /etc/sysctl.conf <<EOF

kernel.shmmax = 34359738368

kernel.shmall = 8388608

vm.swappiness = 10

vm.dirty_ratio = 40

vm.dirty_background_ratio = 10

net.ipv4.tcp_syncookies = 1

net.core.somaxconn = 1024

net.ipv4.tcp_tw_reuse = 1

EOF

sysctl -p


# 资源限制,编辑/etc/security/limits.conf

cat >> /etc/security/limits.conf <<EOF

fgedu soft nofile 65535

fgedu hard nofile 65535

fgedu soft nproc 65535

fgedu hard nproc 65535

EOF

```


修改完成之后,重新登录服务器,检查limits生效。


```

su - fgedu

ulimit -n

ulimit -u

```


预期输出65535。


网上搜索风哥教程可以学习全套数据库教程


### 2.2 PostgreSQL数据库初始化与参数配置


登录fgedu-net-cn1服务器,切换fgedu用户,初始化数据库实例,数据目录/fgedudb/data,wal目录/fgedudb/wal。


```

# 创建目录,授权

mkdir -p /fgedudb/data /fgedudb/wal

chown fgedu:fgedu /fgedudb/data /fgedudb/wal

chmod 700 /fgedudb/data


# 初始化实例

initdb -D /fgedudb/data -W -U fgedu

```


初始化完成后,编辑postgresql.conf文件,按照64G内存、8CPU规格修改核心参数。


```

listen_addresses = '*'

port = 5432

max_connections = 500

shared_buffers = 16GB

work_mem = 64MB

maintenance_work_mem = 2GB

effective_cache_size = 48GB

max_worker_processes = 8

max_parallel_workers_per_gather = 4

max_parallel_workers = 8

wal_level = minimal

max_wal_size = 4GB

min_wal_size = 1GB

wal_buffers = 16MB

synchronous_commit = off

checkpoint_timeout = 15min

checkpoint_completion_target = 0.9

autovacuum = off

log_min_duration_statement = 1000

```


修改pg_hba.conf,允许fgedu-net-cn2客户端访问数据库。


```

host    all             all             fgedu-net-cn2/32        trust

```


启动数据库实例


```

pg_ctl -D /fgedudb/data start

```


创建测试数据库fgedudb


```

createdb -U fgedu fgedudb

```


验证数据库连接,在fgedu-net-cn2客户端执行:


```

psql -h fgedu-net-cn1 -p 5432 -U fgedu -d fgedudb

```


能够正常进入psql交互终端,代表数据库环境就绪。


### 2.3 pgbench基准测试实战


pgbench是原生工具,无需额外安装,直接在压测客户端fgedu-net-cn2执行。pgbench测试分为数据初始化、压测执行、结果分析三个阶段。


#### 2.3.1 pgbench初始化测试数据


pgbench内置测试表,分别为pgbench_accounts、pgbench_branches、pgbench_tellers、pgbench_history。scale参数代表数据缩放因子,scale=1,pgbench_accounts表10万行数据;scale=100,数据量1000万行。本次测试scale=100。


```

pgbench -h fgedu-net-cn1 -p 5432 -U fgedu -d fgedudb -i -s 100

```


参数说明:

-i:初始化模式;

-s:缩放因子scale;

初始化完成后,登录数据库查看表行数:


```

select count(*) from pgbench_accounts;

```


查询结果应该返回10000000。


初始化完成,执行冷压测前,先确认数据库缓存为空。生产环境基准测试更多是热缓存场景,所以先执行一轮预热,将数据加载进shared buffers。


```

pgbench -h fgedu-net-cn1 -p 5432 -U fgedu -d fgedudb -c 8 -j 8 -T 60

```


-c 并发连接数;-j pgbench线程数;-T 持续压测时间,单位秒。预热60秒,结束之后,正式开始基准测试。


#### 2.3.2 pgbench只读负载压测


只读负载,调用pgbench内置select-only脚本,模拟大量点查询。


```

pgbench -h fgedu-net-cn1 -p 5432 -U fgedu -d fgedudb -c 8 -j 8 -T 300 -S

```


参数-S:只读模式。压测持续300秒,压测结束后输出结果,重点查看tps、平均延迟、95分位延迟。


#### 2.3.3 pgbench读写混合TPC-B压测


不增加-S参数,默认使用内置TPC-B混合事务脚本,包含select、update、insert操作,属于OLTP混合负载。


```

pgbench -h fgedu-net-cn1 -p 5432 -U fgedu -d fgedudb -c 8 -j 8 -T 300

```


压测执行期间,在fgedu-net-cn1数据库服务器开启监控,采集系统指标。


```

# 监控CPU

top


# 监控磁盘IO

iostat -x 1


# 查看数据库会话

psql -h localhost -U fgedu -d fgedudb -c "select pid,state,wait_event_type,wait_event from pg_stat_activity where state='active';"

```


压测完成后,记录TPS,延迟数据,保存输出日志。将结果写入基线文档。


上51CTO搜索风哥可以学习全套数据库教程


#### 2.3.4 pgbench自定义SQL脚本压测


很多场景内置脚本不满足需求,可以编写自定义压测脚本custom.sql。


```

\set aid random(1, 10000000)

SELECT * FROM pgbench_accounts WHERE aid = :aid;

```


执行自定义脚本压测:


```

pgbench -h fgedu-net-cn1 -p 5432 -U fgedu -d fgedudb -c 8 -j 8 -T 300 -f custom.sql

```


pgbench支持变量、随机函数,能够模拟业务随机查询场景,适合微基准测试。


### 2.4 sysbench压测实战


sysbench需要在压测客户端fgedu-net-cn2编译安装,sysbench支持PostgreSQL驱动,使用lua脚本定义负载模型。


#### 2.4.1 sysbench编译部署


```

# 安装依赖包

yum install git make automake libtool pkgconfig libaio-devel postgresql-devel -y

git clone [https://github.com/akopytov/sysbench.git](https://github.com/akopytov/sysbench.git)

cd sysbench

./autogen.sh

./configure --with-pgsql

make && make install

# 验证安装

sysbench --version

```


#### 2.4.2 sysbench初始化测试表


使用oltp_point_select.lua脚本,初始化单表数据,表名称sbtest,数据量1000万行。


```

sysbench --db-driver=pgsql --pgsql-host=fgedu-net-cn1 --pgsql-port=5432 --pgsql-user=fgedu --pgsql-db=fgedudb --table-size=10000000 --tables=1 oltp_point_select.lua prepare

```


prepare代表数据初始化阶段,执行完成,登录数据库检查表:


```

select count(*) from sbtest1;

```


#### 2.4.3 sysbench点查询只读压测


```

sysbench --db-driver=pgsql --pgsql-host=fgedu-net-cn1 --pgsql-port=5432 --pgsql-user=fgedu --pgsql-db=fgedudb --table-size=10000000 --tables=1 --threads=8 --time=300 oltp_point_select.lua run

```


run为执行压测,--threads=8压测线程,持续300秒。压测结束输出总事务数、TPS、平均延迟、95分位延迟。


#### 2.4.4 sysbench读写混合压测


```

sysbench --db-driver=pgsql --pgsql-host=fgedu-net-cn1 --pgsql-port=5432 --pgsql-user=fgedu --pgsql-db=fgedudb --table-size=10000000 --tables=1 --threads=8 --time=300 oltp_read_write.lua run

```


oltp_read_write.lua是读写混合脚本,包含select、update、delete事务,适合OLTP混合负载基准测试。压测期间持续监控数据库锁、WAL写入、磁盘刷脏情况。


### 2.5 BenchmarkSQL TPC-C标准压测实战


BenchmarkSQL基于Java实现,模拟标准TPC-C业务模型,多仓库、多表事务模型,更贴近真实电商订单系统。压测客户端fgedu-net-cn2部署BenchmarkSQL。


#### 2.5.1 BenchmarkSQL环境准备


安装Java环境


```

yum install java-1.8.0-openjdk-devel -y

java -version

```


上传BenchmarkSQL压缩包,解压:


```

unzip BenchmarkSQL.zip

cd BenchmarkSQL

```


修改props.pg配置文件,配置数据库连接信息。


```

db=postgres

driver=org.postgresql.Driver

conn=jdbc:postgresql://fgedu-net-cn1:5432/fgedudb

user=fgedu

password=******

warehouses=10

terminals=8

```


warehouses代表仓库数量,仓库越多,数据量越大;terminals并发终端,对应并发连接。本次warehouses=10。


#### 2.5.2 初始化TPC-C测试数据


```

./runSQL.sh props.pg sqlTableCreates

./runSQL.sh props.pg sqlIndexCreates

./runLoader.sh props.pg

```


runLoader.sh会加载TPC-C整套业务表数据,包含warehouse、district、customer、history、order等多张业务表,加载耗时较长。加载完成后,执行统计信息收集。


```

psql -h fgedu-net-cn1 -U fgedu -d fgedudb -c "analyze;"

```


#### 2.5.3 执行TPC-C压测


```

./runBenchmark.sh props.pg

```


BenchmarkSQL启动压测,程序控制台实时输出事务吞吐量,压测结束,生成详细结果报告,包含5类事务各自吞吐量、延迟、失败事务统计。TPC-C测试关注New Order事务吞吐量,这是TPC-C标准核心指标。


### 2.6 基准测试结果采集与对比方法


每一轮压测,都需要完整记录测试清单:服务器硬件信息、操作系统版本、内核参数、postgresql.conf全部参数、数据集大小、压测脚本、并发线程、压测时长。压测过程持续采集指标,推荐写入监控脚本,每2秒输出一次系统状态。


```

#!/bin/bash

while true

do

date >> /fgedudb/bench-monitor.log

iostat -x 1 1 >> /fgedudb/bench-monitor.log

top -b -n1 |head -20 >> /fgedudb/bench-monitor.log

sleep 2

done

```


压测结束后,停止脚本,保存日志文件。


网上搜索风哥教程可以学习全套数据库教程


基线对比方法:第一轮作为基准基线,记录TPS、99延迟、资源使用率。第二轮修改数据库参数,保持其余所有条件完全一致,再次执行相同压测。对比两轮指标:如果TPS上升,尾延迟下降,资源利用率合理,代表优化动作正向有效;如果TPS上涨但是99延迟大幅恶化,CPU或者IO打满,说明系统已经到达瓶颈,优化不可用于线上。


基准测试需要重复执行3次,剔除异常值,取平均值作为最终结果。单次压测结果可能因为随机后台抖动产生偏差,三次结果接近,数据可信度才足够。


### 2.7 基准测试后环境清理工作


压测完成之后,清理测试数据,释放磁盘空间。

pgbench清理:


```

pgbench -h fgedu-net-cn1 -p 5432 -U fgedu -d fgedudb -i -D

```


sysbench清理:


```

sysbench --db-driver=pgsql --pgsql-host=fgedu-net-cn1 --pgsql-port=5432 --pgsql-user=fgedu --pgsql-db=fgedudb --table-size=10000000 --tables=1 oltp_point_select.lua cleanup

```


BenchmarkSQL清理表结构:


```

./runSQL.sh props.pg sqlTableDrops

```


清理完成,登录数据库确认测试表全部删除,数据库恢复干净环境,方便后续新一轮测试。


## 三、风哥针对本文总结


基准测试不是一次性操作,而是PostgreSQL性能优化工作的标准化流程,贯穿容量评估、参数调优、版本验证、架构选型等场景。风哥通过本套风哥教程,完整演示三套主流压测工具从环境准备、数据初始化、压测执行、监控采集、结果对比、环境清理完整实战流程。


首先要明确基准测试和压力测试的区别,基准测试追求稳定可复现基线,核心原则是单变量测试,环境隔离,消除外部干扰。做基准测试不能只看TPS,延迟指标尤其是95、99分位延迟,还有系统资源瓶颈,三者结合才能判断数据库真实性能状态。


三款工具适用场景不同,pgbench适合快速轻量级基准,上手简单,适合日常参数调优验证;sysbench灵活,自定义lua脚本,适合单表读写场景;BenchmarkSQL实现标准TPC-C模型,适合评估复杂混合事务OLTP场景,但部署成本高,测试耗时长。实际工作中,根据测试目标选择合适压测工具,不需要盲目使用复杂工具。


基准测试实操中高频踩坑点:环境不一致,测试和生产硬件差距过大;多变量同时修改,无法定位性能变化根因;压测环境存在后台定时任务干扰;只看平均延迟忽略尾延迟;压测错误率很高仍然采信TPS指标;只执行单次压测,结果偶然性大。以上问题,都会导致基准测试结论失真,误导数据库优化决策。


上51CTO搜索风哥可以学习全套数据库教程


基准测试产出的基线报告,是数据库运维资产。后续数据库任何变更,都可以基于基线做对比,量化性能收益。基准测试是数据库性能优化的起点,而不是终点。拿到基线数据之后,定位瓶颈,针对性调整参数、索引、SQL语句,再使用相同负载复测,验证优化效果,形成闭环调优流程。掌握PostgreSQL基准测试整套方法,DBA才能够客观评估数据库性能,而不是依靠经验主观判断性能好坏。


基准测试学习的核心,不在于背命令,而是建立标准化测试思维。理解负载模型、指标含义、环境控制原则,学会设计贴合业务的压测场景,读懂压测结果,定位系统瓶颈。在后续数据库性能优化工作中,养成先建立基线,再做优化,最后复测验证的工作习惯,才能保障数据库稳定高效运行。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/9664900/viewspace-3186259/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
风哥Oracle,MySQL,PostgreSQL,Linux,大数据,国产数据库,中间件等教程

注册时间:2010-10-26

  • 博文量
    78
  • 访问量
    406512