pgbench是PostgreSQL官方自带的免费性能压测工具,无需额外安装,是数据库运维和开发者测试PostgreSQL吞吐量的首选工具。本文通过在2核i5-4260U服务器上的真实压测数据,详解TPS指标含义、pgbench核心参数、不同并发下的性能表现,帮你精准找到数据库的最佳并发数和最大TPS峰值,同时解决压测过程中常见的"too many clients already"报错问题。
一、TPS 概念解释
tps:transactions per second(每秒事务数)的缩写 在pgbench的测试结果中,tps表示数据库每秒钟能够完成多少个事务
- 对于只读测试,一个“事务”就是一条select查询语句
- 对于默认的tpc-B测试(读写混合),一个事务是一个完整的业务单元:begin–>更新账户–>查询余额–>更新出纳员–>更新分行–>插入历史–>commit tps是衡量数据库吞吐量(处理能力)最核心的指标,tps越高,代表数据库在单位时间内能处理的请求越多,性能越好。
二、pgbench 测试参数解释
常用测试命令示例
pgbench -S -c 16 -j 4 -T 60 -M prepared -r pgbench_test
pgbench -c 16 -j 4 -T 60 -M prepared -r pgbench_test
只读模式(-S),并发16,线程4,持续60s
postgres@lzy:~$ pgbench -S -c 16 -j 4 -T 60 -M prepared -r pgbench_test
pgbench (16.13 (Ubuntu 16.13-0ubuntu0.24.04.1))
starting vacuum...end.
transaction type: <builtin: select only>
scaling factor: 100
query mode: prepared
number of clients: 16
number of threads: 4
maximum number of tries: 1
duration: 60 s
number of transactions actually processed: 2262366
number of failed transactions: 0 (0.000%)
latency average = 0.424 ms
initial connection time = 21.638 ms
tps = 37719.421242 (without initial connection time)
statement latencies in milliseconds and failures:
0.001 0 \set aid random(1, 100000 * :scale)
0.420 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
读写混合模式,并发16,线程4,持续60s
postgres@lzy:~$ pgbench -c 16 -j 4 -T 60 -M prepared -r pgbench_test
pgbench (16.13 (Ubuntu 16.13-0ubuntu0.24.04.1))
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 100
query mode: prepared
number of clients: 16
number of threads: 4
maximum number of tries: 1
duration: 60 s
number of transactions actually processed: 94767
number of failed transactions: 0 (0.000%)
latency average = 10.258 ms
initial connection time = 20.287 ms
tps = 1559.782572 (without initial connection time)
statement latencies in milliseconds and failures:
0.002 0 \set aid random(1, 100000 * :scale)
0.001 0 \set bid random(1, 1 * :scale)
0.001 0 \set tid random(1, 10 * :scale)
0.001 0 \set delta random(-5000, 5000)
0.320 0 BEGIN;
0.533 0 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
0.465 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
0.377 0 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
0.908 0 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
0.232 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
7.273 0 END;
参数说明
- -S:只读模式,加上-S时,只执行select查询,不执行更新/插入。不加时执行默认的tpc-B读写混合事务
- -c:客户端并发数
- -j:工作线程数,使用指定数量的cpu线程来驱动这些客户端。通常设为cpu核心数
- -T:测试持续时间,压测持续时间,如果不指定-T或-t,默认只运行10s
- -r:在测试结束后,额外输出每条 SQL 语句的平均耗时
- -M:查询模式,使用预处理语句,可以减少sql解析和计划开销,使测试更聚焦于数据库执行性能
三、服务器 CPU 信息与 pgbench -j 参数最佳实践
postgres@lzy:~$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Address sizes: 39 bits physical, 48 bits virtual
Byte Order: Little Endian
CPU(s): 4 逻辑cpu总数
On-line CPU(s) list: 0-3
Vendor ID: GenuineIntel
Model name: Intel(R) Core(TM) i5-4260U CPU @ 1.40GHz
CPU family: 6
Model: 69
Thread(s) per core: 2 物理核心数
Core(s) per socket: 2 每个核心2个超线程
Socket(s): 1
Stepping: 1
CPU(s) scaling MHz: 52%
结论:根据电脑cpu情况,-j 线程数建议为物理核心数2,让每个核心处理一个工作线程。
四、pgbench 测试结果
测试1:读写混合模式,不同并发(4/8/16/32/64),线程2,持续30s
4.1 并发4,线程2
postgres@lzy:~$ pgbench -c 4 -j 2 -T 30 -M prepared -r pgbench_test
pgbench (16.13 (Ubuntu 16.13-0ubuntu0.24.04.1))
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 100
query mode: prepared
number of clients: 4
number of threads: 2
maximum number of tries: 1
duration: 30 s
number of transactions actually processed: 33938
number of failed transactions: 0 (0.000%)
latency average = 3.535 ms
initial connection time = 8.900 ms
tps = 1131.527031 (without initial connection time)
statement latencies in milliseconds and failures:
0.002 0 \set aid random(1, 100000 * :scale)
0.001 0 \set bid random(1, 1 * :scale)
0.001 0 \set tid random(1, 10 * :scale)
0.001 0 \set delta random(-5000, 5000)
0.091 0 BEGIN;
0.246 0 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
0.116 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
0.135 0 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
0.206 0 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
0.103 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
2.634 0 END;
4.2 并发8,线程2
postgres@lzy:~$ pgbench -c 8 -j 2 -T 30 -M prepared -r pgbench_test
pgbench (16.13 (Ubuntu 16.13-0ubuntu0.24.04.1))
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 100
query mode: prepared
number of clients: 8
number of threads: 2
maximum number of tries: 1
duration: 30 s
number of transactions actually processed: 36874
number of failed transactions: 0 (0.000%)
latency average = 6.702 ms
initial connection time = 13.167 ms
tps = 1193.745774 (without initial connection time)
statement latencies in milliseconds and failures:
0.002 0 \set aid random(1, 100000 * :scale)
0.001 0 \set bid random(1, 1 * :scale)
0.001 0 \set tid random(1, 10 * :scale)
0.001 0 \set delta random(-5000, 5000)
0.162 0 BEGIN;
0.342 0 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
0.236 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
0.232 0 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
0.388 0 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
0.155 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
5.060 0 END;
4.3 并发16,线程2
postgres@lzy:~$ pgbench -c 16 -j 2 -T 30 -M prepared -r pgbench_test
pgbench (16.13 (Ubuntu 16.13-0ubuntu0.24.04.1))
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 100
query mode: prepared
number of clients: 16
number of threads: 2
maximum number of tries: 1
duration: 30 s
number of transactions actually processed: 71725
number of failed transactions: 0 (0.000%)
latency average = 6.845 ms
initial connection time = 26.046 ms
tps = 2337.479811 (without initial connection time)
statement latencies in milliseconds and failures:
0.002 0 \set aid random(1, 100000 * :scale)
0.001 0 \set bid random(1, 1 * :scale)
0.001 0 \set tid random(1, 10 * :scale)
0.001 0 \set delta random(-5000, 5000)
0.296 0 BEGIN;
0.500 0 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
0.444 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
0.301 0 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
0.636 0 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
0.237 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
4.284 0 END;
4.4 并发32,线程2
postgres@lzy:~$ pgbench -c 32 -j 2 -T 30 -M prepared -r pgbench_test
pgbench (16.13 (Ubuntu 16.13-0ubuntu0.24.04.1))
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 100
query mode: prepared
number of clients: 32
number of threads: 2
maximum number of tries: 1
duration: 30 s
number of transactions actually processed: 75520
number of failed transactions: 0 (0.000%)
latency average = 13.173 ms
initial connection time = 51.288 ms
tps = 2429.190715 (without initial connection time)
statement latencies in milliseconds and failures:
0.002 0 \set aid random(1, 100000 * :scale)
0.001 0 \set bid random(1, 1 * :scale)
0.001 0 \set tid random(1, 10 * :scale)
0.001 0 \set delta random(-5000, 5000)
0.455 0 BEGIN;
0.694 0 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
0.825 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
0.624 0 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
1.855 0 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
0.495 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
7.975 0 END;
4.5 并发64,线程2
postgres@lzy:~$ pgbench -c 64 -j 2 -T 30 -M prepared -r pgbench_test
pgbench (16.13 (Ubuntu 16.13-0ubuntu0.24.04.1))
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 100
query mode: prepared
number of clients: 64
number of threads: 2
maximum number of tries: 1
duration: 30 s
number of transactions actually processed: 74684
number of failed transactions: 0 (0.000%)
latency average = 26.209 ms
initial connection time = 104.197 ms
tps = 2441.905430 (without initial connection time)
statement latencies in milliseconds and failures:
0.002 0 \set aid random(1, 100000 * :scale)
0.001 0 \set bid random(1, 1 * :scale)
0.001 0 \set tid random(1, 10 * :scale)
0.001 0 \set delta random(-5000, 5000)
0.846 0 BEGIN;
1.493 0 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
1.856 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
1.884 0 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
6.508 0 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
1.821 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
11.481 0 END;
五、测试结论
并发: 4 8 16 32 64
TPS: 1131 1194 2337 2429 2442
- 4 → 8 并发:TPS 几乎不变(1131 → 1194),延迟从 3.5ms 涨到 6.7ms。说明并发翻倍但没有带来吞吐量提升,资源开始出现竞争。
- 8 → 16 并发:TPS 翻倍(1194 → 2337),这是合理的提升。延迟基本持平(6.7ms → 6.8ms)。说明在 16 并发以内,系统还能有效利用并发。
- 16 → 32 并发:TPS 几乎不再增长(2337 → 2429),仅增加 4%,而延迟翻倍(6.8ms → 13.2ms)。
- 32 → 64 并发:TPS 完全停滞(2429 → 2442),延迟再次翻倍(13.2ms → 26.2ms)。
核心结论
性能拐点在 16 并发。超过 16 后,增加并发只会让延迟飙升,吞吐量基本不变。最大 TPS 约 2440(在当前硬件和配置下)。 当前服务器(2 核 i5-4260U,默认 PostgreSQL 配置)在 pgbench 读写混合测试中,最大 TPS 约 2440,最佳并发 16。性能瓶颈主要是磁盘写入延迟(WAL fsync)和单行表锁竞争,CPU 和内存不是首要限制。
六、常见报错:too many clients already 解决方案
报错信息
postgres@lzy:~$ postgres@lzy:~$ pgbench -c 128 -j 2 -T 30 -M prepared -r pgbench_test
pgbench (16.13 (Ubuntu 16.13-0ubuntu0.24.04.1))
starting vacuum...end.
pgbench: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: FATAL: sorry, too many clients already
pgbench: error: could not create connection for client 113
排查结果
postgres=# show max_connections;
max_connections
100
(1 row)
相关阅读
Ubuntu 24.04 部署与卸载 PostgreSQL 16.13 教程(新手必看) https://wdhlzy.xyz/posts/postgresql-ubuntu-install/
PostgreSQL 核心知识点与实操演练(含电商订单统计案例) https://wdhlzy.xyz/posts/postgres/