导读:本期聚焦于小伙伴创作的《如何用pg_test_timing检测PostgreSQL的计时精度是否影响性能测试?》,敬请观看详情。当你在PostgreSQL上跑基准测试却发现数字忽高忽低,有没有想过是操作系统计时源本身不准?pg_test_timing是官方随发行包提供的命令行工具,专门测量数据库依赖的时钟获取开销与抖动。它循环调用时钟函数并记录耗时分布,若单次取时超过一微秒或波动明显,EXPLAIN ANALYZE等依赖计时的统计就会失真。本文说明其编译位置、运行参数与结果判读,帮助你判断计时偏差是否已构成测试瓶颈,以及何时该切换clock_source或调整内核配置来稳住基准数据。

pg_test_timing是PostgreSQL源码contrib目录下提供的实用程序,用于在数据库部署环境中直接检验时钟源(clock source)的解析度与稳定性。许多性能问题并非SQL本身缓慢,而是底层gettimeofday或clock_gettime系统调用在不同硬件和虚拟化环境下表现出不可预期的延迟,从而导致执行计划统计、等待事件采样出现偏差。理解这个工具的工作原理,是开展可信基准测试的前提。

一、pg_test_timing的基本作用与原理

在PostgreSQL内部,无论是EXPLAIN ANALYZE输出节点耗时,还是pg_stat_statements记录总耗时,都依赖操作系统提供的计时函数。如果计时调用本身消耗了数百纳秒且抖动剧烈,那么测量出的SQL时间就会叠加这部分噪声。pg_test_timing通过紧密循环获取当前时间,统计每次调用花费的周期数,并以直方图展示不同延迟区间的占比。

该工具不连接任何数据库实例,它纯粹在用户态反复执行时钟读取。默认使用与数据库相同的时钟源,因此能真实反映postgres进程可能遭遇的计时开销。其输出中的“Timing overhead”一行给出平均每次取时的开销,若数值高于1微秒,通常意味着在该机器上做微基准测试会得到失真结论。

1.1 编译与存放位置

在从源码安装时,进入contrib/pg_test_timing目录执行make与make install即可。使用包管理器(如apt或yum)安装的服务器版本,通常已将该二进制置于/usr/lib/postgresql/版本/bin/或同等路径下。可直接用which pg_test_timing确认可用性。

# 源码编译示例
cd postgresql-15.4/contrib/pg_test_timing
make
sudo make install

# 直接运行查看帮助
pg_test_timing --help

上述命令中,make阶段会链接PostgreSQL头文件,确保工具与运行实例使用一致的时钟宏定义。若系统缺失开发包,可先安装postgresql-server-dev对应版本再编译。

二、运行参数与结果解读

pg_test_timing支持少量参数:-d指定测试总时长(秒),默认3秒;-p仅显示每次循环的开销而不打印直方图。对于快速巡检,执行pg_test_timing -d 1即可在一秒内获得统计。

2.1 输出结构分析

典型输出包含“Per loop time including overhead”以及按时间区间划分的“Histogram of timing durations”。前者表示每次循环平均耗时,后者列出如100ns以下、100-200ns等区间的命中次数。若大量样本落在较高区间,说明时钟源受中断或虚拟化影响。

Testing timing overhead for 1 seconds.
Per loop time including overhead: 112 ns
Histogram of timing durations:
  < 100ns:   8234512  78.3%
  100-200ns: 2103444  20.0%
  200-500ns:  165021   1.6%
  > 500ns:     1234   0.1%

以上示例中,平均开销112纳秒属于可接受范围,但仍有约1.7%的调用超过200纳秒。在测量亚毫秒级查询时,这部分长尾会拉高标准差。若发现“Per loop”超过1000纳秒,应考虑修改内核时钟源。

2.2 常见时钟源调整

Linux下可通过cat /sys/devices/system/clocksource/clocksource0/current_clocksource查看当前源。在虚拟机中tsc可能不稳定,可尝试切换为kvm-clock或acpi_pm。修改需在启动时通过内核参数指定,并重新运行pg_test_timing验证开销下降。

时钟源典型开销适用场景
tsc20-50ns物理机且不变频
kvm-clock100-300nsKVM虚拟化
acpi_pm500ns以上老旧硬件兼容

表格列出三种源的对比。当数据库跑在云主机却使用了acpi_pm,pg_test_timing很容易报出微秒级开销,此时联系厂商切换为更优源才能拿到干净数据。

三、在性能测试中的实际用法

在正式用pgbench压测前,先跑pg_test_timing确认环境。若开销异常,则pgbench的TPS波动不能简单归咎于参数配置。可将其写入巡检脚本,作为硬件验收一步。

3.1 结合pgbench的判读

假设pg_test_timing显示平均900ns开销,而pgbench测得某查询平均耗时50us,那么计时噪声占比近2%,且每次测量的置信区间会变宽。此时优化shared_buffers等参数得到的提升,可能被噪声淹没。先解决计时再调优,才符合工程逻辑。

# 巡检脚本片段
if pg_test_timing -d 2 | grep -q "Per loop time including overhead: [0-9]+ ns"; then
  overhead=$(pg_test_timing -d 2 | awk '/Per loop/ {print $5}')
  echo "当前计时开销为 $overhead 纳秒"
fi

该脚本提取开销值供后续判断。实践中可设定阈值,如超过500纳秒就中止当天的基准任务并告警。这样避免把环境缺陷误读为代码回归。

3.2 避免误区

有人以为pg_test_timing数字低就代表数据库快,这是概念混淆。它只测计时本身,不反映IO或锁竞争。正确认知是:它告诉你“尺子准不准”,而不是“桌子有多长”。只有尺子准了,后续所有用PostgreSQL内置计时得到的指标才值得信。

计时精度是性能测试的隐藏前提,忽略它,再漂亮的TPS曲线也可能只是噪声的舞蹈。

综上,把pg_test_timing作为环境摸底工具,养成压测前必跑的习惯,才能让你的PostgreSQL优化结论站得住脚。

pg_test_timingPostgreSQL计时精度修改时间:2026-08-10 13:42:43

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。