- •Предисловие
- •Об этой книге
- •Глава 1. Обзор статистики
- •Внутреннее устройство PostgreSQL
- •Установка соединений и работа сеансов
- •Запросы как базовая единица рабочей нагрузки
- •Планирование и выполнение запросов
- •Ввод-вывод при выполнении запросов
- •Журнал сообщений СУБД
- •Репликация изменений
- •Архивирование журнала предзаписи
- •Фоновая синхронизация данных
- •Автоочистка
- •Интерфейс статистики
- •Статистика как отправная точка инструментов мониторинга
- •Особенности статистики
- •Тестовое окружение
- •Глава 2. Статистика активности
- •Ключ к пониманию происходящего в СУБД
- •Взаимодействие клиента и сервера
- •Источники информации об активности
- •Представление pg_stat_activity
- •Представление pg_locks
- •Особенности pg_stat_activity и pg_locks
- •Представление pg_stat_database
- •Подключенные клиенты
- •Отслеживание клиентских сеансов
- •Транзакционная активность
- •Статусы завершения сеансов
- •Состояния сеансов
- •Отслеживание состояний
- •Ожидания и блокировки
- •Отслеживание состояний с учетом ожиданий
- •Взаимоблокировки
- •Бездействующие транзакции
- •Время выполнения запросов и транзакций
- •Отслеживание времени ожидания блокировок
- •Использование pg_locks.waitstart
- •Использование pg_stat_activity.state_change
- •Дерево блокировок
- •Глава 3. Выполнение запросов и функций
- •Зачем нужен мониторинг запросов
- •Расширение pg_stat_statements
- •Метаданные запроса
- •Планирование запроса
- •Исполнение запроса
- •Сквозная идентификация с queryid
- •Построение отчетов на основе pg_stat_statements
- •Представление pg_stat_statements_info
- •Выполнение процедур и функций
- •Глава 4. Базы данных
- •Иерархия объектов СУБД
- •Кластер баз данных
- •Табличные пространства
- •Базы данных
- •Схемы
- •Таблицы и индексы
- •TOAST
- •События в кластере баз данных
- •Рабочая нагрузка в отношении таблиц и индексов
- •Ошибки и нежелательные события
- •Функции для работы с объектами СУБД
- •Определение размеров объектов СУБД
- •Размещение объектов в файловой системе
- •Глава 5. Область общей памяти и ввод-вывод
- •Анализ общей памяти
- •Представление pg_buffercache
- •Представление pg_shmem_allocations
- •Анализ памяти клиентских процессов
- •Оценка использования SLRU-кешей
- •Ввод-вывод в контексте объектов СУБД
- •Базы данных
- •Ввод-вывод в контексте выполнения запросов
- •Временные файлы
- •Уровень баз данных
- •Ввод-вывод при выполнении запросов
- •Отслеживание в журнале сообщений
- •Отслеживание активных временных файлов
- •Ввод-вывод фоновых процессов
- •Глава 6. Журнал упреждающей записи
- •Отслеживание активности в журнале
- •Представление pg_stat_wal
- •Представление pg_stat_statements
- •Архивирование журнала
- •Представление pg_stat_archiver
- •Очередь архивирования
- •Глава 7. Репликация
- •Обзор репликации
- •Инструменты отслеживания репликации
- •Представление pg_stat_replication
- •Представление pg_stat_wal_receiver
- •Cлоты репликации и pg_replication_slots
- •Публикации и подписки
- •Конфликты восстановления
- •Глава 8. Очистка
- •Введение в очистку
- •Особенности очистки на практике
- •Когда выполняется автоочистка?
- •Статистика выполнения очистки
- •Счетчик транзакций и предотвращение ошибок, связанных с его зацикливанием
- •Раздувание таблиц и индексов
- •Отслеживание активных процессов очистки
- •Представление pg_stat_activity
- •Представление pg_stat_progress_vacuum
- •Глава 9. Ход выполнения операций
- •Представление pg_stat_progress_analyze
- •Представление pg_stat_progress_basebackup
- •Представление pg_stat_progress_cluster
- •Представление pg_stat_progress_create_index
- •Представление pg_stat_progress_copy
- •Предметный указатель
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.
