Автовакуум PostgreSQL вызывает значительное снижение производительности

Наша база данных Postgres (размещенная на Google Cloud SQL с 1 ЦП, 3,7 ГБ ОЗУ, см. Ниже) состоит в основном из одной большой таблицы размером ~90 ГБ и приблизительно 60 миллионов строк. Шаблон использования состоит почти исключительно из добавлений и нескольких индексированных чтений в конце таблицы. Время от времени несколько пользователей удаляются, удаляя небольшой процент строк, разбросанных по всей таблице.

Все это прекрасно работает, но каждые несколько месяцев на этом столе срабатывает автовакуум, что существенно влияет на производительность нашего сервиса в течение ~8 часов:

  • Использование памяти увеличивается на ~1 ГБ в течение периода работы автовакуума (несколько часов), а затем медленно возвращается к предыдущему значению (может в конечном итоге упасть ниже его из-за страниц, освобождающих от автовакуума).
  • Загрузка ЦП базы данных возрастает с <10% до ~20%
  • Операции чтения / записи диска увеличиваются с нуля до ~50 в секунду
  • Память базы данных немного увеличивается, но остается ниже 2 ГБ
  • Как и следовало ожидать, байты транзакции / сек и входные / выходные также практически не подвержены влиянию

Это приводит к увеличению 95-го процентиля латентности нашего сервиса с ~100 мс до ~0,5-1 с во время автовакуума, что, в свою очередь, запускает наш мониторинг. Служба обслуживает около десяти запросов в секунду, причем каждый запрос состоит из нескольких простых операций чтения / записи в БД, которые обычно имеют задержку 2-3 мс каждая.

Вот несколько скриншотов мониторинга, иллюстрирующих проблему:

Конфигурация БД довольно ванильная:

Запись в журнале, документирующая этот процесс автоочистки, гласит:

system usage: CPU 470.10s/358.74u sec elapsed 38004.58 sec
avg read rate: 2.491 MB/s, avg write rate: 2.247 MB/s
buffer usage: 8480213 hits, 12117505 misses, 10930449 dirtied
tuples: 5959839 removed, 57732135 remain, 4574 are dead but not yet removable
pages: 0 removed, 6482261 remain, 0 skipped due to pins, 0 skipped frozen
automatic vacuum of table "XXX": index scans: 1

Какие-нибудь предложения, что мы могли бы настроить, чтобы уменьшить влияние будущих автовакуумов на наш сервис? Или мы что-то не так делаем?

1 ответ

Решение

Если вы можете увеличить autovacuum_vacuum_cost_delayВаш автовакуум будет работать медленнее и будет менее агрессивным.

Тем не менее, обычно это лучшее решение, чтобы сделать это быстрее, установив autovacuum_vacuum_cost_limit до 2000 или около того. Тогда это заканчивается быстрее.

Вы также можете попробовать запланировать VACUUMс самим столом иногда, когда это меньше всего болит.

Но, честно говоря, если одного безобидного автовакуума достаточно, чтобы помешать вашей работе, вам нужна большая пропускная способность ввода / вывода.

Другие вопросы по тегам