5

我有一个 Web 应用程序显示由单独的进程生成并存储在 PostgreSQL 8.4 版中的数据。后端相当连续地写入,但 Web 应用程序中的大多数视图只执行只读 SELECT 查询。

根据 New Relic Python 代理的说法,我 30% 的视图处理时间都花在等待 COMMIT 完成上,在发出大量 SELECT 查询的视图中尤其糟糕,即使它们没有修改任何数据。

我希望一个只读事务在提交阶段几乎没有工作要做。Postgres 在 COMMIT 期间对这些只读查询做了什么?

我知道我可以关闭synchronous_commit这些事务以隐藏视图中的延迟,我当然不关心只读事务的持久性,但我不明白为什么它应该是必要的,我很担心这样做可能会掩盖更深层次的错误配置。

4

2 回答 2

4

需要执行各种清理操作以保持数据库处于良好状态,其中许多是由偶然发现机会的第一个进程完成的,即使该进程仅执行选择查询。

这些清理操作可以生成 WAL 记录,然后在提交时触发同步。因此,虽然选择在用户可见级别上可能是只读的,但在幕后,它们实际上是在进行写入。

应该可以检测到给定事务中完成的所有 WAL 操作何时来自清理操作,然后在这些情况下自动异步执行提交。但是还没有人开始实现这个特性(或者甚至对所有属于这个类别的 WAL 调用站点进行编目)。

于 2013-08-09T22:07:13.803 回答
1

评论太短了,就这样吧。在运行代码时捕获一些日志,并将猜测工作排除在等式之外。

更新 postgresql.conf 以获得这些设置。您将需要重新启动 postgre 以获取 logging_collector。完成后,您可以并且应该删除这些设置。因此,请确保在进行任何更改之前备份 postgresql.conf。一旦你有一个包含捕获数据的日志文件,如果日志超过一页左右,我建议使用它来查看它http://dalibo.github.io/pgbadger/

log_destination = 'stderr'
logging_collector = on
log_directory = 'pg_log'
log_filename = 'postgresql-%Y-%m-%d.log'
log_rotation_age = 0
client_min_messages = notice
log_min_messages = warning
log_min_error_statement = error
log_min_duration_statement = 0
log_checkpoints = on
log_connections = on
log_disconnections = on
log_duration = off
log_error_verbosity = verbose
log_hostname = on
log_line_prefix = '%t [%p]: [%l-1] db=%d,user=%u '
log_lock_waits = on
log_statement = 'none'
log_temp_files = 0
于 2013-08-09T21:44:17.167 回答