- •Предисловие
- •Об этой книге
- •Глава 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.2. Особенности очистки на практике |
197 |
всвою очередь,запускаетрабочий процесс autovacuum worker.Рабочий процесс очистки узнает имя целевой базы, подключается к ней и строит список таблиц, подлежащих обработке. Обрабатывая по очереди таблицы из списка, рабочий процесс сканирует их на предмет устаревших версий строк, не нужных ни одной из активных транзакций, и освобождает место как
всамих таблицах, так и в индексах. Освобожденное пространство может использоваться для вставкиновыхстрок.Есливходеочисткисвободноепространствообразовалосьвконцефайла таблицы,тоочисткаможетотсечьхвостовыепустыестраницы(truncateheap)итакимобразом уменьшить файл таблицы.
При некоторых видах рабочих нагрузок возникают случаи,когда втаблицах и индексах содержится относительно небольшое количество живых строк, а все остальное пространство освобождено и при этом не используется.Если при этом участки пустого пространства физически находятся в разных частях файла,то очистка не может высвободить эти участки и уменьшить сам файл.Процесс образования таких участков и их постепенное увеличение называют раздуванием (bloat). В самом безобидном случае следствием эффекта раздувания является впустую занимаемое пространство, а в худшем — снижение производительности ввода-вывода из-за избыточных операций, нехватки буферного кеша и снижения эффективности индексного доступа из-за образования лишних уровней у индексов. Поэтому при эксплуатации СУБД необходимо отслеживать излишнее раздувание таблиц и индексов и сокращать его.
Подводя некоторый итог,можно сказать,что с точки зрения эксплуатации администратор БД должен отслеживать эффективность работы автоочистки, создаваемый ею уровень нагрузки
идолю мертвых строк в таблицах, и при необходимости корректировать настройки очистки
иуменьшать образовавшееся раздувание.
В современных реалиях с ростом производительности систем хранения важность отслеживания уровня нагрузки от очистки сильно уменьшилась. Если раньше, в эпоху HDD-дисков, это было актуально, поскольку очистка могла значительно влиять на производительность запросов, то сейчас, при использовании SSD- и NVMe-носителей, это негативное влияние сильно уменьшилось или вообще сошло на нет.
8.2. Особенности очистки на практике
Чтобы получить представление о том, что именно следует отслеживать в работе очистки, давайте рассмотрим практические особенности ее работы. Очистка запускается только при наступлении определенных событий,и в идеале не должна запаздывать.Но в случае запаздывания важно представлять себе объем накопившейся работы.
Когда выполняется автоочистка?
Автоочистка обрабатывает таблицу, когда объем мертвых строк в ней превышает некоторое допустимое количество. Устаревшие версии строк появляются из-за обновлений и удалений;
198Глава 8. Очистка
при выполнении этих операций количество устаревших версий постоянно отслеживается, и, как только оно превыситдопустимое значение,таблица добавляется в список на обработку. Предельное значение вычисляется на основании следующей информации:
•pg_class.reltuples — общее количество строк в таблице согласно последнему выполнению очистки;
•pg_stat_all_tables.n_dead_tup — общее количество мертвых строк, которое обновляется при операциях обновления и удаления;
•autovacuum_vacuum_threshold — параметр, определяющий базовое пороговое значение, то есть минимальное количество мертвых строк в таблице, необходимое для ее очистки (по умолчанию 50 строк);
•autovacuum_vacuum_scale_factor — параметр, определяющий долю общего числа строк, на которую увеличивается базовое пороговое значение autovacuum_vacuum_threshold (по умолчанию 0,2,что означает 20% от pg_class.reltuples).
Согласно значениям по умолчанию, для срабатывания автоочистки количество мертвых строк в таблице должно превышать 50 + 20% от общего числа строк. Значение параметра autovacuum_vacuum_scale_factor = 0.2 часто воспринимается как консервативное и в современных конфигурациях принято указывать меньшее значение в диапазоне от 0,01 до 0,05, тем самым вызывая автоочистку чаще и при гораздо меньшем количестве мертвых строк. Для очень больших таблиц (с большими индексами) даже небольшое значение параметра autovacuum_vacuum_scale_factor припереводев строкиможетоказатьсябольшим,и рабочейпамяти может не хватитьдля размещения всех указателей на мертвые строки.Это очень сильно повышаетстоимостьпроцедурыочистки,таккакприэтомприходитсяполностьюсканировать иочищатьиндексынесколькораз.Втакихслучаяхдляотдельныхтаблицможноустанавливать индивидуальные параметры очистки с помощью параметров хранения1.
Теперь,знаяусловиесрабатыванияавтоочистки,можнонаписатьзапросдляопределениятаблиц, у которых количество мертвых строк превышает допустимое значение. Запрос выводит список пользовательских таблиц с некоторой статистикой:
•relation—имя таблицы.При желании можно вывести также имя схемы;
•reltuples—приблизительное количество строк втаблице.Это значение обновляется каждый раз после выполнения автоочистки,команд VACUUM,ANALYZE и некоторых DDL-команд вроде CREATE INDEX;
•live_tup—количество живых строк в таблице;
•dead_tup—количество устаревших,мертвых строк в таблице;
•boundary—допустимое количество мертвых версий строк.Когда количество мертвых версий превысит это значение,таблица должна обработаться автоочисткой;
•av_cnt—общее количество выполненных операций автоочистки на таблице;
•since_last_av—время,прошедшее с момента выполнения последней автоочистки;
1 postgrespro.ru/docs/postgresql/current/sql-createtable#SQL-CREATETABLE-STORAGE-PARAMETERS
8.2. Особенности очистки на практике |
199 |
•av_need—признактого,что количество мертвых версий превышаетдопустимое значение и таблице требуется обработка;
•dead_ratio — процентное отношение количества мертвых версий к общему числу строк в таблице.
#SELECT
*, |
|
|
|
|
|
|
|
|
|
|
av.dead _ tup > av.boundary AS av_need, |
|
|
|
|
|
|
||||
CASE WHEN reltuples > 0 |
|
|
|
|
|
|
|
|
||
THEN round(100.0 * av.dead_tup / reltuples) |
|
|
|
|
|
|||||
ELSE 0 |
|
|
|
|
|
|
|
|
|
|
END AS n _ dead _ratio |
|
|
|
|
|
|
|
|
||
FROM |
|
|
|
|
|
|
|
|
|
|
(SELECT |
|
|
|
|
|
|
|
|
|
|
c.relname AS relation, |
|
|
|
|
|
|
|
|
||
c.reltuples AS reltuples, |
|
|
|
|
|
|
|
|||
pg _ stat _ get_live_tuples(c.oid) AS live_tup, |
|
|
|
|
|
|||||
pg _ stat _ get_dead_tuples(c.oid) AS dead_tup, |
|
|
|
|
|
|||||
round(current_setting('autovacuum_vacuum_threshold')::integer + |
|
|
|
|
||||||
current_setting('autovacuum_vacuum_scale_factor')::numeric * c.reltuples |
|
|
|
|||||||
) AS boundary, |
|
|
|
|
|
|
|
|
|
|
pg _ stat _ get_autovacuum_count(c.oid) AS av_cnt, |
|
|
|
|
|
|||||
now() - pg _stat_get_last_autovacuum_time(c.oid) AS since_last_av |
|
|
|
|||||||
FROM pg _ class c |
|
|
|
|
|
|
|
|
|
|
LEFT JOIN pg _namespace n ON (n.oid = c.relnamespace) |
|
|
|
|
|
|||||
WHERE c.relkind = 'r' |
|
|
|
|
|
|
|
|
||
AND n.nspname NOT IN ('pg_catalog', 'information_schema') |
|
|
|
|
||||||
) AS av |
|
|
|
|
|
|
|
|
|
|
ORDER BY av _ need, dead_tup DESC; |
|
|
|
|
|
|
|
|||
relation |
| |
reltuples |
| live_tup | dead_tup | boundary | av_cnt | since_last_av |
| av_need | dead_ratio |
||||||
------------------ |
+-------------- |
|
+ |
----------+ |
----------+---------- |
+-------- |
+----------------- |
+--------- |
+ |
------------ |
pgbench _ accounts | 1.998889e+06 | |
1998889 | |
161911 | |
399828 | |
0 | |
| f |
| |
8 |
|||
pgbench _ history |
| |
957729 | |
973640 | |
0 | |
191596 | |
114 | 01:02:37.853934 |
| f |
| |
0 |
|
pgbench _ tellers |
| |
200 | |
200 | |
1361 | |
90 | |
2849 | 00:00:36.65028 |
| t |
| |
680 |
|
pgbench _ branches | |
|
20 | |
20 | |
1160 | |
54 | |
2849 | 00:00:36.660004 | t |
| |
5800 |
||
По результатам запроса можно сделать несколько наблюдений:
•есть две таблицы (pgbench_tellers и pgbench_branches), которым требуется очистка: количество мертвых версий в них существенно превышает допустимое значение, о чем говорит признак av_need = t;
•значения av_cnt и since_last_av показывают, что две эти таблицы регулярно очищаются, ноприсложившейсярабочейнагрузкедоследующегозапускаочисткивтаблицахуспевает накопиться большое количество мертвых версий (см. dead_ratio);
•для оценки значения since_last_av важно знатьзначение параметра autovacuum_naptime1 (по умолчанию одна минута). Этот параметр определяет интервал, с которым процесс
1 postgrespro.ru/docs/postgresql/current/runtime-config-autovacuum#GUC-AUTOVACUUM-NAPTIME
200 |
Глава 8. Очистка |
autovacuum launcher отправляет сигнал на запуск рабочих процессов очистки в каждую базуданных.Ввыводезапросаестьдветаблицыспризнакомнеобходимостиочистки.Значенияsince_last_avдляэтихдвухтаблицукладываютсявминуту:этозначит,чтотаблицы хотьидолжны бытьобработаны,но задержки при этом нет.И наоборот,если бы при наличии признака очистки значение since_last_av превышало значение autovacuum_naptime, это указывало бы на то,что очистка опаздывает;
•есть таблица с большим количеством строк, которая при этом ни разу не подвергалась обработке (pgbench_accounts), поскольку объем мертвых строк ни разу не достигал порогового значения.
Можно сделать вывод: в тестовом окружении не так много таблиц,и автоочистка справляется со своей работой.
Дополнительно стоит отметить, как вычисляется допустимое значение (boundary). За основу берутсяобщиепараметрыконфигурации,однакоСУБДпредоставляетвозможностьуказывать эти параметры индивидуальнодля отдельныхтаблиц с помощьютак называемых параметров хранения (storage parameter)1.Они имеют приоритет перед общими параметрами конфигурации,иихследуетучитыватьприрасчетепороговогозначения.Втестовомокруженииутаблиц нет явно определенных параметров хранения,поэтому запрос их не учитывает.
Статистика выполнения очистки
В ранее рассмотренном запросе была использована функция pg_stat_get_autovacuum_count, которая возвращает количество обработок таблицы автоочисткой. Эта и еще несколько похожих функций используются в представлении pg_stat_all_tables, на котором также основаны представления pg_stat_user_tables и pg_stat_sys_tables.На основе этих функций в представленияхотображаютсянесколькополей,указывающихнаработукакавтоматической,такиручной очистки:
•last_vacuum—время,когда таблица в последний раз очищалась командой VACUUM;
•last_autovacuum—время,когда таблица в последний раз была обработана автоочисткой;
•vacuum_count—общее количество обработок таблицы командой VACUUM;
•autovacuum_count—общее количество обработок таблицы автоочисткой.
Сбор статистики для планировщика
Набор похожих полей естьидля операций сбора статистики планировщика.Сбор статистики можетвыполнятьсялибо с помощью вызова команды ANALYZE,либо какдополнительная операция при вызове команды VACUUM (с указанием параметра ANALYZE),либо рабочим процессом автоочистки.
1 postgrespro.ru/docs/postgresql/current/sql-createtable#SQL-CREATETABLE-STORAGE-PARAMETERS
8.2. Особенности очистки на практике |
201 |
Следующий запрос позволяет отслеживать регулярность очистки:
# SELECT |
|
|
|
|
|
|
|
schemaname ||'.'|| relname AS relation, |
|
|
|
||||
vacuum_count AS vacuum, |
|
|
|
|
|
|
|
now() - last_vacuum AS since_last_vacuum, |
|
|
|
||||
autovacuum_count AS autovacuum, |
|
|
|
|
|||
now() - last_autovacuum AS since_last_autovacuum |
|
|
|
||||
FROM pg_stat_user_tables; |
|
|
|
|
|
|
|
relation |
| vacuum | |
since_last_vacuum | autovacuum | since_last_autovacuum |
|||||
------------------------- |
+-------- |
|
+ |
------------------- |
+ |
------------ |
+----------------------- |
public.pgbench_tellers |
| |
5 |
| |
07:54:41.804464 |
| |
2869 |
| 00:00:29.026952 |
public.pgbench_branches |
| |
5 |
| |
07:54:41.805567 |
| |
2869 |
| 00:00:29.035908 |
public.pgbench_history |
| |
0 |
| |
|
| |
114 |
| 01:22:30.721539 |
public.pgbench_accounts |
| |
0 |
| |
|
| |
0 |
| |
Ввыводезапросаотраженастатистикаипоручным,ипоавтоматическимочисткам.Основная работа по очистке выполняется автоочисткой, и изредка выполняется команда VACUUM (специфика рабочей нагрузки).
Собрав статистику выполнения операций очистки со всех БД,можно получитьобщую картину по всему экземпляру и вывести ее в мониторинг (рис. 8.1):
Рис. 8.1.Частота выполнения операций очистки и анализа
График на рис. 8.1 показывает количество операций очистки и анализа, выполненных в течение пяти минут. За показанные сутки количество операций держится на одном уровне без больших колебаний, однако можно заметить некоторую цикличность с интервалом 10 часов. В случае корректировок настроек автоочистки такой график помогает понять, как сделанные изменения отразились на ее работе. Значительные изменения в рабочей нагрузке, особенно связанные с объемом записи,также могут повлиять на частоту выполнения служебных операций,и последствия этих изменений также будут заметны на графике.
