Добавил:
ИВТ (советую зайти в "Несортированное")rnПИН МАГА Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Database 2024 / Books / Мониторинг PostgreSQL.pdf
Скачиваний:
26
Добавлен:
20.11.2024
Размер:
6.87 Mб
Скачать

8.5. Отслеживание активных процессов очистки

217

LOG: automatic vacuum of table "pgbench.public.pgbench_accounts": index scans: 1 pages: 0 removed, 66788 remain, 66788 scanned (100.00% of total)

tuples: 1793208 removed, 2000413 remain, 411 are dead but not yet removable removable cutoff: 215988728, which was 1945 XIDs old when operation ended new relfrozenxid: 215985452, which is 104702 XIDs ahead of previous value

index scan needed: 33412 pages from table (50.03% of total) had 1887056 dead item identifiers removed index "pgbench_accounts_pkey": pages: 10970 in total, 0 newly deleted, 0 currently deleted, 0 reusable I/O timings: read: 2668.125 ms, write: 935.198 ms

avg read rate: 13.761 MB/s, avg write rate: 14.561 MB/s buffer usage: 83992 hits, 94033 misses, 99499 dirtied

WAL usage: 173015 records, 77548 full page images, 328276128 bytes system usage: CPU: user: 1.90 s, system: 1.58 s, elapsed: 53.38 s

Статистика о работе очистки содержит массу информации, и, если проанализировать статистику за продолжительный период, наверняка можно сделать интересные наблюдения и выводы. В приведенном примере нас интересует последняя строка, где отмечено, что выполнение очистки заняло 53,38 секунды. Таким образом, анализируя поток журнала, можно отследить все очистки, выполнявшиеся дольше log_autovacuum_min_duration, в отличие от обращений к pg_stat_activity, где приходится полагаться на удачу. Однако не стоит злоупотреблятьислишкомсильноуменьшатьзначениеlog_autovacuum_min_duration,посколькувсистемах с большой активностью и большим количеством таблиц может выполняться огромное количество очисток,что приведет к существенному объему записи в журнал сообщений.

Представление pg_stat_progress_vacuum

Представление pg_stat_progress_vacuum содержит подробную информацию о работе процессов очистки и позволяет оценить ход их выполнения. Каждая строка в представлении описывает отдельный процесс, который идет в данный момент. Если выполняющихся процессов очистки нет,то и в представлении не будет ни одной строки.

pid—идентификатор процесса в операционной системе;

datid, datname — идентификатор и имя базы данных, с которой установлено соединение

ив которой в данный момент выполняется очистка таблиц и индексов;

relid—идентификатор таблицы,для которой в данный момент выполняется очистка;

phase—фаза выполнения очистки:

initializing—инициализация и подготовка к работе;

scanning heap—сканированиетаблицы,можетвключать в себя очистку,дефрагментацию страниц и заморозку строк;

vacuuming indexes — обработка индексов, может выполняться несколько раз (в случае нехватки autovacuum_work_mem или maintenance_work_mem);

vacuuming heap — обработка таблиц, отличается от сканирования тем, что выполняется каждый раз после обработки индексов (сначала в индексах удаляются указатели

218

Глава 8. Очистка

на строки, затем в таблице удаляются непосредственно сами версии строк, отмеченные указателями);

cleaning up indexes — окончательная обработка индексов, выполняется после завершения полного сканирования таблицы и очистки как таблицы,так и ее индексов;

truncating heap — усечение файла таблицы и высвобождение свободных страниц с целью вернуть место операционной системе;

performingfinalcleanup—окончательнаяочистка,обновлениекартысвободногопро- странства,обновление статистики в pg_class и т. п.,завершение работы;

heap_blks_total — общее количество блоков в таблице на момент начала работы; блоки, добавленные в процессе очистки,не учитываются;

heap_blks_scanned — общее количество просканированных блоков. Для оптимизации сканирования используется карта видимости, и часть блоков может быть пропущена без проверки, но пропущенные блоки также учитываются в этом поле и в конечном счете heap_blks_scanned сравняется с heap_blks_total;

heap_blks_vacuumed — общее количество блоков, которые были очищены от устаревших версий строк. Если в таблице нет индексов, этот счетчик увеличивается только в фазе vacuuming heap. Блоки, не содержащие мертвых строк, пропускаются, так что счетчик может увеличиваться большими рывками;

index_vacuum_count—общее количество завершенных циклов очистки индексов;

max_dead_tuples—количество указателей на устаревшие версии строк,которые можно по-

местить в рабочую память (autovacuum_work_mem, maintenance_work_mem). Когда рабочая память заканчивается,выполняется цикл очистки индексов;

num_dead_tuples — количество указателей на устаревшие версии строк, собранных в рабочей памяти с момента завершения последнего цикла очистки индексов.

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

# SELECT * FROM pg_stat_progress_vacuum;

-[ RECORD 1 ]------

+---------------------------------------------------

pid

| 2688928

datid

| 16437

datname

| pgbench

relid

| 16462

phase

| vacuuming heap

heap_blks_total

| 66788

heap_blks_scanned

| 66788

heap_blks_vacuumed

| 30540

index_vacuum_count

| 1

max_dead_tuples

| 11184809

num_dead_tuples

| 1921611

8.5. Отслеживание активных процессов очистки

219

В выводе присутствуют идентификаторы и значения в блоках, менее привычные, чем обычные байты. Для удобства к запросу можно добавить информацию из pg_stat_activity, а поля pg_stat_progress_vacuum привести к более привычному для восприятия виду:

# SELECT p.pid,

now() - a.xact_start AS duration, wait_event_type ||'.'|| wait_event AS wait_event, CASE

WHEN a.query ~ '^autovacuum.*to prevent wraparound' THEN 'wraparound' WHEN a.query ~ '^vacuum' THEN 'user'

ELSE 'regular' END AS mode, p.datname AS database,

p.relid::regclass AS table, p.phase,

pg_size_pretty(p.heap_blks_total * current_setting('block_size')::int) AS table_size, pg_size_pretty(pg_total_relation_size(relid)) AS total_size, pg_size_pretty(p.heap_blks_scanned * current_setting('block_size')::int) AS scanned, round(100.0 * p.heap_blks_scanned / p.heap_blks_total, 1) AS scanned_pct, pg_size_pretty(p.heap_blks_vacuumed * current_setting('block_size')::int) AS vacuumed, round(100.0 * p.heap_blks_vacuumed / p.heap_blks_total, 1) AS vacuumed_pct, p.index_vacuum_count,

round(100.0 * p.num_dead_tuples / p.max_dead_tuples,1) AS work_mem_usage FROM pg_stat_progress_vacuum p

JOIN pg_stat_activity a ON a.pid = p.pid

ORDER BY now() -

a.xact_start DESC;

-[ RECORD 1 ]------+---------------------------------------------------

pid

| 2688928

duration

| 00:00:52.050535

wait_event

| Timeout.VacuumDelay

mode

| regular

database

| pgbench

table

| pgbench_accounts

phase

| vacuuming heap

table_size

| 522 MB

total_size

| 608 MB

scanned

| 522 MB

scanned_pct

| 100.0

vacuumed

| 239 MB

vacuumed_pct

| 45.7

index_vacuum_count

| 1

work_mem_usage

| 17.2

Теперь в полученном результате есть четкие ответы:

выполняется обработка таблицы pgbench_accounts;

обработка текущей таблицы длится 52 секунды;

в данный момент выполняется штатная пауза между обработкой блоков (wait_event = Timeout.VacuumDelay);

220Глава 8. Очистка

mode = regular указываетнато,что это обычная автоочистка (не связанная с обслуживанием счетчика транзакций и не вызванная пользователем);

размер таблицы 522 МБ,вместе с индексами—608 МБ;

значение scanned_pct = 100.0% говорит о том, что таблица полностью просканирована на предмет мертвых строк и выполняется непосредственно очистка (phase = vacuuming heap);

vacuumed_pct = 45.7% указывает на то,что очистка выполнена почти наполовину;

рабочая память заполнена на 17.2% (work_mem_usage) и уже был выполнен один цикл об-

работки индексов (index_vacuum_count = 1).

Если снова провести полное обновление таблицы pgbench_accounts,а в соседнем сеансе запустить запрос с помощью \watch 1, можно будет наглядно наблюдать за тем, как выполняется очистка. Однако такой запрос и выводимая статистика больше подходят для текущей оценки происходящего,собиратьтакую информацию в мониторинг не имеет особого смысла.

Резюме

Механизм конкурентного доступа допускает существование нескольких версий одной

итой же строки.

Жизненный цикл строк подразумевает существование живых и мертвых версий.

Мертвые версии строки необходимо регулярно вычищать.

Очистка выполняется как для таблиц,так и для индексов.

Автоочисткавыполняется,когдаколичествомертвыхверсийстрокпревышаетопределенный порог.

Очистка создаетдополнительный ввод-вывод и может влиять на производительность.

Администратору важно отслеживать работу очистки в СУБД.

Автоочистка должна запускаться без задержек.

Автоочистка обслуживает счетчик транзакций и обеспечивает постоянный запас свободных идентификаторов транзакций.

Администратору важно отслеживать запас доступных идентификаторов транзакций.

При неблагоприятном стечении обстоятельств запас идентификаторов может оказаться исчерпанным,что приведет к остановке нормальной работы СУБД.

Неэффективная работа очистки может приводить к эффекту раздувания.

Следствиемраздуванияявляютсянеэффективноеиспользованиедисковогопространства

иснижение производительности.

Для оценки степени раздувания используется расширение pgstattuple.

Для отслеживания активных процессов очистки могут использоваться представления pg_stat_activity и pg_stat_progress_vacuum.

Соседние файлы в папке Books