Postgres表现问题

时间:2012-08-13 18:55:54

标签: performance postgresql

我们正在运行Postgres 9.1.3,并且我们最近开始在我们的一台服务器上遇到重大性能问题。

我们的查询运行良好一段时间,但截至8月1日,它们已经大幅放缓。似乎大多数有问题的查询都是Select查询(带有count(*)的查询特别糟糕),但一般情况下,数据库的运行速度非常慢。

我们在服务器上运行this查询,这些是我们对默认配置文件所做的更改(注意:之前服务器运行正常,因此,它们可能无关紧要) :

       name            |                                                current_setting
---------------------------+---------------------------------------------------------------------------------------------------------------
version                   | PostgreSQL 9.1.2 on x86_64-unknown-linux-gnu, compiled by  gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-51), 64-bit
autovacuum                | off
bgwriter_delay            | 20ms
checkpoint_segments       | 6
checkpoint_warning        | 0
client_encoding           | UTF8
default_statistics_target | 1000
effective_cache_size      | 4778MB
effective_io_concurrency  | 2
fsync                     | off
full_page_writes          | off
lc_collate                | en_US.UTF-8
lc_ctype                  | en_US.UTF-8
listen_addresses          | *
maintenance_work_mem      | 1GB
max_connections           | 100
max_stack_depth           | 2MB
port                      | 5432
random_page_cost          | 2
server_encoding           | UTF8
shared_buffers            | 1792MB
synchronous_commit        | off
temp_buffers              | 16MB
TimeZone                  | US/Eastern
wal_buffers               | 16MB
wal_level                 | minimal
wal_writer_delay          | 10ms
work_mem                  | 16MB
(28 rows)

Time: 210.231 ms

通常,当出现这样的问题时,人们首先推荐的是吸尘,我们已经尝试过。我们对大部分数据库进行了真空分析,但没有帮助。

我们在一些查询中使用了Explain,并注意到Postgres正在使用顺序扫描,即使这些表有索引也是如此。

我们关闭顺序扫描以强制查询计划程序使用索引,但这也没有帮助。

然后我们尝试了this查询,看看我们是否有很多未使用的磁盘空间,Postgres正在经历这些磁盘空间以查找它正在寻找的内容。不幸的是,虽然我们的一些表确实有点大量,但它似乎不足以降低整体系统性能。

我们认为减速可能与I / O有关,但我们无法弄清楚具体细节。 Postgres是愚蠢的,如果是的话,它的哪一部分? VM有什么问题,或者物理硬件本身可能有问题吗?

你们对我们可以尝试或检查的事情有任何其他建议吗?

编辑:

我很抱歉没有尽快更新。我被其他事情搞砸了。

在这台特定的机器上,通过对虚拟机的设置进行一次小的修改,我们的性能得到了极大的提升。

有一个处理IO缓存的设置。它最初设置为ON。我们认为不断缓存事情会减慢事情的速度,我们是正确的。我们把它关掉了,事情急剧改善。

有趣的是,我们大多数其他服务器已关闭此设置。

还有其他问题,我相信我们会提出很多建议,所以,非常感谢您的帮助。

4 个答案:

答案 0 :(得分:13)

你最大的问题是这一行:

autovacuum                | off

打开它不会立即解决问题,但它应该防止事情进一步恶化。几乎没有任何情况下关闭它是个好主意。主要的例外是大量装载,然后是明确的VACUUM FREEZE ANALYZE,之后应该重新打开autovacuum。关闭autovacuum后,您将看到性能下降,就像您一样。一旦数据库变得如此糟糕,它需要比autovacuum可以提供的更积极的维护来恢复。

checkpoint_segments       | 6

增加此值有助于数据修改,但不会提高SELECT语句的速度。

fsync                     | off
full_page_writes          | off

这些设置告诉PostgreSQL以牺牲持久性为代价来加速写入。如果您的硬件或操作系统(或VM)崩溃或突然被杀,您的数据库将被破坏,最好的办法是从上次已知的良好备份中恢复。 (当然,由于硬件可能随时出现故障,如果您担心丢失数据,则可以采用良好的备份策略。)

maintenance_work_mem      | 1GB

这对于8GB的VM而言太高了。在对该连接运行一些繁重的维护之前,您始终可以在单个连接上对其进行增强。

wal_writer_delay          | 10ms

即使是经验丰富的专家也难以将其调整为比默认值更好的性能。几乎总是最好不要管它。

此时最好的办法是使用pg_dumpall将数据库集群转储到其他介质,从新的initdb开始,然后恢复。作为数据库超级用户,运行VACUUM FREEZE ANALYZE(通常不建议使用FREEZE,除非在此类批量加载之后),并且在启用autovacuum的情况下运行。

我强烈建议您获得Greg Smith的“PostgreSQL 9.0高性能”一书的副本,并仔细阅读。 (完全披露,我是这本书的技术评论员之一,但没有从销售中获得金钱。)他建议的第一件事就是在你安装PostgreSQL之前获得RAM和磁盘速度的基准数字 - 那个你知道你在做什么的方式。

答案 1 :(得分:10)

很难确定,但我认为你对I / O问题持怀疑态度是正确的。可能发生的是,随着表变大或连接增加,缓存命中率开始下降。这会增加I / O需求并减慢一切。同时,更多的查询到达,使问题变得更糟。这种情况对您来说很复杂,因为虚拟磁盘的行为不一定与物理磁盘相同。

首先,您需要测量VM上的实际活动(可能通过vmstat或iostat)。其次,在真实硬件上做同样的事情。最后,在两者上运行一些标准磁盘带宽工具(特别是随机读/写混合)。现在,您可以说明您正在使用的可用I / O的数量。

至于查询计划,没有架构细节和解释分析输出,没有人可以说。

你会发现postgresql.org邮件列表很有用,即使只是为了档案。此外,下面链接的书非常好。

http://www.packtpub.com/postgresql-90-high-performance/book

答案 2 :(得分:2)

  

(带有count(*)的查询特别糟糕),

您应该查看window functions

否则,我们不知道没有看到您的相关架构和您的查询。

答案 3 :(得分:0)

我也打开自动吸尘器。您可以设置一些变量来控制真空干扰的程度。使用大量的RAM,您应该将共享缓冲区设置在2048MB到3276MB之间。如果您的系统似乎没有使用大量额外的RAM,而您在其他地方并不需要,那么您应该将其设置为更接近更高端。您也可以使用sysctl查看最大段大小。你的maintenance_work_mem真的很高,但是如果你主要做的是维护,那么我认为它没有我想象的那么糟糕。