Сколько времени займет операция вакуум / автоочистка?

18

Я управляю большой (несколько сотен гигов) базой данных, содержащей таблицы с различными ролями, некоторые из которых содержат миллионы записей. Некоторые таблицы получают только большое количество вставок и удалений, другие - только несколько вставок и большое количество обновлений.

База данных работает на PostgreSQL 8.4 в системе Debian 6.0 amd64 с 16 гигабайтами оперативной памяти.

Иногда вопрос заключается в том, что процесс автоочистки на столе занимает очень много времени (дней). Я хочу иметь возможность приблизительно сказать, сколько времени займет конкретная команда вакуума, чтобы иметь возможность решить, отменять ли ее или нет. Также, если бы был индикатор прогресса для вакуумных операций postgres, это было бы очень полезно.

Редактировать:

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

Я видел, что pg_catalog.pg_stat_all_tablesесть столбец для количества мертвых кортежей. Таким образом, можно получить оценку, даже если это означает, что нужно идти к ANALYZEстолу раньше. С другой стороны, autovacuum_vacuum_thresholdи autovacuum_vacuum_scale_factorодни только настройки доказывают, что сам Postgres знает кое-что о количестве изменений в таблицах и, вероятно, передает его в руки администратора баз данных.

Я не уверен, какой запрос выполнить, потому что когда я запускаю VACUUM VERBOSE, я вижу, что обрабатываются не только таблицы, но и индексы по ним.

zaadeh
источник

Ответы:

34

На моем PostgreSQL (8.3) я использую этот трюк:

  1. Я получаю размер диска таблицы, используя pg_total_relation_size()- это включает в себя индексы и размер TOAST, который и VACUUMобрабатывает. Это дает мне представление о том, сколько байтов VACUUMнужно прочитать.
  2. Я бегу VACUUMпо столу.
  3. Я нахожу pidв VACUUMпроцессе (в pg_catalog.pg_stat_activity).
  4. В Linux shell я запускаю while true; do cat /proc/123/io | grep read_bytes; sleep 60; done(где 123pid) - это показывает мне байты, прочитанные процессом с диска до сих пор.

Это дает мне приблизительное представление о том, сколько байтов обрабатывается (читается) каждую минуту VACUUM. Я предполагаю, что VACUUMдолжен прочитать всю таблицу (включая индексы и TOAST), размер диска которого я знаю из шага 1.

Я предполагаю, что таблица достаточно велика, так что большинство ее страниц должны читаться с диска (их нет в общей памяти Postgres), поэтому read_bytesполе достаточно хорошо для использования в качестве счетчика хода выполнения.

Каждый раз, когда я делал это, общее количество байтов, прочитанных процессом, составляло не более 5% от общего размера отношения, поэтому я думаю, что этот подход может быть достаточно хорошим для Вас.

Роман Хокк
источник
Неприятно :) Это работает и для более поздних версий? И, что еще важнее, для автовакуума?
Дезсо
Я не пробовал это для более новых версий. Он должен работать VACUUM FULLна 9.0+, так как полностью переписывает таблицу. Это должно работать для обычного VACUUMтоже, но я еще не проверял это. Ибо autovacuumэто сработало бы, если бы вы могли поймать рабочий процесс autovacuum на заданной таблице, но я не знаю, как этого добиться.
Роман
Есть ли у вас какие-либо предложения о том, как этого добиться с помощью RDS? Естественно, у нас нет доступа к оболочке Linux при использовании RDS, но мы бы очень хотели иметь возможность оценить это.
jwg2s
@ jwg2s Что вы подразумеваете под "RDS", пожалуйста? Сервисы баз данных Amazon? Если это так, я, к сожалению, не знаком с этим :-( Может быть, их поддержка поможет.
Роман Хокк
1
Кажется, хорошо работает на PG 10 с полным вакуумом, а также.
DylanYoung
9

Это очень сложно определить. Вы можете настроить автоочистку чтобы она была более агрессивной или более мягкой. Но если установить значение «мягкий» и оно отстает, а базовая нагрузка ввода-вывода слишком высока, может случиться так, что он никогда не достигнет надлежащего вакуумированного состояния - тогда вы увидите, что процесс работает, работает и работает. Кроме того, более поздние выпуски PostreSQL имеют значительно улучшенные возможности автоочистки, одного этого может быть достаточно, чтобы перейти к одному из них (предпочтительно 9.2 как самый последний).

Индикатор выполнения звучит неплохо, но я думаю, что реализовать его не так просто. Поскольку у вас постоянная нагрузка на ваши таблицы, вполне возможно, что прогресс явно движется в обратном направлении (я имею в виду, что число / процент мертвых строк увеличивается, а не уменьшается) - тогда какой вывод вы сделаете?

Dezso
источник
2
Я предпочитаю видеть какой-то индикатор прогресса, даже если он идет назад, а не ничего.
Зааде
3
VACUUM ANALYZE VERBOSEпо крайней мере, выводит какую-то активность на консоль, как она это делает. Лучше просто смотреть на статичные подсказки, задаваясь вопросом, не застряло ли что-то часами.
Фальшивое имя
Вопрос задается по поводу «вакуума / автовакуума». VACUUMВышесказанное полезно только для , а не для автовакуума, но это все же что-то.
Фальшивое имя
@ FakeName Э, я неправильно прочитал вопрос - пропустил ручную вакуумную часть. Извините, я удаляю свой комментарий.
Дезсо
3

В нашем производстве одна из самых больших таблиц имела этот журнал:

pages: 0 removed, 1801722 remain
tuples: 238912 removed, 42582083 remain, 1396 are dead but not yet removable
buffer usage: 9477565 hits, 3834218 misses, 2220101 dirtied
avg read rate: 2.976 MB/s, avg write rate: 1.723 MB/s
system usage: CPU 68.47s/177.49u sec elapsed 10065.08 sec

Это, безусловно, худшее потребление ресурсов, все другие таблицы заняли менее 2 с.

Чтобы увидеть эти типы журналов, вы должны выполнить это:

alter system set log_autovacuum_min_duration TO 5; 

(в течение 5 мс) перезагрузите файл конфигурации.

stonelazy
источник
3

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

Я использую этот запрос для отслеживания прогресса сканирования таблиц в вакууме, что, кажется, является основной частью работы:

SELECT heap_blks_scanned/cast(heap_blks_total as numeric)*100 as heap_blks_percent, progress.*, activity.query
FROM pg_stat_progress_vacuum AS progress
INNER JOIN pg_stat_activity AS activity ON activity.pid = progress.pid;

Однако это не включает сканирование индекса, которое происходит впоследствии, и может занять столько же времени, если не больше, если у вас есть тонна индексов. К сожалению, я не могу найти способ контролировать индекс сканирования / очистки.

Cerin
источник