PostgreSQL:如何记录查询执行后同步提交所花费的时间?(文档没有帮助)

q8l4jmvw  于 2023-04-11  发布在  PostgreSQL
关注(0)|答案(1)|浏览(168)

我在ubuntu上运行PostgreSQL 12服务器。下面是我的postgresql.conf文件中的相关设置:

log_duration = on
log_statement = 'all'
log_destination = 'csvlog'
logging_collector = on

我从rust程序在本地运行了几个更新查询,它们需要大约3-4毫秒才能返回。我从转储的csv文件中检查了PostgreSQL日志,我惊讶地发现记录的查询持续时间只有大约0.18毫秒。
这个差异对我来说似乎太大了,不可能只是客户端应用程序的开销。我禁用了同步提交,现在客户端的查询时间不超过1毫秒。所以看起来开销是由于同步提交和fdatasync系统调用。
我的问题是,为什么这个开销没有反映在日志中,我在文档中也找不到任何指定查询持续时间不包括提交所花费的时间的信息。另外,如果我需要,我如何记录每个提交操作所花费的时间?

axr492tv

axr492tv1#

在这里,我花了几乎整个星期天的时间查看PostgreSQL源代码和阅读前端后端协议(https://www.postgresql.org/docs/current/protocol.html)的文档。现在,我相信我有答案了。
首先,我应该在问题中提到这一点,但我的客户端应用程序使用的是扩展查询协议。当客户端向服务器发送“Sync”消息时,会发生同步(以及随后的fsync到光盘)。但是,不会记录同步,只有前一个Execute才是,Execute不包括提交时间,因为提交是通过单独的消息(Sync)完成的。如果您想要写入磁盘所需的时间,则需要使用显式的开始和COMMIT。
当您使用扩展查询协议时,上述内容适用。如果您运行的是简单查询,则会记录完整的持续时间(包括写入光盘所需的时间)。有关完整内容,请查看:https://github.com/postgres/postgres/blob/master/src/backend/tcop/postgres.c
相关职能包括:
exec_simple_query:它在中间检查是否应该提交简单查询。(假设不使用显式BEGINCOMMIT。)
PostgresMain:里面的switch语句将阐明,在扩展查询协议中,ExecuteSync是单独的步骤,Sync不会被记录。

相关问题