- •Предисловие
- •Об этой книге
- •Глава 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
- •Предметный указатель
3.3. Метаданные запроса |
75 |
Перечисленные параметры можно указатьв основной конфигурации,в файлеpostgresql.conf, и для вступления в силу большинства из них достаточно перечитать конфигурацию (для изменения pg_stat_statements.max требуется перезапуск).
Больше подробностей, относящихся к работе расширения, можно найти в официальной документации1.
Всю статистику в pg_stat_statements можно условно разделить на несколько категорий:
•запрос и его метаданные;
•статистика планирования (доступна с PostgreSQL 13 и pg_stat_statements 1.8);
•статистика выполнения;
•статистика использования ресурсов—здесь речь идет об использовании ресурсов с точки зрения СУБД, а с точки зрения операционной системы она может иметь несколько иной вид,о чем я упомяну отдельно;
•статистика записи в WAL-журнал (доступна с PostgreSQL 13 и pg_stat_statements 1.8);
•статистика JIT-компилятора (доступна с PostgreSQL 15 и pg_stat_statements 1.10).
Можно заметить,что разная статистика появляется в разных версиях расширения.При обновлениях основной версии СУБД следуеттакже обновлять и расширения.
В следующих разделах мы шаг за шагом рассмотрим все категории статистики.
3.3. Метаданные запроса
Текст запроса и его метаданные позволяют отличать одни запросы от других и дают отправную точку поиска приложения,отправившего запрос.Запрос и его метаданные представлены несколькими полями:
•userid — идентификатор пользователя, от имени которого был выполнен запрос. Имя можно найти с помощью соединения с pg_user или функцией pg_get_userbyid;
•dbid — идентификатор базы данных, в которой был выполнен запрос. Имя можно найти с помощью соединения с pg_database. Функция для получения имени базы данных идентификатору отсутствует;
•queryid— идентификатор запроса, вычисляемый на основе его текста. На него не влияют имя пользователя или базы, и если аналогичный запрос выполняется в других базах или другими пользователями,то значения queryid для таких запросов будут совпадать;
•query— нормализованный текст запроса. Нормализация объединяет множество однотипных запросов с разными значениями параметров в один общий тип запроса,где конкретные значения заменены пронумерованными аргументами;
1 postgrespro.ru/docs/postgresql/current/pgstatstatements.html
76Глава 3. Выполнение запросов и функций
•toplevel—уровеньвызова запроса: trueдля вызовов верхнего уровня и false,если вызов былвложенвпроцедуруилифункцию.Еслиpg_stat_statements.track установленвзначение top, поле всегда равно true. При создании отчетов производительности этот флаг позволяет отфильтровать вложенные вызовы и не учитывать их статистику, поскольку она уже учтена в статистике запросов верхнего уровня.Без использования этого флага статистика может быть посчитана несколько раз,и отчет получится неверным.
Спомощью метаданных появляется возможностьвыделитьи сгруппироватьстатистику по отдельным пользователям,базам данных или группам:
#SELECT pg_get_userbyid(s.userid) AS username, d.datname, count(*) FROM pg_stat_statements s, pg_database d
WHERE s.dbid = d.oid
GROUP BY 1,2 ORDER BY 3 DESC;
username |
| datname |
| count |
|
---------- |
+---------- |
+ |
------- |
stats |
| postgres | |
31 |
|
pgbench |
| pgbench |
| |
12 |
stats |
| pgbench |
| |
10 |
maru |
| pgbench |
| |
9 |
classic |
| pgbench |
| |
9 |
serral |
| pgbench |
| |
9 |
postgres |
| postgres | |
6 |
|
3.4. Планирование запроса
Планирование — это отдельный этап, предшествующий выполнению запроса. На этом этапе планировщик рассматривает набор планов, которые могут отличаться сложностью исполнения и стоимостью (cost) — оценкой количества вычислительных ресурсов, необходимых для выполнения запроса.Стоимость измеряется в условных единицах,за базу принята стоимость чтения одной страницы при последовательном доступе. Среди построенных планов выбирается наиболее оптимальный, то есть имеющий наименьшую стоимость, согласно которому и будет выполнен запрос. В общем случае план зависит от сложности запроса, наличия подходящих индексов, настроек планировщика и того, насколько статистика соответствует реальным данным. Статистика планирования в pg_stat_statements позволяет отслеживать количество планирований и общее время, затраченное на планирование. Однако, как уже замечено, по умолчанию сбор статистики планирования выключен ввиду возможного снижения производительности при видах рабочей нагрузки,схожих с OLTP.
Статистика планирования в pg_stat_statements представлена следующими полями:
•plans—количество планирований запроса;
•total_plan_time—общее время,затраченное на планирование запросов данного типа;
3.4. Планирование запроса |
77 |
•min_plan_time—наименьшая продолжительность планирования;
•max_plan_time—наибольшая продолжительность планирования;
•mean_plan_time—средняя продолжительность планирования;
•stddev_plan_time—величинастандартногоотклонениядлявремени,затраченногонапла- нирование.
Все значения времени указываются в миллисекундах.
Наибольший интерес в этой статистике вызывают время планирования и факты его значительных изменений, особенно в бóльшую сторону, когда запрос стал планироваться дольше при более или менее постоянном количестве планирований. Такое случается на практике, но, к счастью,это большая редкость.
Сценариевиспользованиястатистикипланированиянетакмного,отправнымиточкамимогут служить следующие варианты:
•время планирования отдельных типов запросов может быть полезно для отслеживания аномалий планирования в случаях,когда объем выполняемых запросов не изменяется;
•величина стандартного отклонения показывает, насколько сильно время планирования «гуляет» относительно среднего времени планирования.
Давайте рассмотрим в качестве примера первый вариант. Для этого нам потребуется следующий запрос:
#topk_avg(5,
sum by (queryid,query) ( rate(postgres_statements_time_seconds_total{
service_id="primary",mode="planning"
}[1m]) + on(database,user,queryid) group_left(query)
0 * postgres_statements_query_info{service_id="primary"} ), "other")
Подобные запросы будут и дальше использоваться в этой главе, поэтому его стоит детально разобрать:
•в качестве основной величины берется некоторая конкретная метрика, в данном случае это postgres_statements_time_seconds_total;
•относительно этой метрики считается частота изменений в минуту;
•для получения метки с текстом запроса (query) выполняется соединение с метрикой postgres_statements_query_info на основе общих меток database,user,queryid;
•величина postgres_statements_query_info равна единице, поэтому умножаем ее на ноль, чтобы не прибавлять лишнюю единицу к величине основной метрики;
•полученные метрики с частотой изменения суммируются с группировкой по меткам queryid и query, поскольку в тестовом окружении есть несколько пользователей, которые совместно выполняют одни и те же запросы;
78 |
Глава 3. Выполнение запросов и функций |
•функция topk_avg считает средние величины за выбранный интервал временнóго ряда, сортируетихпоубываниюиберетпервыеK значений(вданномслучаепять),аостальные суммирует в шестую метрику с меткой other.
Полученный запрос выводит статистику по времени планирования (метка mode="planning") пяти запросов, которые планировались наиболее долго. Время планирования остальных запросов объединено в шестой метрике с меткой other.
На основе запроса можно построить так называемый график top-K (рис. 3.1), который будет довольно часто появляться на протяжении всей книги. Удобство этого графика заключается в том,что он позволяет вывести и наибольшие величины,и сумму оставшихся.
Рис. 3.1.Время планирования запросов
Каждая строка легенды содержит идентификатор и текст запроса, а также последнее и максимальноезначениеметрики.Длякаждоготипазапросовграфикпоказывает,сколькомашинного времениСУБДтратитнапланирование в однусекундуреальноговремени.В машинномвременисуммируетсяпродолжительностьработывсехядер,поэтомувнагруженныхсистемахсмногоядерными процессорами машинное время за одну реальную секунду легко может секунду превышать. График отображает изменение частоты именно суммарного времени планирования всех запросов конкретного типа, и эту особенность очень важно понимать. На графике отмечена конкретная точка — 18:30:00, и в эту секунду реального времени на планирование всех запросов всеми ядрами в сумме было затрачено около 16 миллисекунд (более подробная детализация приведена во всплывающей подсказке).
График времени планирования важно рассматривать вместе с графиком количества планирований на основе pg_stat_statements.plans.Поскольку величина затраченного времени прямо пропорциональна количеству планирований, при уменьшении (или увеличении) числа планирований затраченное времятакже уменьшится (или увеличится).Подозрительными можно считать случаи, когда время планирования изменилось, а количество планирований осталось прежним или вообще изменилось в обратную сторону.
