Проблемы с производительностью Postgres

Мы запускаем Postgres 9.1.3, и мы недавно начали сталкиваться с серьезными проблемами производительности на одном из наших серверов.

Наши запросы немного прекратились, но по состоянию на 1 августа они резко замедлились. Похоже, что большинство проблемных запросов - это запросы на выбор (запросы с 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 просто глупым, и если да, то какая его часть? Что-то не так с VM, или что-то не так с самим физическим оборудованием?

Есть ли у вас другие предложения для вещей, которые мы можем попробовать или проверить?

EDIT:

Мне очень жаль, что раньше не обновлял. Я попался в другое дело.

На этой конкретной машине наша производительность значительно улучшилась, сделав небольшую модификацию настроек виртуальной машины.

Существует настройка, связанная с кэшированием IO. Первоначально он был установлен в положение ON. Мы полагали, что постоянное кеширование вещей замедляет процесс, и мы были правы. Мы отключили его, и ситуация резко улучшилась.

Интересно, что большинство наших других серверов уже отключили эту настройку.

Есть и другие проблемы, и я уверен, что мы возьмем много ваших предложений, поэтому большое спасибо за помощь.

Ответ 1

Трудно быть уверенным, но я думаю, что вы правы, чтобы быть подозрительными к проблемам ввода-вывода. Что может случиться, так это то, что по мере увеличения таблиц или увеличения соединений кеширование начинает падать. Это увеличивает требования ввода-вывода и замедляет все. Между тем появляется больше запросов, что делает проблему хуже. Ситуация для вас сложна, потому что виртуальные диски не обязательно ведут себя так же, как физические.

Во-первых, вам нужно будет измерить действительную активность на виртуальной машине (возможно, через vmstat или iostat). Во-вторых, сделайте то же самое на реальном оборудовании. Наконец, запустите некоторые стандартные инструменты для работы с дисками на обоих (в частности, случайные миксы чтения/записи). Теперь вы сможете сказать, сколько из ваших доступных I/O используется.

Что касается планов запросов, без деталей схемы и объяснения результатов анализа никто не может сказать.

Вы найдете список почтовых рассылок postgresql.org полезным даже для архивов. Кроме того, книга, приведенная ниже, превосходна.

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

Ответ 2

Самая большая проблема в этой строке:

autovacuum                | off

Включение этого процесса не сразу устранит проблему, но это должно удержать вещи от размывания. Почти нет случаев, когда это хорошая идея, чтобы отключить это. Основное исключение - большая объемная загрузка, за которой следует явный ВАКУУМНЫЙ АНАЛИЗ ЗАКАЗА, после чего автообработку следует снова включить. С отключением autovacuum вы увидите ухудшение производительности, как и у вас. После того, как база данных попала в такую ​​плохую форму, она требует более агрессивного обслуживания, чем позволяет autovacuum для восстановления.

checkpoint_segments       | 6

Увеличение этого объема поможет модификациям данных, но не будет способствовать повышению скорости операторов SELECT.

fsync                     | off
full_page_writes          | off

Эти настройки говорят, что PostgreSQL ускоряет запись за счет сохранения. Если ваше оборудование или ОС (или виртуальная машина) сбой или внезапно будет убито, ваша база данных будет повреждена, и наилучшим решением будет восстановление с вашей последней известной хорошей резервной копии. (Конечно, поскольку аппаратное обеспечение может в любой момент сбой, если вы хотите потерять данные, у вас есть хорошая стратегия резервного копирования.)

maintenance_work_mem      | 1GB

Это слишком велико для VM 8GB. Вы всегда можете увеличить его на одном подключении, прежде чем запускать некоторое техническое обслуживание в этом соединении.

wal_writer_delay          | 10ms

Даже опытные эксперты не могут настроить это на что-то лучшее, чем по умолчанию. Это почти всегда лучше всего оставить в покое.

Лучше всего на этом этапе использовать pg_dumpall, чтобы сбросить кластер базы данных на другой носитель, начать с нового initdb и восстановить. В качестве суперпользователя базы данных запустите VACUUM FREEZE ANALYZE (FREEZE обычно не рекомендуется, кроме как после массовой загрузки) и запускается с включенным autovacuum.

Я настоятельно рекомендую вам получить копию книги Greg Smith "PostgreSQL 9.0 High Performance" и внимательно прочитайте ее. (Полное раскрытие, я был одним из технических рецензентов для книги, но не получаю никаких денег от продаж.) Одна из первых вещей, которую он рекомендует, - это получить контрольные номера на скорости вашей ОЗУ и диска, прежде чем вы даже установите PostgreSQL - это как вы знаете, с чем имеете дело.

Ответ 3

(запросы с count (*) особенно плохи),

Вы должны посмотреть функции окна

В противном случае мы понятия не имеем, не увидев вашу соответствующую схему и ваши запросы.

Ответ 4

Я бы включил авто вакуум. Есть несколько переменных, которые вы можете установить, чтобы контролировать, насколько вакуум будет мешать. С объемом оперативной памяти вы должны иметь свои общие буферы между 2048 МБ - 3276 МБ. Если у вас много лишней памяти, что ваша система, похоже, не использует то, что вам не нужно в другом месте, вы должны, вероятно, установить ее ближе к более высокому концу. Также вы можете посмотреть свой максимальный размер сегмента с помощью sysctl. Ваше обслуживание_work_mem действительно велико, но если вы занимаетесь главным образом обслуживанием, я полагаю, что это не так плохо, как я думал.