27.4. Отслеживание выполнения

В PostgreSQL имеется возможность отслеживать выполнение определённых команд. В настоящее время такое отслеживание поддерживается только для команд CREATE INDEX, VACUUM и CLUSTER. В будущем эта поддержка может быть расширена.

27.4.1. Отслеживание выполнения CREATE INDEX

Во время выполнения CREATE INDEX или REINDEX представление pg_stat_progress_create_index будет содержать по одной строке для каждого обслуживающего процесса, создающего индексы в этот момент. Таблицы ниже показывают, какая информация будет отслеживаться, и поясняют, как её интерпретировать.

Таблица 27.22. Представление pg_stat_progress_create_index

СтолбецТипОписание
pidintegerИдентификатор (PID) обслуживающего процесса
datidoidOID базы данных, к которой подключён этот обслуживающий процесс.
datnamenameИмя базы данных, к которой подключён этот обслуживающий процесс.
relidoidOID таблицы, в которой создаётся индекс.
index_relidoidOID создаваемого или перестраиваемого индекса. При выполнении CREATE INDEX в неблокирующем режиме содержит 0.
commandtextВыполняемая команда: CREATE INDEX, CREATE INDEX CONCURRENTLY, REINDEX или REINDEX CONCURRENTLY.
phasetextТекущая фаза создания индекса. См. Таблицу 27.23.
lockers_totalbigintОбщее число процессов, потребовавших ожидания, если таковые имеются.
lockers_donebigintЧисло процессов, ожидание которых уже завершено.
current_locker_pidbigintИдентификатор процесса, удерживающего конфликтующую блокировку в данный момент.
blocks_totalbigintОбщее число блоков, которые должны быть обработаны в текущей фазе.
blocks_donebigintЧисло блоков, уже обработанных в текущей фазе.
tuples_totalbigintОбщее число кортежей, которые должны быть обработаны в текущей фазе.
tuples_donebigintЧисло кортежей, уже обработанных в текущей фазе.
partitions_totalbigintПри создании индекса в секционированной таблице этот столбец содержит общее число секций, в которых создаётся индекс.
partitions_donebigintПри создании индекса в секционированной таблице этот столбец содержит число секций, в которых индекс уже построен.

Таблица 27.23. Фазы CREATE INDEX

ФазаОписание
initializingИнициализация — процедура CREATE INDEX или REINDEX подготавливается к созданию индекса. Эта фаза должна быть очень быстрой.
waiting for writers before buildОжидание окончания записи перед построением — процедура CREATE INDEX CONCURRENTLY или REINDEX CONCURRENTLY ожидает завершения транзакций, которые удерживают блокировки записи и могут читать таблицу. Эта фаза пропускается при выполнении операции в неблокирующем режиме. Выполнение процедуры в этой фазе отражается в столбцах lockers_total, lockers_done и current_locker_pid.
building indexПостроение индекса — код, реализующий метод доступа, строит индекс. В этой фазе методы доступа, поддерживающие отслеживание процесса, передают свои данные о текущем состоянии, и в этом столбце видна внутренняя фаза. Обычно ход построения индекса отражается в столбцах blocks_total и blocks_done, но также могут меняться и столбцы tuples_total и tuples_done.
waiting for writers before validationОжидание окончания записи перед проверкой — процедура CREATE INDEX CONCURRENTLY или REINDEX CONCURRENTLY ожидает завершения транзакций, которые удерживают блокировки записи и могут записывать в таблицу. Эта фаза пропускается при выполнении операции в неблокирующем режиме. Выполнение процедуры в этой фазе отражается в столбцах lockers_total, lockers_done и current_locker_pid.
index validation: scanning indexПроверка индекса: сканирование — процедура CREATE INDEX CONCURRENTLY сканирует индекс, находя кортежи, требующие проверки. Эта фаза пропускается при выполнении операции в неблокирующем режиме. Выполнение процедуры в этой фазе отражается в столбцах blocks_total (показывающем общий размер индекса) и blocks_done.
index validation: sorting tuplesПроверка индекса: сортировка кортежей — процедура CREATE INDEX CONCURRENTLY сортирует результат фазы сканирования индекса.
index validation: scanning tableПроверка индекса: сканирование таблицы — процедура CREATE INDEX CONCURRENTLY сканирует таблицу, чтобы проверить кортежи индекса, собранные в предыдущих двух фазах. Эта фаза пропускается при выполнении операции в неблокирующем режиме. Выполнение процедуры в этой фазе отражается в столбцах blocks_total (показывающем общий размер таблицы) и blocks_done.
waiting for old snapshotsОжидание старых снимков — процедура CREATE INDEX CONCURRENTLY или REINDEX CONCURRENTLY ожидает освобождения снимков теми транзакциями, которые могут видеть содержимое таблицы. Эта фаза пропускается при выполнении операции в неблокирующем режиме. Выполнение процедуры в этой фазе отражается в столбцах lockers_total, lockers_done и current_locker_pid.
waiting for readers before marking deadОжидание завершения чтения перед отключением старого индекса — процедура REINDEX CONCURRENTLY ожидает завершения транзакций, которые удерживают блокировки чтения, прежде чем пометить старый индекс как нерабочий. Эта фаза пропускается при выполнении операции в неблокирующем режиме. Выполнение процедуры в этой фазе отражается в столбцах lockers_total, lockers_done и current_locker_pid.
waiting for readers before droppingОжидание завершения чтения перед удалением старого индекса — процедура REINDEX CONCURRENTLY ожидает завершения транзакций, которые удерживают блокировки чтения, прежде чем удалить старый индекс. Эта фаза пропускается при выполнении операции в неблокирующем режиме. Выполнение процедуры в этой фазе отражается в столбцах lockers_total, lockers_done и current_locker_pid.

27.4.2. Отслеживание выполнения VACUUM

В процессе выполнения VACUUM представление pg_stat_progress_vacuum будет содержать по одной строке для каждого обслуживающего процесса (включая рабочие процессы автоочистки), производящего очистку в данный момент. Таблицы ниже показывают, какая информация будет отслеживаться, и поясняют, как её интерпретировать. Выполнение команд VACUUM FULL отслеживается через pg_stat_progress_cluster, так как и VACUUM FULL, и CLUSTER перезаписывают таблицу, тогда как обычная команда VACUUM модифицирует её саму. См. Подраздел 27.4.3.

Таблица 27.24. Представление pg_stat_progress_vacuum

СтолбецТипОписание
pidintegerИдентификатор (PID) обслуживающего процесса
datidoidOID базы данных, к которой подключён этот обслуживающий процесс.
datnamenameИмя базы данных, к которой подключён этот обслуживающий процесс.
relidoidOID очищаемой таблицы.
phasetextТекущая фаза очистки. См. Таблицу 27.25.
heap_blks_totalbigintОбщее число блоков кучи в таблице. Это число отражает состояние в начале сканирования; блоки, добавленные позже, не будут (и не должны) обрабатываться текущей командой VACUUM.
heap_blks_scannedbigintЧисло просканированных блоков кучи. Так как для оптимизации сканирования применяется карта видимости, некоторые блоки могут пропускаться без осмотра; пропущенные блоки входят в это общее число, так что по завершении очистки это число станет равно heap_blks_total. Этот счётчик увеличивается только в фазе scanning heap.
heap_blks_vacuumedbigintЧисло очищенных блоков кучи. Если в таблице нет индексов, этот счётчик увеличивается только в фазе vacuuming heap (очистка кучи). Блоки, не содержащие «мёртвых» кортежей, при этом пропускаются, так что этот счётчик иногда может увеличиваться резкими рывками.
index_vacuum_countbigintКоличество завершённых циклов очистки индекса.
max_dead_tuplesbigintЧисло «мёртвых» кортежей, которое мы можем сохранить, прежде чем потребуется выполнить цикл очистки индекса, в зависимости от maintenance_work_mem.
num_dead_tuplesbigintЧисло «мёртвых» кортежей, собранных со времени последнего цикла очистки индекса.

Таблица 27.25. Фазы VACUUM

ФазаОписание
initializingИнициализация — VACUUM готовится начать сканирование кучи. Эта фаза должна быть очень быстрой.
scanning heapСканирование кучи — VACUUM в настоящее время сканирует кучу. При этом будет очищена и, если требуется, дефрагментирована каждая страница, а возможно, также будет произведена заморозка. Отслеживать процесс сканирования можно, следя за содержимым столбца heap_blks_scanned.
vacuuming indexesОчистка индексов — VACUUM в настоящее время очищает индексы. Если у таблицы есть какие-либо индексы, эта фаза будет наблюдаться минимум единожды в процессе очистки, после того, как куча будет просканирована полностью. Она может повторяться несколько раз в процессе очистки, если объёма maintenance_work_mem (или, в случае автоочистки, autovacuum_work_mem, если он задан) оказывается недостаточно для сохранения всех найденных «мёртвых» кортежей.
vacuuming heapОчистка кучи — VACUUM в настоящее время очищает кучу. Очистка кучи отличается от сканирования, так как она происходит после каждой операции очистки индексов. Если heap_blks_scanned меньше чем heap_blks_total, система вернётся к сканированию кучи после завершения этой фазы; в противном случае она начнёт уборку индексов.
cleaning up indexesУборка индексов — VACUUM в настоящее время производит уборку в индексах. Это происходит после завершения полного сканирования кучи и очистки индексов и кучи.
truncating heapУсечение кучи — VACUUM в настоящее время усекает кучу, чтобы возвратить операционной системе объём пустых страниц в конце отношения. Это происходит после уборки индексов.
performing final cleanupВыполнение окончательной очистки — VACUUM выполняет окончательную очистку. На этой стадии VACUUM очищает карту свободного пространства, обновляет статистику в pg_class и передаёт статистику сборщику статистики, После этой фазы VACUUM завершит свою работу.

27.4.3. Отслеживание выполнения CLUSTER

Во время выполнения CLUSTER или VACUUM FULL представление pg_stat_progress_cluster будет содержать по одной строке для каждого обслуживающего процесса, выполняющего любую из этих команд. Таблицы ниже показывают, какая информация будет отслеживаться, и поясняют, как её интерпретировать.

Таблица 27.26. Представление pg_stat_progress_cluster

СтолбецТипОписание
pidintegerИдентификатор (PID) обслуживающего процесса
datidoidOID базы данных, к которой подключён этот обслуживающий процесс.
datnamenameИмя базы данных, к которой подключён этот обслуживающий процесс.
relidoidOID обрабатываемой таблицы.
commandtextВыполняемая команда: CLUSTER или VACUUM FULL.
phasetextТекущая фаза обработки. См. Таблицу 27.27.
cluster_index_relidoidЕсли таблица сканируется по индексу, это поле содержит OID данного индекса, а иначе — 0.
heap_tuples_scannedbigintЧисло просканированных кортежей кучи. Этот счётчик увеличивается только в фазе seq scanning heap, index scanning heap или writing new heap.
heap_tuples_writtenbigintЧисло записанных кортежей кучи. Этот счётчик увеличивается только в фазе seq scanning heap, index scanning heap или writing new heap.
heap_blks_totalbigintОбщее число блоков кучи в таблице. Это число отражает состояние в начале фазы seq scanning heap.
heap_blks_scannedbigintЧисло просканированных блоков кучи. Этот счётчик увеличивается только в фазе seq scanning heap.
index_rebuild_countbigintЧисло перестроенных индексов. Это счётчик увеличивается только в фазе rebuilding index.

Таблица 27.27. Фазы CLUSTER и VACUUM FULL

ФазаОписание
initializingКоманда готовится начать сканирование кучи. Эта фаза должна быть очень быстрой.
seq scanning heapКоманда в данный момент сканирует таблицу последовательным образом.
index scanning heapCLUSTER в данный момент сканирует таблицу по индексу.
sorting tuplesCLUSTER в данный момент сортирует кортежи.
writing new heapCLUSTER в данный момент записывает новую кучу.
swapping relation filesКоманда в данный момент переставляет только что построенные файлы на место.
rebuilding indexКоманда в данный момент перестраивает индекс.
performing final cleanupКоманда выполняет окончательную очистку. После этой фазы CLUSTER или VACUUM FULL завершит работу.