PostgreSQL pgbench SQL RT 与 事务RT 浅析

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS SQL Server,基础系列 2核4GB
简介:

背景

使用pgbench测试数据库性能时,在输出的报告中,可以输出事务的平均RT,以及单条SQL的平均RT。

那么这两个有什么分别呢?

pic1

每行代表一个线程,被填充了颜色的部分表示从客户端发起SQL到SQL返回的时间窗口,没有填充颜色的部分表示线程的空闲时间。

如何统计事务 平均RT :
执行的事务数/总的测试时长

如何统计SQL 平均RT :
每条SQL的执行时长累加/总的SQL执行次数

从计算公式以及图例来分析,显然SQL的平均RT会更低,因为没有计算线程的空闲时间。

特别是pgbench与数据库在同一主机进行测试时,全力压测(CPU吃满)的情况下,PGBENCH的线程等待(空闲)时间会更明显,SQL的RT会比事务的RT低很多。

那么哪个值更能代表数据库的处理能力呢?

SQL平均RT可以代表数据库的真实处理能力,而事务RT则是代表从客户端到数据库端作为一个整体来看待的事务处理能力(包括客户端的处理时间,数据库的处理时间,以及网络传输时间)。

pgbench 相关源码浅析

不加 -r 参数

返回样例如下

transaction type: TPC-B (sort of)
scaling factor: 100
query mode: prepared
number of clients: 10
number of threads: 10
duration: 10 s
number of transactions actually processed: 29032
latency average: 3.442 ms
latency stddev: 74.879 ms
tps = 2902.936994 (including connections establishing)
tps = 2903.710037 (excluding connections establishing)

代码如下
打印事务RT(或脚本RT)为 测试的持续时长 除以 总的事务数

                /* only an average latency computed from the duration is available */
                printf("latency average: %.3f ms\n",
                           1000.0 * duration * nclients / total->cnt);

加 -r 参数

  -r, --report-latencies   report average latency per command

返回样例如下

transaction type: TPC-B (sort of)
scaling factor: 100
query mode: prepared
number of clients: 10
number of threads: 10
duration: 10 s
number of transactions actually processed: 22000
latency average: 5.634 ms
latency stddev: 191.632 ms
tps = 1773.794731 (including connections establishing)
tps = 1774.193277 (excluding connections establishing)
statement latencies in milliseconds:
        0.003053        \set nbranches 1 * :scale
        0.000832        \set ntellers 10 * :scale
        0.000661        \set naccounts 100000 * :scale
        0.001120        \setrandom aid 1 :naccounts
        0.000909        \setrandom bid 1 :nbranches
        0.000742        \setrandom tid 1 :ntellers
        0.000773        \setrandom delta -5000 5000
        0.053747        BEGIN;
        0.183235        UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
        0.092281        SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
        0.113678        UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
        0.155755        UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
        0.088806        INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
        4.929969        END;

代码浅析
参数

-r
                        case 'r':
                                benchmarking_option_set = true;
                                per_script_stats = true;
                                is_latencies = true;
                                break;

语句开始时间

        instr_time      stmt_begin;             /* used for measuring statement latencies */
......
        /* Record statement start time if per-command latencies are requested */
        if (is_latencies)
                INSTR_TIME_SET_CURRENT(st->stmt_begin);

累加语句的执行时间

                /*
                 * command finished: accumulate per-command execution times in
                 * thread-local data structure, if per-command latencies are requested
                 */
                if (is_latencies)
                {
                        if (INSTR_TIME_IS_ZERO(now))
                                INSTR_TIME_SET_CURRENT(now);

                        /* XXX could use a mutex here, but we choose not to */
                        addToSimpleStats(&commands[st->state]->stats,
                                                         INSTR_TIME_GET_DOUBLE(now) -
                                                         INSTR_TIME_GET_DOUBLE(st->stmt_begin));
                }
......
/*
 * Accumulate one value into a SimpleStats struct.
 */
static void
addToSimpleStats(SimpleStats *ss, double val)
{
        if (ss->count == 0 || val < ss->min)
                ss->min = val;
        if (ss->count == 0 || val > ss->max)
                ss->max = val;
        ss->count++;
        ss->sum += val;
        ss->sum2 += val * val;
}

数据结构

/*
 * Simple data structure to keep stats about something.
 *
 * XXX probably the first value should be kept and used as an offset for
 * better numerical stability...
 */
typedef struct SimpleStats
{
        int64           count;                  /* how many values were encountered */
        double          min;                    /* the minimum seen */
        double          max;                    /* the maximum seen */
        double          sum;                    /* sum of values */
        double          sum2;                   /* sum of squared values */
} SimpleStats;


/*
 * Data structure to hold various statistics: per-thread and per-script stats
 * are maintained and merged together.
 */
typedef struct StatsData
{
        long            start_time;             /* interval start time, for aggregates */
        int64           cnt;                    /* number of transactions */
        int64           skipped;                /* number of transactions skipped under --rate
                                                                 * and --latency-limit */
        SimpleStats latency;
        SimpleStats lag;
} StatsData;

打印语句的RT (语句的累计时间 除以 语句的调用次数)

                        /* Report per-command latencies */
                        if (is_latencies)
                        {
                                Command   **commands;

                                printf(" - statement latencies in milliseconds:\n");

                                for (commands = sql_script[i].commands;
                                         *commands != NULL;
                                         commands++)
                                        printf("   %11.3f  %s\n",
                                                   1000.0 * (*commands)->stats.sum /
                                                   (*commands)->stats.count,
                                                   (*commands)->line);
                        }

Count

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
4月前
|
SQL 数据库 数据安全/隐私保护
SQL Server数据库Owner导致事务复制log reader job无法启动的解决办法
【8月更文挑战第14天】解决SQL Server事务复制Log Reader作业因数据库所有者问题无法启动的方法:首先验证数据库所有者是否有效并具足够权限;若非,使用`ALTER AUTHORIZATION`更改为有效登录名。其次,确认Log Reader使用的登录名拥有读取事务日志所需的角色权限。还需检查复制配置是否准确无误,并验证Log Reader代理的连接信息及参数。重启SQL Server Agent服务或手动启动Log Reader作业亦可能解决问题。最后,审查SQL Server错误日志及Windows事件查看器以获取更多线索。
|
1月前
|
SQL Oracle 关系型数据库
[SQL]事务
本文介绍了事务处理的基本概念,包括事务的四大特性(原子性、一致性、隔离性、持久性)及生命周期。文章还详细解释了事务的保存点、四种事务隔离级别及其异常读现象,并提供了设置事务隔离级别的方法。最后,作者建议读者深入学习相关理论以更好地理解事务隔离级别。
46 0
|
3月前
|
SQL 关系型数据库 C语言
PostgreSQL SQL扩展 ---- C语言函数(三)
可以用C(或者与C兼容,比如C++)语言编写用户自定义函数(User-defined functions)。这些函数被编译到动态可加载目标文件(也称为共享库)中并被守护进程加载到服务中。“C语言函数”与“内部函数”的区别就在于动态加载这个特性,二者的实际编码约定本质上是相同的(因此,标准的内部函数库为用户自定义C语言函数提供了丰富的示例代码)
|
4月前
|
SQL 存储 关系型数据库
PostgreSQL核心之SQL基础学习
PostgreSQL核心之SQL基础学习
50 3
|
4月前
|
SQL 安全 关系型数据库
PostgreSQL SQL注入漏洞(CVE-2018-10915)--处理
【8月更文挑战第8天】漏洞描述:PostgreSQL是一款自由的对象关系型数据库管理系统,支持多种SQL标准及特性。存在SQL注入漏洞,源于应用未有效验证外部输入的SQL语句,允许攻击者执行非法命令。受影响版本包括10.5及更早版本等。解决方法为升级PostgreSQL
291 2
|
3月前
|
SQL 安全 数据库
基于SQL Server事务日志的数据库恢复技术及实战代码详解
基于事务日志的数据库恢复技术是SQL Server中一个非常强大的功能,它能够帮助数据库管理员在数据丢失或损坏的情况下,有效地恢复数据。通过定期备份数据库和事务日志,并在需要时按照正确的步骤恢复,可以最大限度地减少数据丢失的风险。需要注意的是,恢复数据是一个需要谨慎操作的过程,建议在执行恢复操作之前,详细了解相关的操作步骤和注意事项,以确保数据的安全和完整。
146 0
|
4月前
|
SQL 监控 供应链
|
4月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
455 0
|
4月前
|
SQL 关系型数据库 MySQL
SQL Server 事务执行、回滚
SQL Server 事务执行、回滚
50 0
|
6月前
|
SQL 数据库 索引
SQL中如何实现事务?
【6月更文挑战第17天】SQL中如何实现事务?
52 2

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版