Задать вопрос

VACUUM в PostgreSQL 15 уже несколько суток в фазе vacuuming indexes что можно сделать?

В PostgreSQL 15 есть большая не секционированная таблица (~2.4 ТБ), для которой VACUUM перестал завершаться за приемлемое время и уже 4 сутки висит в фазе vacuuming indexes.

pg_stat_progress_vacuum почти всегда показывает фазу vacuuming indexes, heap_blks_scanned и heap_blks_vacuumed растут крайне медленно.

pid                  | 659632
datid                | 16476
relid                | 54995
phase                | vacuuming indexes
heap_blks_total      | 1172082308
heap_blks_scanned    | 695643348
heap_blks_vacuumed   | 692970226
index_vacuum_count   | 61
max_dead_tuples      | 178956969
num_dead_tuples      | 178956698


Что пробовал: прерывал долгий VACUUM, запускал VACUUM (INDEX_CLEANUP OFF) — завершился за ~5 часов, затем перестроил индексы (PK ~690 ГБ и составной на 2 поля (int, timestamp) ~800 ГБ). Ситуация не изменилась.

vacuum_cost_delay = 0
maintenance_work_mem = 16GB (пробовал на уровне сессии, 50GB - эффекта не дало)
какие еще "ручки" можно покрутить?

Как корректно очистить таблицу вместе с индексами и понять, почему затык именно на этой таблице? Раньше VACUUM укладывался в 6–8 часов.
  • Вопрос задан
  • 250 просмотров
Подписаться 4 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
Melkij
@Melkij
DBA для вашего PostgreSQL?
В фазе vacuuming indexes нам нужно прочитать и обработать все индексы таблицы. Наступает эта фаза всякий раз когда набирается num_dead_tuples столько, сколько уже не лезет в max_dead_tuples (который, в свою очередь, считается от maintenance_work_mem, но для pg15 это по-прежнему не более 1гб, 178956969 как раз похоже на 1гб списка таплов)
index_vacuum_count - это как раз и есть счётчик, сколько раз вызывали vacuuming indexes. За четверо суток 61 раз vacuuming indexes, то есть не более 1,5 часа каждый - вполне неплохо, бывало веселее, когда каждый vacuuming indexes длился часов по 15.

Начиная с pg13 vacuum (но не autovacuum) может запускать дополнительных воркеров для vacuuming indexes. Применимы max_parallel_maintenance_workers (до тех пор пока позволяют max_parallel_workers и max_worker_processes). Воркеры работают по принципу очереди из списка индексов, в пределе можно запустить воркеров по числу индексов.

Раз досчитали до index_vacuum_count = 61, значит уже прожевали порядка 11млрд мёртвых строк. Похоже что недавно было массовое удаление старых/более ненужных данных. Ну или не менее массовый update, который, конечно, тоже оставит много мёртвых строк.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы