PostgreSQL压测工具pgbench

PGbench默认是一种宽松场景的基于TPC-B的测试工具。压测主要关注压测TPS、数据量及延迟。

环境介绍:

RHEL 7.5
PG 11.5

环境准备:

PG数据库初始化完成(Port:5435),创建压测用户(pgbench)、表空间(pgbtbs)、数据库(pgbench)。

[postgres@rhel75 ~]$mkdir /postgres/pgbtbs

postgres=# create user pgbench password 'pgbench';

postgres=# CREATE TABLESPACE pgbtbs
postgres-#   OWNER pgbench
postgres-#   LOCATION '/postgres/pgbtbs';
CREATE TABLESPACE

postgres=# CREATE DATABASE pgbench
postgres-#   WITH OWNER = pgbench
postgres-#        ENCODING = 'UTF8'
postgres-#        TABLESPACE = pgbtbs;
CREATE DATABASE

PGbench参数说明:

[postgres@rhel75 ~]$pgbench --help
pgbench is a benchmarking tool for PostgreSQL.

Usage:
  pgbench [OPTION]... [DBNAME]

Initialization options:
  -i, --initialize         invokes initialization mode
  -I, --init-steps=[dtgvpf]+ (default "dtgvp")
                           run selected initialization steps
  -F, --fillfactor=NUM     set fill factor
  -n, --no-vacuum          do not run VACUUM during initialization
  -q, --quiet              quiet logging (one message each 5 seconds)
  -s, --scale=NUM          scaling factor
  --foreign-keys           create foreign key constraints between tables
  --index-tablespace=TABLESPACE
                           create indexes in the specified tablespace
  --tablespace=TABLESPACE  create tables in the specified tablespace
  --unlogged-tables        create tables as unlogged tables

Options to select what to run:
  -b, --builtin=NAME[@W]   add builtin script NAME weighted at W (default: 1)
                           (use "-b list" to list available scripts)
  -f, --file=FILENAME[@W]  add script FILENAME weighted at W (default: 1)
  -N, --skip-some-updates  skip updates of pgbench_tellers and pgbench_branches
                           (same as "-b simple-update")
  -S, --select-only        perform SELECT-only transactions
                           (same as "-b select-only")

Benchmarking options:
  -c, --client=NUM         number of concurrent database clients (default: 1)
  -C, --connect            establish new connection for each transaction
  -D, --define=VARNAME=VALUE
                           define variable for use by custom script
  -j, --jobs=NUM           number of threads (default: 1)
  -l, --log                write transaction times to log file
  -L, --latency-limit=NUM  count transactions lasting more than NUM ms as late
  -M, --protocol=simple|extended|prepared
                           protocol for submitting queries (default: simple)
  -n, --no-vacuum          do not run VACUUM before tests
  -P, --progress=NUM       show thread progress report every NUM seconds
  -r, --report-latencies   report average latency per command
  -R, --rate=NUM           target rate in transactions per second
  -s, --scale=NUM          report this scale factor in output
  -t, --transactions=NUM   number of transactions each client runs (default: 10)
  -T, --time=NUM           duration of benchmark test in seconds
  -v, --vacuum-all         vacuum all four standard tables before tests
  --aggregate-interval=NUM aggregate data over NUM seconds
  --log-prefix=PREFIX      prefix for transaction time log file
                           (default: "pgbench_log")
  --progress-timestamp     use Unix epoch timestamps for progress
  --random-seed=SEED       set random seed ("time", "rand", integer)
  --sampling-rate=NUM      fraction of transactions to log (e.g., 0.01 for 1%)

Common options:
  -d, --debug              print debugging output
  -h, --host=HOSTNAME      database server host or socket directory
  -p, --port=PORT          database server port number
  -U, --username=USERNAME  connect as specified database user
  -V, --version            output version information, then exit
  - , --help               show this help, then exit

Report bugs to .

初始化压测数据

At the default “scale factor” of 1, the tables initially contain this many rows:

table                   # of rows
---------------------------------
pgbench_branches        1
pgbench_tellers         10
pgbench_accounts        100000
pgbench_history         0
You can (and, for most purposes, probably should) increase the number of rows by using the -s (scale factor) option. The -F (fillfactor) option might also be used at this point.

Once you have done the necessary setup, you can run your benchmark with a command that doesn't include -i, that is

测试环境scale factor是10,fillfactor是50,生产环境根据实际配置响应调大

[postgres@rhel75 ~]$pgbench -i -F 10 -s 50 -h localhost -U pgbench -d pgbench
dropping old tables...
creating tables...
generating data...
100000 of 5000000 tuples (2%) done (elapsed 0.07 s, remaining 3.47 s)
......
5000000 of 5000000 tuples (100%) done (elapsed 37.26 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done.
查看压测数据库大小:
pgbench=> select pg_database_size('pgbench')/1024/1024||'M'
;
  column  
----------
 6627M
(1 row)

--readonly测试场景
nohup pgbench -c 5 -j 2 -M prepared -n  -s 500 -S -T 120 -r -h localhost  -p 5435 -U pgbench -d pgbench > readonly.out  2>&1
......
client 2 receiving
pghost: localhost pgport: 5435 nclients: 5 duration: 120 dbName: pgbench
transaction type:
scaling factor: 50
query mode: prepared
number of clients: 5
number of threads: 2
duration: 120 s
number of transactions actually processed: 700065
latency average = 0.857 ms
tps = 5833.808371 (including connections establishing)
tps = 5834.011213 (excluding connections establishing)
statement latencies in milliseconds:
         0.009  \set aid random(1, 100000 * :scale)
         0.848  SELECT abalance FROM pgbench_accounts WHERE aid = :aid;

--update\select\insert测试场景
nohup pgbench -c 5 -j 2 -M prepared -n -s 500 -T 120 -r -h localhost -p 5435 -U pgbench -d pgbench> all.out 2>&1
......
pghost: localhost pgport: 5435 nclients: 5 duration: 120 dbName: pgbench
transaction type:
scaling factor: 50
query mode: prepared
number of clients: 5
number of threads: 2
duration: 120 s
number of transactions actually processed: 160509
latency average = 3.738 ms
tps = 1337.438196 (including connections establishing)
tps = 1337.477417 (excluding connections establishing)
statement latencies in milliseconds:
         0.008  \set aid random(1, 100000 * :scale)
         0.004  \set bid random(1, 1 * :scale)
         0.004  \set tid random(1, 10 * :scale)
         0.004  \set delta random(-5000, 5000)
         0.359  BEGIN;
         0.731  UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
         0.517  SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
         0.414  UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
         0.476  UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
         0.440  INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
         0.780  END;
--减少更新比例
nohup pgbench -c 5 -j 2 -M prepared -n -N -s 500 -T 120 -r -h localhost -p 5435 -U pgbench -d pgbench> noupdate.out 2>&1
pghost: localhost pgport: 5435 nclients: 5 duration: 120 dbName: pgbench
transaction type:
scaling factor: 50
query mode: prepared
number of clients: 5
number of threads: 2
duration: 120 s
number of transactions actually processed: 189086
latency average = 3.174 ms
tps = 1575.493301 (including connections establishing)
tps = 1575.549160 (excluding connections establishing)
statement latencies in milliseconds:
         0.008  \set aid random(1, 100000 * :scale)
         0.005  \set bid random(1, 1 * :scale)
         0.004  \set tid random(1, 10 * :scale)
         0.004  \set delta random(-5000, 5000)
         0.394  BEGIN;
         0.926  UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
         0.550  SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
         0.439  INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
         0.843  END;

--可以将默认压测结果后面的sql语句写入到一个sql文件中,进行相关调整及测试,例如自定义只读脚本
[postgres@rhel75 ~]$cat read.sql 
\set aid random(1, 100000 * :scale)
SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
nohup pgbench -c 5 -j 2 -M prepared -n  -s 500 -S -T 120 -r  -f /home/postgres/read.sql -h localhost  -p 5435 -U pgbench -d pgbench > self_readonly.out  2>&1
......
pghost: localhost pgport: 5435 nclients: 5 duration: 120 dbName: pgbench
transaction type: multiple scripts
scaling factor: 50
query mode: prepared
number of clients: 5
number of threads: 2
duration: 120 s
number of transactions actually processed: 386732
latency average = 1.552 ms
tps = 3222.238267 (including connections establishing)
tps = 3222.372968 (excluding connections establishing)
SQL script 1:
 - weight: 1 (targets 50.0% of total)
 - 193222 transactions (50.0% of total, tps = 1609.919330)
 - latency average = 1.544 ms
 - latency stddev = 4.794 ms
 - statement latencies in milliseconds:
         0.009  \set aid random(1, 100000 * :scale)
         1.535  SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
SQL script 2: /home/postgres/read.sql
 - weight: 1 (targets 50.0% of total)
 - 193510 transactions (50.0% of total, tps = 1612.318937)
 - latency average = 1.559 ms
 - latency stddev = 5.488 ms
 - statement latencies in milliseconds:
         0.009  \set aid random(1, 100000 * :scale)
         1.550  SELECT abalance FROM pgbench_accounts WHERE aid = :aid;


--测试读写函数性能
create or replace function pgbench(i_aid int,i_bid int,i_tid int,i_delta int) returns setof int as $$
declare
begin
UPDATE pgbench_accounts SET abalance = abalance + i_delta WHERE aid = i_aid;
UPDATE pgbench_tellers SET tbalance = tbalance + i_delta WHERE tid = i_tid;
UPDATE pgbench_branches SET bbalance = bbalance + i_delta WHERE bid = i_bid;
INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (i_tid, i_bid, i_aid, i_delta, CURRENT_TIMESTAMP);
return query SELECT abalance FROM pgbench_accounts WHERE aid = i_aid;
end;
$$ language plpgsql;

[postgres@rhel75 ~]$cat readwritef.sql 
\set aid random(1, 100000 * :scale)
\set bid random(1, 1 * :scale)
\set tid random(1, 10 * :scale)
\set delta random(-5000, 5000)
select pgbench(:aid,:bid,:tid,:delta);

[postgres@rhel75 ~]$nohup pgbench -c 5 -j 2 -M prepared -n  -s 500 -S -T 120 -r  -f /home/postgres/readwritef.sql -h localhost  -p 5435 -U pgbench -d pgbench > self_readw.out 2>&1
......
pghost: localhost pgport: 5435 nclients: 5 duration: 120 dbName: pgbench
transaction type: multiple scripts
scaling factor: 50
query mode: prepared
number of clients: 5
number of threads: 2
duration: 120 s
number of transactions actually processed: 309075
latency average = 1.942 ms
tps = 2575.112761 (including connections establishing)
tps = 2575.187960 (excluding connections establishing)
SQL script 1:
 - weight: 1 (targets 50.0% of total)
 - 154687 transactions (50.0% of total, tps = 1288.801966)
 - latency average = 1.245 ms
 - latency stddev = 2.064 ms
 - statement latencies in milliseconds:
         0.009  \set aid random(1, 100000 * :scale)
         1.236  SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
SQL script 2: /home/postgres/readwritef.sql
 - weight: 1 (targets 50.0% of total)
 - 154388 transactions (50.0% of total, tps = 1286.310795)
 - latency average = 2.639 ms
 - latency stddev = 2.867 ms
 - statement latencies in milliseconds:
         0.009  \set aid random(1, 100000 * :scale)
         0.005  \set bid random(1, 1 * :scale)
         0.005  \set tid random(1, 10 * :scale)
         0.005  \set delta random(-5000, 5000)
         2.615  select pgbench(:aid,:bid,:tid,:delta);


参考文档:
https://www.postgresql.org/docs/11/pgbench.html
https://blog.csdn.net/arcticJian/article/details/83272068

你可能感兴趣的:(PostgreSQL,DB)