12

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

我们的查询在一段时间内运行良好,但截至 8 月 1 日,它们的速度急剧下降。看起来大多数有问题的查询都是 Select 查询(带有 count(*) 的查询特别糟糕),但总的来说,数据库运行得很慢。

我们在服务器上运行了这个查询,这些是我们对默认配置文件所做的更改(注意:服务器在这些更改之前运行良好,因此它们可能并不重要):

       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 使用顺序扫描,即使表有索引。

我们关闭了顺序扫描以强制查询计划器使用索引,但这也无济于事。

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

我们认为减速可能与 I/O 有关,但我们无法弄清楚具体情况。Postgres 只是愚蠢吗?如果是,那是什么?虚拟机有问题,还是物理硬件本身有问题?

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

编辑:

我很抱歉没有早点更新这个。我被其他事情缠住了。

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

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

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

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

4

4 回答 4

15

你最大的问题是这一行:

自动真空 | 离开

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

checkpoint_segments | 6

增加这将有助于数据修改,但不会对提高SELECT语句的速度起到太大作用。

同步 | 离开
full_page_writes | 离开

这些设置告诉 PostgreSQL 以牺牲持久性为代价来加快写入速度。如果您的硬件或操作系统(或虚拟机)崩溃或突然终止,您的数据库将损坏,您最好的选择是从上次已知的良好备份中恢复。(当然,由于硬件随时可能发生故障,如果您担心丢失数据,那么您有一个很好的备份策略。)

维护工作内存 | 1GB

这对于 8GB 虚拟机来说太高了。在对该连接进行大量维护之前,您始终可以在单个连接上提升它。

wal_writer_delay | 10ms

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

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

我强烈建议您获取 Greg Smith 的“PostgreSQL 9.0 High Performance”一书,并仔细阅读。(完全公开,我是这本书的技术审稿人之一,但没有从销售中获得任何收入。)他建议的第一件事是在安装 PostgreSQL 之前获得 RAM 和磁盘速度的基准数据——即方式你知道你在处理什么。

于 2012-08-15T02:08:12.373 回答
11

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

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

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

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

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

于 2012-08-13T21:27:45.533 回答
2

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

你应该看看窗口函数

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

于 2012-08-13T19:13:01.873 回答
0

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

于 2014-01-18T10:46:18.923 回答