为什么在使用PostgreSQL后,仅使用SELECT的事务后我的COMMIT会变慢?

时间:2013-08-09 20:19:50

标签: postgresql

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

根据New Relic Python代理程序,我的视图处理时间的30%用于等待COMMIT完成,并且在发出大量SELECT查询的视图中尤其如此,即使它们没有修改任何数据。

我期望一个只读的事务在提交阶段很少有工作要做。在这些只读查询的COMMIT期间,Postgres做了什么?

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

2 个答案:

答案 0 :(得分:3)

为了使数据库保持良好状态,需要进行各种清理操作,其中许多操作都是由偶然遇到机会的第一个进程完成的,即使该进程只执行选择查询。

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

应该可以检测给定事务中完成的所有WAL操作何时来自清理操作,然后在这些情况下自动异步提交。但是还没有人能够实现这个功能(甚至编目这个类别中的所有WAL呼叫站点)。

答案 1 :(得分: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