PostgreSQL每日一贴-测试工具之pgbench
yuyutoo 2024-10-24 17:52 2 浏览 0 评论
名称
pgbench -- 在PostgreSQL中执行基准线测试
大纲
pgbench -i [option...] [dbname]
pgbench [option...] [dbname]
描述
pgbench是一个用于在PostgreSQL数据库中运行基准测试的简单程序。pgbench在多个并发的数据库会话中反复运行一系列相同的SQL命令,并计算事务执行的平均速率(每秒执行的事务个数)。 pgbench默认测试的是一种基于TPC-B的松散的测试,即一个事务中包括5个SELECT,UPDATE和INSERT语句。同时允许基于开发者自己书写的事务脚本文件进行其他场景的测试。
典型的pgbench输出如下:
transactiontype: TPC-B (sort of)
scaling factor: 10
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 1000
number of transactions actually processed: 10000/10000
tps = 85.184871 (including connections establishing)
tps = 85.296346 (excluding connections establishing)
前六行显示了一些非常重要的参数。接下来显示的是已经完成的事务和预计应该执行的事务个数。这两个数值应该是相等的,如果不相等说明存在执行失败的情况(如果指定为-T模式,则只打印实际完成的事务数量)。最后两行显示的是每秒完成的事务数量(包含连接建立时间和不包含连接建立时间分别计算出的平均值)。
默认的TPC-B-like事务测试需要预先设置特定的表。pgbench调用-i(初始化)选项来创建和填充这些表。在使用一个定制化脚本测试时,不需要调用-i选项初始化,但是需要对这个定制化脚本需要的表进行初始化。初始化过程类似如下:
pgbench -i [ other-options ] dbname
dbname用于指定一个可以用来测试的数据库的数据库名称。你可能需要指定-h,-p,-U等参数来连接数据库服务器。
注意
pgbench -i命令会创建四个表(pgbench_accounts, pgbench_branches, pgbench_history, 和pgbench_tellers),创建这几个表会执行对应表的删除动作。执行前应确认对应数据库中是否已经有这些表,是否会误删除。
按照默认的比例因子1,这些表按如下行数初始化:
表名 行数
---------------------------------
pgbench_branches 1
pgbench_tellers 10
pgbench_accounts 100000
pgbench_history 0
可以通过指定-s(比例因子)参数来增加初始化时各表的行数。-F(填充因子)参数此时也可以同时使用。
做了必要的设置后,就可以使用如下命令进行基准测试(不需要再使用-i参数)
pgbench [ options ] dbname
在几乎所有情况下,您将需要一些选项做出有用的测试。最重要的选项是-c(客户端数量),-t(事务数量),-T(时间限制)和-f(定制脚本)
具体参数见下文的完整列表。
选项
下面的选项分成三个不同类别,分别是使用在数据库初始化阶段,基准测试运行阶段或两个阶段都可以使用。
初始化选项
pgbench接受以下命令行参数:
-i
--initialize
调用初始化模式.
-F fillfactor
--fillfactor=fillfactor
使用给出的填充因子创建pgbench_accounts,pgbench_tellers,pgbench_branches等表.默认值是100.
-n
--no-vacuum
初始化后不执行vacuum。
-q
--quiet
日志模式切换为静默方式。即每五秒只打印一条进度信息,默认是每10万条记录打印一条日志,这样通常会有很多日志产生。
-s scale_factor
--scale=scale_factor
生成的行数乘以比例因子。比如,-s 100会在pgbench_accounts表中将会生成1000万条记录。默认值是1。当指定的参数超过20000时,为了能够容纳账户标识符的范围,保存这些信息的列字段类型会调整为大整形。
--foreign-keys
在默认创建的表上创建外键。
--index-tablespace=index_tablespace
在指定的表空间上创建索引。
--tablespace=tablespace
在指定的表空间上创建默认表。
--unlogged-tables
Create all tables as unlogged tables, rather thanpermanent tables.(创建临时表?)
基准测试选项
pgbench接受以下命令行基准测试参数参数:
-c clients
--client=clients
模拟的客户数量,具体指并发运行的数据库会话数。默认值为1。
-C
--connect
每个事务都新创建一个连接来执行,而不是仅使用一个客户端连接。这个对于测试连接过载是有意义的。
-d
--debug
打印调试信息
-D varname=value
--define=varname=value
定义一个客户定制脚本适用的变量。允许多个-D选项。
-f filename
--file=filename
从指定文件中读取事务脚本。具体参见下面的详细介绍。-N, -S和-f是互斥的。
-j threads
--jobs=threads
指定工作线程数量。在多核场景下使用多于一个线程是有意义的。由于每个线程会被分配相同数量的客户端数目,所以客户端数量必须设置为线程数目的整数倍。该参数默认值为1。
-l
--log
记录每个线程的耗时到日志文件中。详细内容见下文。
-M querymode
--protocol=querymode
用于向服务器提交查询的协议:
默认值为简单协议. (详细说明参考Chapter 49 。)
-n
--no-vacuum
测试运行前不执行vacuum。如果运行的是一个不包含默认表( pgbench_accounts, pgbench_branches, pgbench_history和pgbench_tellers.
)的定制测试时,这个选项是必要的。
-N
--skip-some-updates
不更新表pgbench_tellers和pgbench_branches.设置后会避免更新这两个表。但是这样返会使该测试与TPC-B测试产生差异。
-P sec
--progress=sec
每秒显示一次进度报告。报告包括已运行时间,上次报告到当前的tps、事务延迟时间、标准误差。节流(-R)模式下,误差是从事务计划开始时间计算,而不是实际的事务开始时间,因此,这个时间还包含了平均执行计划延迟时间。
-r
--report-latencies
基准测试运行完成后报告每个命令的平均延迟时间(从客户角度看到的执行时间)。详细内容见下文。
-R rate
--rate=rate
按执行速率执行事务,而不是尽可能快地运行(默认方式)。这个速率指定的是每秒的事务数。如果指定的速率比最大可能速率还大,则这个速率参数不会对结果产生影响。
速率以沿着Poisson-distributed计划时间线开始的事务为目标。期待的开始时间基于客户第一次启动时间向前,而不是最后一个事务的完成时间。这种方法意味着当事务经过了原先的计划结束时间,后续的事务仍然有可能赶上
The rate is targeted by starting transactions along aPoisson-distributed schedule time line. The expected start time schedule movesforward based on when the client first started, not when the previoustransaction ended. That approach means that when transactions go past theiroriginal scheduled end time, it is possible for later ones to catch up again.
当节流开关是有效的,则运行结束时报告的事务时延是从计划开始时间计算的,因此这个时间是包含了每个事务等待前一个事务完成的这段时间的。等待时间又称为计划延迟时间,并且它的平均时间和最大时间也会被分别输出。因此基于实际事务开始时间的事务时延,也就是,在数据库中执行事务实际花费的时间,可以用减去时延报告中的计划延迟时间来计算。
一个高的计划延迟时间表明系统无法以指定的速率、客户端数量和线程数来处理事务。当平均事务执行时间比事务执行间隔时间要长时,每个连续的事务将会下跌,测试的时间越长,计划延迟时间将会持续越长。当这些事情发生时,你需要降低定制的事务速率。
-s scale_factor
--scale=scale_factor
在pgbench报告中输出定制的比例因子。内置测试不需要设置这个参数。通过计算在pgbench_branches表中的行数,正确的比例因子将会被检测到。但是,如果通过-f运行客户定制的基准测试,比例因子会被报告为1,除非使用了这个参数。
-S
--select-only
运行select-only事务测试而不是TPC-B-like测试。
-t transactions
--transactions=transactions
每个客户端运行的事务数量,默认值为10.
-T seconds
--time=seconds
运行测试这么多秒,而不是每个客户端运行固定数量的事务。-t - t是互相排斥的。
-v
--vacuum-all
运行测试前先对四张基准表做vacuum。如果不指定-n也不执行-v,默认对表pgbench_tellers和pgbench_branches做vacuum并将pgbench_history表truncate掉。
--aggregate-interval=seconds
汇总时间间隔长度。只有-l和这个参数同时使用才有效。日志包含每个间隔的概要(事务数量,最大最小时延和两个额外的用于方差估计的字段)
--sampling-rate=rate
抽样速率,将数据写入日志时使用,用于降低生产的日志数量。如果设置了这个参数,只有指定的事务部分才会被记录。1.0表示所有事务都被记录。0.05表示只有5%的事务会被记录。当处理日志文件时记得考虑采样率。例如,当计算tps值,你需要乘上对应的数量(比如0.01采样率,你实际只是获得了1/100的实际tps)。
通用参数
pgbench接受以下命令行常见参数:
-h hostname
--host=hostname
数据库服务器主机名称
-p port
--port=port
数据库服务器端口号
-U login
--username=login
用来登陆的数据库用户名称
-V
--version
打印pgbench版本
-?
--help
显示pgbench命令帮助信息
说明
在pgbench中运行的所谓的“事务”是什么?
默认的事务脚本在每个事务中执行如下七条语句:
- BEGIN;
- UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
- SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
- UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
- UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
- INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
- END;
如果你指定了-N,第4步和第5步不会执行。如果指定了-S,则只有select语句会执行。
客户化定制脚本
通过使用-f参数读取文件替换掉默认的事务脚本,pgbench可以实现客户化基准测试场景。在这种情况下,一个“事务”指的是一个SQL脚本文件。你甚至可以指定多个SQL脚本(多个-f参数),在这种情况下,每次客户端会话会随机选择一个脚本开始一个新事务。
脚本文件格式是每一条SQL命令独占一行。一行多个SQL命令是不支持的。空行和以--开头的行会被忽略。脚本中还可以录入由pgbench解释的"元命令",具体描述见下文:
pgbench有一个简单的脚本文件的变量替换功能。变量可以使用上面提到的-D参数设置,也可以使用pgbench元命令设置(下面会详细介绍)。除了通过-D参数设置的变量,还有一些变量是默认设置的,列举在了表G-1中。-D设置的变量优先于预设变量。一旦设置后,一个变量的值就可以通过:变量名称的方式插入到一个SQL命令中。当超过一个会话运行时,每个会话都可以有自己的一组变量。
表G-1.自动变量
变量名称
描述
scale
当前的比例因子
client_id
客户端会话唯一的数字识别(从0开始)
脚本文件元命令以(\)开始。元命令参数由空格分隔。支持如下元命令:
\set varname operand1 [ operator operand2 ]
设置变量varname整数值计算公式。每个操作数可以是一个整数常量或是用:variablename引用的一个是整数类型的变量。操作符可以是+、-、*、/。
例:
\set ntellers 10 * :scale
\setrandom varname min max
设置变量varname为一个在min和max之间的随机整数。min和max可以是一个整数常量或是用:variablename引用的一个是整数类型的变量。
例:
\setrandom aid 1 :naccounts
\sleep number [ us | ms | s ]
指定脚本休眠时间,单位可以是微妙(us),毫秒(ms)或秒(s)。时间单位默认是秒。number可以是一个整数常量或用:variablename引用的一个是整数类型的变量。
例:
\sleep 10 ms
\setshell varname command [ argument ... ]
设置变量varname为shell命令command的返回值,这个命令的标准输出必须是一个整数。argument可以是一个文本常量或者是用 :variablename表示的一个任意类型的变量。如果想要使用以:开头的argument,需要在argument 的开头增加一个额外的:。
例e:
\setshell variable_to_be_assigned command literal_argument:variable ::literal_starting_with_colon
\shell command [ argument ... ]
和 \setshell相同,但是结果会被忽略。
例:
\shell command literal_argument :variable::literal_starting_with_colon
作为一个例子,内置的TPC-B-like事务的完整定义如下:
\setnbranches :scale
\set ntellers 10 * :scale
\set naccounts 100000 * :scale
\setrandom aid 1 :naccounts
\setrandom bid 1 :nbranches
\setrandom tid 1 :ntellers
\setrandom delta -5000 5000
BEGIN;
UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid =:aid;
SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid =:tid;
UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid =:bid;
INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid,:aid, :delta, CURRENT_TIMESTAMP);
END;
这个脚本允许事务的每次迭代引用不同的、随机选择的行。(这个例子也说明了为什么为每个客户端会话拥有自己的独立变量是重要的,因为如果不这样设置他们可能不会使用不同的行,进而造成锁等待)。
事务处理日志
使用-l参数但没有使用--aggregate-interval,pgbench会将每个事务消耗的时间写入到一个日志文件中。这个日志文件会被命名为pgbench.nnn,nnn是pgbench进程的PID,如果通过-j指定的参数大于等于2,每个pgbench进程会有多个工作线程。每个工作线程都会有单独的日志文件。第一个工作线程的日志文件名称与进程的日志文件名称相同,其他的日志文件会被命名为pgbench_log.nnn.mmm,mmm是一个从1开始的序号。
log的格式如下:
client_id transaction_notime file_notime_epoch time_us[schedule_lag]
time 是事务消耗的全部时间,单位是ms。
file_no用于说明使用的是哪个脚本文件(在使用-f指定了多个脚本文件时是有用的)。
time_epoch/time_us是用于展示事务完成的UNIX时间戳和一个毫秒偏移量(适用于创建一个ISO 8601与分数秒时间戳)。
schedule_lag是事务计划开始时间和事务实际开始时间的时间差。这个值只有在使用--rate参数时才会有。
样例输出:
0 199 2241 0 1175850568 995598
0 200 2465 0 1175850568998079
0 201 2513 0 1175850569 608
0 202 2038 0 1175850569 2663
当长时间运行测试时,会执行大量的事务,此时日志文件会变得很大。--sampling-rate参数可以被用来指定只记录一定比例的随机事务样本执行情况。
聚合的日志
指定--aggregate-interval参数,日志使用稍微不同的格式:
interval_start num_of_transactionslatency_sum latency_2_sum min_latencymax_latency [lag_sum lag_2_sum min_lag max_lag]
interval_start 是间隔开始时间(UNIX时间戳)
num_of_transactions 是这段时间间隔中执行的事务个数。
latency_sum 是时延总和(可以通过这个值计算平均时延)
接下来的两个字段用于方差估计。latency_sum是时延总和,latency_2_sum是 a sum of 2nd powers of latencies。
最后两个字段是min_latency (这段时间中的最小时延值)、max_latency(这段时间中的最大时延值)。
在时间间隔中提交的事务才会被统计。最后四个字段lag_sum,lag_2_sum, min_lag, and max_lag只有在使用了--rate时才会显示。这几个时间值是从每个事务等待前一个完成时开始计算,也就是每个事务计划开始时间和实际开始时间之间的差异。
样例输出:
13458285015601 1542744 483552416 61 2573
1345828503 7884 1979812 565806736 60 1479
1345828505 7208 1979422 567277552 59 1391
1345828507 7685 1980268 569784714 60 1398
1345828509 7073 1979779 573489941 236 1411
注意:非聚合日志包含了每个客户化定制脚本文件的统计,但是聚合日志不包含。对于聚合日志,如果需要每个脚本数据,要自己聚合整理。
每个语句延迟
使用-r参数,pgbench会收集每个客户端的每条sql语句的执行时间。基准测试完成后,依赖于每个语句的时延,会输出这些统计项的平均值。
对于默认的事务脚本,输出类似如下:
startingvacuum...end.
transaction type: TPC-B (sort of)
scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 1000
number of transactions actually processed: 10000/10000
tps = 618.764555 (including connections establishing)
tps = 622.977698 (excluding connections establishing)
statement latencies in milliseconds:
0.004386 \set nbranches 1 * :scale
0.001343 \set ntellers 10 * :scale
0.001212 \set naccounts 100000 *:scale
0.001310 \setrandom aid 1 :naccounts
0.001073 \setrandom bid 1 :nbranches
0.001005 \setrandom tid 1 :ntellers
0.001078 \setrandom delta -5000 5000
0.326152 BEGIN;
0.603376 UPDATE pgbench_accounts SET abalance =abalance + :delta WHERE aid = :aid;
0.454643 SELECT abalance FROM pgbench_accountsWHERE aid = :aid;
5.528491 UPDATE pgbench_tellers SET tbalance =tbalance + :delta WHERE tid = :tid;
7.335435 UPDATE pgbench_branches SET bbalance =bbalance + :delta WHERE bid = :bid;
0.371851 INSERT INTO pgbench_history (tid, bid,aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta,CURRENT_TIMESTAMP);
1.212976 END;
如果指定了多个事务脚本文件,会安装事务脚本分别输出上述统计项的平均值。
注意收集这些额外的时间信息,每个语句都会增加一些额外开销。这些会降低平均执行速率和命令的TPS。对速率和TPS的影响随平台和硬件的不同而不同。分别统计包含和不包含时延的报告是用来评估这些额外开销影响是否严重的好方法。
最佳实践
很容易使用pgbench生成完全无意义的数字。下面是一些指导方针来帮助你得到有用的结果。
首先,不要相信任何只运行几秒钟的测试得出的数字。使用-t和-T选项,使运行至少持续几分钟已用于屏蔽掉一些波动。在某些情况下,你可能需要运行几个小时测试,用于确认测试数字是可再生的(即准确的)。多尝试几次测试是个好主意,用于保证测试数据是可再生的。
对于默认的TPC-B-like测试场景,初始化的比例因子(-s)大小至少要和你设置的客户端数量(-c)相等,否则会有大量时间消耗在更新争用上。pgbench_branches表中只有-s行,并且每个事务都会尝试更新这样行中一行,因此-c值超过-s值将导致大量事务等待其他事务完成。
默认的测试场景也很敏感,这是由于从表初始化开始表中累积的dead记录和dead空间导致的。要理解对应的结果你必须跟踪更新总数和什么时候会启动vacuum。如果启用了autovacuum就会导致不可预知的测量性能变化。
pgbench的一个限制是当试图测试大量的客户端会话时,pgbench本身会成为瓶颈。这可以通过在非数据库服务器的机器上运行pgbench来保证,同时要保证pgbench运行的机器和数据库服务器之间是低网络延迟的。同样,同时在不同机器上(非数据库服务器)运行多个pgbench实例也是有效的。
相关推荐
- jQuery VS AngularJS 你更钟爱哪个?
-
在这一次的Web开发教程中,我会尽力解答有关于jQuery和AngularJS的两个非常常见的问题,即jQuery和AngularJS之间的区别是什么?也就是说jQueryVSAngularJS?...
- Jquery实时校验,指定长度的「负小数」,小数位未满末尾补0
-
在可以输入【负小数】的输入框获取到焦点时,移除千位分隔符,在输入数据时,实时校验输入内容是否正确,失去焦点后,添加千位分隔符格式化数字。同时小数位未满时末尾补0。HTML代码...
- 如何在pbootCMS前台调用自定义表单?pbootCMS自定义调用代码示例
-
要在pbootCMS前台调用自定义表单,您需要在后台创建表单并为其添加字段,然后在前台模板文件中添加相关代码,如提交按钮和表单验证代码。您还可以自定义表单数据的存储位置、添加文件上传字段、日期选择器、...
- 编程技巧:Jquery实时验证,指定长度的「负小数」
-
为了保障【负小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【负小数】的方法。HTML代码<inputtype="text"class="forc...
- 一篇文章带你用jquery mobile设计颜色拾取器
-
【一、项目背景】现实生活中,我们经常会遇到配色的问题,这个时候去百度一下RGB表。而RGB表只提供相对于的颜色的RGB值而没有可以验证的模块。我们可以通过jquerymobile去设计颜色的拾取器...
- 编程技巧:Jquery实时验证,指定长度的「正小数」
-
为了保障【正小数】的正确性,做成了通过Jquery,在用户端,实时验证指定长度的【正小数】的方法。HTML做成方法<inputtype="text"class="fo...
- jquery.validate检查数组全部验证
-
问题:html中有多个name[],每个参数都要进行验证是否为空,这个时候直接用required:true话,不能全部验证,只要这个数组中有一个有值就可以通过的。解决方法使用addmethod...
- Vue进阶(幺叁肆):npm查看包版本信息
-
第一种方式npmviewjqueryversions这种方式可以查看npm服务器上所有的...
- layui中使用lay-verify进行条件校验
-
一、layui的校验很简单,主要有以下步骤:1.在form表单内加上class="layui-form"2.在提交按钮上加上lay-submit3.在想要校验的标签,加上lay-...
- jQuery是什么?如何使用? jquery是什么功能组件
-
jQuery于2006年1月由JohnResig在BarCampNYC首次发布。它目前由TimmyWilson领导,并由一组开发人员维护。jQuery是一个JavaScript库,它简化了客户...
- django框架的表单form的理解和用法-9
-
表单呈现...
- jquery对上传文件的检测判断 jquery实现文件上传
-
总体思路:在前端使用jquery对上传文件做部分初步的判断,验证通过的文件利用ajaxFileUpload上传到服务器端,并将文件的存储路径保存到数据库。<asp:FileUploadI...
- Nodejs之MEAN栈开发(四)-- form验证及图片上传
-
这一节增加推荐图书的提交和删除功能,来学习node的form提交以及node的图片上传功能。开始之前需要源码同学可以先在git上fork:https://github.com/stoneniqiu/R...
- 大数据开发基础之JAVA jquery 大数据java实战
-
上一篇我们讲解了JAVAscript的基础知识、特点及基本语法以及组成及基本用途,本期就给大家带来了JAVAweb的第二个知识点jquery,大数据开发基础之JAVAjquery,这是本篇文章的主要...
- 推荐四个开源的jQuery可视化表单设计器
-
jquery开源在线表单拖拉设计器formBuilder(推荐)jQueryformBuilder是一个开源的WEB在线html表单设计器,开发人员可以通过拖拉实现一个可视化的表单。支持表单常用控件...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- mybatis plus (70)
- scheduledtask (71)
- css滚动条 (60)
- java学生成绩管理系统 (59)
- 结构体数组 (69)
- databasemetadata (64)
- javastatic (68)
- jsp实用教程 (53)
- fontawesome (57)
- widget开发 (57)
- vb net教程 (62)
- hibernate 教程 (63)
- case语句 (57)
- svn连接 (74)
- directoryindex (69)
- session timeout (58)
- textbox换行 (67)
- extension_dir (64)
- linearlayout (58)
- vba高级教程 (75)
- iframe用法 (58)
- sqlparameter (59)
- trim函数 (59)
- flex布局 (63)
- contextloaderlistener (56)