PostgreSQL 主机性能测试方法 - 单机单实例

简介:

背景

业界有一些通用的数据库性能测试模型,可以用来测试硬件在不同测试模型下的性能表现。
参考
http://www.tpc.org/
https://github.com/oltpbenchmark/oltpbench
http://oltpbenchmark.com/

本文主要以PostgreSQL为例,向大家介绍一下,如何使用PostgreSQL来测试硬件的性能。

PostgreSQL 的功能非常的强大,所以可以适用于几乎所有的测试模型,同时用户还可以根据自己的应用场景设计测试模型。

前面已经介绍了单机多实例的测试方法。

本文介绍的是单机单实例的测试方法。

一、单机io测试

使用fio测试磁盘或块设备的IO能力。

1. 安装libaio库

# yum install -y libaio libaio-devel
# mkdir -p /data01/digoal
# chown dege.zz /data01/digoal

2. 安装fio

$ git clone https://github.com/axboe/fio
$ cd fio
$ ./configure --prefix=/home/digoal/fiohome
$ make -j 32
$ make install

$ export PATH=/home/digoal/fiohome/bin:$PATH

3. 测试顺序读写,随机读写8K数据块。

fio -filename=/data01/digoal/testdir -direct=1 -thread -rw=write -ioengine=libaio -bs=8K -size=16G -numjobs=128 -runtime=60 -group_reporting -name=mytest >/tmp/fio_write.log 2>&1
fio -filename=/data01/digoal/testdir -direct=1 -thread -rw=read -ioengine=libaio -bs=8K -size=16G -numjobs=128 -runtime=60 -group_reporting -name=mytest >/tmp/fio_read.log 2>&1
fio -filename=/data01/digoal/testdir -direct=1 -thread -rw=randwrite -ioengine=libaio -bs=8K -size=16G -numjobs=128 -runtime=60 -group_reporting -name=mytest >/tmp/fio_randwrite.log 2>&1
fio -filename=/data01/digoal/testdir -direct=1 -thread -rw=randread -ioengine=libaio -bs=8K -size=16G -numjobs=128 -runtime=60 -group_reporting -name=mytest >/tmp/fio_randread.log 2>&1

测试数据关注

bps(MB/S)
lat(min,us)
lat(max,us)
lat(avg,us)
lat(stddev,us)

二、单机数据库准备

测试单实例,所以不使用cgroup

1. 配置环境变量

$ vi ~/envpg.sh

export PS1="$USER@`/bin/hostname -s`-> "
export PGPORT=1921
export PGDATA=/data02/digoal/pg_root_single
export LANG=en_US.utf8
export PGHOME=/home/digoal/pgsql9.6rc1
export LD_LIBRARY_PATH=$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH
export DATE=`date +"%Y%m%d%H%M"`
export PATH=/home/fiohome/bin:$PGHOME/bin:$PATH:.
export MANPATH=/home/fiohome/man:$PGHOME/share/man:$MANPATH
export PGHOST=$PGDATA
export PGUSER=postgres
export PGDATABASE=postgres
alias rm='rm -i'
alias ll='ls -lh'
unalias vi

. ~/envpg.sh

2. 初始化数据库集群

$ initdb -D $PGDATA -U postgres -E UTF8 --locale=C -X /data01/digoal/pg_xlog_single

3. 配置数据库

$ cd $PGDATA


$ vi postgresql.conf
listen_addresses = '0.0.0.0'            # what IP address(es) to listen on;
port = 1921                             # (change requires restart)
max_connections = 300                   # (change requires restart)
unix_socket_directories = '.'   # comma-separated list of directories
shared_buffers = 96GB                   # min 128kB
maintenance_work_mem = 2GB              # min 1MB
autovacuum_work_mem = 2GB               # min 1MB, or -1 to use maintenance_work_mem
dynamic_shared_memory_type = posix      # the default is the first option
bgwriter_delay = 10ms                   # 10-10000ms between rounds
bgwriter_lru_maxpages = 1000            # 0-1000 max buffers written/round
bgwriter_lru_multiplier = 10.0          # 0-10.0 multiplier on buffers scanned/round
wal_buffers = 128MB                    # min 32kB, -1 sets based on shared_buffers
wal_writer_flush_after = 0              # 0 disables
checkpoint_timeout = 55min              # range 30s-1h
max_wal_size = 192GB 
checkpoint_completion_target = 0.0      # checkpoint target duration, 0.0 - 1.0
random_page_cost = 1.0                  # same scale as above
effective_cache_size = 480GB
constraint_exclusion = on  # on, off, or partition
log_destination = 'csvlog'              # Valid values are combinations of
logging_collector = on          # Enable capturing of stderr and csvlog
log_truncate_on_rotation = on           # If on, an existing log file with the
log_checkpoints = on
log_connections = on
log_disconnections = on
log_error_verbosity = verbose           # terse, default, or verbose messages
log_timezone = 'PRC'
autovacuum_vacuum_scale_factor = 0.002  # fraction of table size before vacuum
datestyle = 'iso, mdy'
timezone = 'PRC'
lc_messages = 'C'                       # locale for system error message
lc_monetary = 'C'                       # locale for monetary formatting
lc_numeric = 'C'                        # locale for number formatting
lc_time = 'C'                           # locale for time formatting
default_text_search_config = 'pg_catalog.english'
synchronous_commit=on
full_page_writes=on
autovacuum_naptime=10s
autovacuum_max_workers=16


$ vi pg_hba.conf
host all all 0.0.0.0/0 trust

4. 启动数据库

$ pg_ctl start

三、单机数据库测试 - TPC-B

1. 初始化TPC-B数据

tpc-b (40亿记录)

准备数据

$ pgbench -i -s 40000

2. 持续测试15天(在客户端机器启动测试,假设客户端POSTGRESQL已部署)

$ vi test.sh

date +%F%T >/tmp/single.log
pgbench -M prepared -n -r -P 1 -c 128 -j 128 -T 1296000 -h 目标机器IP -p 数据库端口 -U postgres postgres >>/tmp/single.log 2>&1
date +%F%T >>/tmp/single.log

$ chmod 700 test.sh

$ nohup ./test.sh >/dev/null 2>&1 &

3. 测试结果

$ cat /tmp/single.log

$ head -n 30000 /tmp/single.log |tail -n 7200 > /tmp/1
$ cat /tmp/1|awk '{print $4 "," $7 "," $10}' >/tmp/2

输出TPS,RT,标准差。

TPS表示数据库视角的事务处理能力(也就是单个测试脚本的每秒调用次数)。

RT表示响应时间。

标准差可以用来表示抖动,通常应该在1以内(越大,说明抖动越厉害)。

4. 主机性能结果

$ sar -f ....

四、单机数据库测试 - 定制测试1

测试分区表upsert 即 insert on conflict

安装分区表插件

$ git clone https://github.com/postgrespro/pg_pathman
$ cd pg_pathman
$ export PATH=/home/digoal/pgsql9.6rc1/bin:$PATH
$ make USE_PGXS=1
$ make install USE_PGXS=1

$ vi $PGDATA/postgresql.conf
shared_preload_libraries='pg_pathman'

$ pg_ctl restart -m fast

$ psql
postgres=# create extension pg_pathman;
CREATE EXTENSION

1. 定制测试脚本
例如测试insert on conflict, 20亿分区表,单表2000万。

$ psql
postgres=# drop table test;
postgres=# create table test(id int primary key, info text, crt_time timestamptz);
CREATE TABLE
postgres=# 
postgres=# select create_range_partitions('test'::regclass, 'id', 1, 20000000, 100, false);
 create_range_partitions 
-------------------------
                     100
(1 row)
postgres=# select disable_parent('test'::regclass);
 disable_parent 
----------------

(1 row)

reconnect  
postgres=# explain select * from test where id=1;
                                   QUERY PLAN                                    
---------------------------------------------------------------------------------
 Append  (cost=0.15..2.17 rows=1 width=44)
   ->  Index Scan using test_1_pkey on test_1  (cost=0.15..2.17 rows=1 width=44)
         Index Cond: (id = 1)
(3 rows)

新建的表如下

postgres=# \d+ test_1
                                  Table "postgres.test_1"
  Column  |            Type             | Modifiers | Storage  | Stats target | Description 
----------+-----------------------------+-----------+----------+--------------+-------------
 id       | integer                     | not null  | plain    |              | 
 info     | text                        |           | extended |              | 
 crt_time | timestamp without time zone |           | plain    |              | 
Indexes:
    "test_1_pkey" PRIMARY KEY, btree (id)
Check constraints:
    "pathman_test_1_1_check" CHECK (id >= 1 AND id < 20000001)
Inherits: test

postgres=# \d+ test_100
                                 Table "postgres.test_100"
  Column  |            Type             | Modifiers | Storage  | Stats target | Description 
----------+-----------------------------+-----------+----------+--------------+-------------
 id       | integer                     | not null  | plain    |              | 
 info     | text                        |           | extended |              | 
 crt_time | timestamp without time zone |           | plain    |              | 
Indexes:
    "test_100_pkey" PRIMARY KEY, btree (id)
Check constraints:
    "pathman_test_100_1_check" CHECK (id >= 1980000001 AND id < 2000000001)
Inherits: test

目前9.6在分区表执行on conflict有个BUG,已提交给社区。

insert into test(id,info,crt_time) values(:id, md5(random()::text), now()) on conflict (id) do update set info=excluded.info,crt_time=excluded.crt_time;

先使用function代替

create or replace function upsert_test(int,text,timestamptz) returns void as $$ 
declare
begin
  update test set info=$2,crt_time=$3 where id=$1;
  if not found then
    insert into test(id,info,crt_time) values ($1,$2,$3);
  end if;
  exception when others then
  return;
end;
$$ language plpgsql strict;

pgbench脚本

\set id random(1,2000000000)
select upsert_test(:id,md5(random()::text),now());

2. 测试

$ vi test.sh

date +%F%T >/tmp/single.log
pgbench -M prepared -f test.sql -n -r -P 1 -c 128 -j 128 -T 1296000 -h 目标机器IP -p 数据库端口 -U postgres postgres >>/tmp/single.log 2>&1
date +%F%T >>/tmp/single.log

$ chmod 700 test.sh

$ nohup ./test.sh >/dev/null 2>&1 &

五、单机数据库测试 - 定制测试2

测试单表upsert 即 insert on conflict

1. 定制测试脚本
例如测试insert on conflict, 单表20亿。

$ psql
postgres=# drop table test cascade;
postgres=# create table test(id int primary key, info text, crt_time timestamptz);
CREATE TABLE

pgbench脚本

vi test.sql

\set id random(1,2000000000)
insert into test(id,info,crt_time) values(:id, md5(random()::text), now()) on conflict (id) do update set info=excluded.info,crt_time=excluded.crt_time;

2. 测试

$ vi test.sh

date +%F%T >/tmp/single.log
pgbench -M prepared -f test.sql -n -r -P 1 -c 128 -j 128 -T 1296000 -h 目标机器IP -p 数据库端口 -U postgres postgres >>/tmp/single.log 2>&1
date +%F%T >>/tmp/single.log

$ chmod 700 test.sh

$ nohup ./test.sh >/dev/null 2>&1 &

Count

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
3月前
|
测试技术 开发者 Python
Python单元测试入门:3个核心断言方法,帮你快速定位代码bug
本文介绍Python单元测试基础,详解`unittest`框架中的三大核心断言方法:`assertEqual`验证值相等,`assertTrue`和`assertFalse`判断条件真假。通过实例演示其用法,帮助开发者自动化检测代码逻辑,提升测试效率与可靠性。
375 1
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
如何让AI更“聪明”?VLM模型的优化策略与测试方法全解析​
本文系统解析视觉语言模型(VLM)的核心机制、推理优化、评测方法与挑战。涵盖多模态对齐、KV Cache优化、性能测试及主流基准,助你全面掌握VLM技术前沿。建议点赞收藏,深入学习。
886 8
|
9月前
|
关系型数据库 测试技术 Linux
PostgreSQL配置文件修改及启用方法
总的来说,修改和启用PostgreSQL的配置文件是一个直接而简单的过程。只需要找到配置文件,修改你想要改变的选项,然后重启服务器即可。但是,你需要注意的是,不正确的配置可能会导致服务器性能下降,甚至导致服务器无法启动。因此,在修改配置文件之前,你应该充分理解每个选项的含义和影响,如果可能的话,你应该在测试环境中先进行试验。
739 72
|
6月前
|
测试技术
软考软件评测师——可靠性测试测试方法
软件可靠性是指软件在规定条件和时间内完成预定功能的能力,受运行环境、软件规模、内部结构、开发方法及可靠性投入等因素影响。失效概率指软件运行中出现失效的可能性,可靠度为不发生失效的概率,平均无失效时间(MTTF)体现软件可靠程度。案例分析显示,嵌入式软件需满足高可靠性要求,如机载软件的可靠度需达99.99%以上,通过定量指标评估其是否达标。
|
6月前
|
消息中间件 缓存 监控
性能测试怎么做?方法、流程与核心要点解析
本文系统阐述了性能测试的核心方法论、实施流程、问题定位优化及报告编写规范。涵盖五大测试类型(负载验证、极限压力、基准比对、持续稳定性、弹性扩展)与七项关键指标,详解各阶段任务如需求分析、场景设计和环境搭建,并提供常见瓶颈识别与优化实战案例。最后规范测试报告内容框架与数据可视化建议,为企业级实践提出建立基线库、自动化回归和全链路压测体系等建议,助力高效开展性能测试工作。
|
10月前
|
编解码 缓存 Prometheus
「ximagine」业余爱好者的非专业显示器测试流程规范,同时也是本账号输出内容的数据来源!如何测试显示器?荒岛整理总结出多种测试方法和注意事项,以及粗浅的原理解析!
本期内容为「ximagine」频道《显示器测试流程》的规范及标准,我们主要使用Calman、DisplayCAL、i1Profiler等软件及CA410、Spyder X、i1Pro 2等设备,是我们目前制作内容数据的重要来源,我们深知所做的仍是比较表面的活儿,和工程师、科研人员相比有着不小的差距,测试并不复杂,但是相当繁琐,收集整理测试无不花费大量时间精力,内容不完善或者有错误的地方,希望大佬指出我们好改进!
707 16
「ximagine」业余爱好者的非专业显示器测试流程规范,同时也是本账号输出内容的数据来源!如何测试显示器?荒岛整理总结出多种测试方法和注意事项,以及粗浅的原理解析!
|
10月前
|
人工智能 自然语言处理 测试技术
AxBench:斯坦福大学推出评估语言模型控制方法的基准测试框架
AxBench 是由斯坦福大学推出,用于评估语言模型可解释性方法的基准测试框架,支持概念检测和模型转向任务,帮助研究者系统地比较不同控制技术的有效性。
284 5
AxBench:斯坦福大学推出评估语言模型控制方法的基准测试框架
|
4月前
|
前端开发 Java jenkins
Jmeter压力测试工具全面教程和使用技巧。
JMeter是一个能够模拟高并发请求以检查应用程序各方面性能的工具,包括但不限于前端页面、后端服务及数据库系统。熟练使用JMeter不仅能够帮助发现性能瓶颈,还能在软件开发早期就预测系统在面对真实用户压力时的表现,确保软件质量和用户体验。在上述介绍的基础上,建议读者结合官方文档和社区最佳实践,持续深入学习和应用。
981 10
|
6月前
|
Java 测试技术 容器
Jmeter工具使用:HTTP接口性能测试实战
希望这篇文章能够帮助你初步理解如何使用JMeter进行HTTP接口性能测试,有兴趣的话,你可以研究更多关于JMeter的内容。记住,只有理解并掌握了这些工具,你才能充分利用它们发挥其应有的价值。+
1059 23

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版
  • 推荐镜像

    更多