12 Занятие 12: Производительность / Анализ производительности
Эта страница извлечена из официального PDF в нативный Markdown. Текст слайдов, код и комментарии сохранены в порядке чтения; исходные PDF и HTML остаются эталоном макета. HTML source: pgpro_12_perfanalysis.html Archive: PGPRO-handouts-16.zip Страниц PDF: 26
Page 1: Производительность / Анализ производительности
Авторские права
© Postgres Professional, 2023–2026 Авторы: Алексей Береснев, Илья Баштанов, Павел Толмачев, Игорь Гнатюк Фото: Олег Бартунов (монастырь Пху и пик Бхрикути, Непал)
Использование материалов курса
Некоммерческое использование материалов курса (презентации, демонстрации) разрешается без ограничений. Коммерческое использование возможно только с письменного разрешения компании Postgres Professional. Запрещается внесение изменений в материалы курса.
Обратная связь
Отзывы, замечания и предложения направляйте по адресу: edu@postgrespro.ru
Отказ от ответственности
Компания Postgres Professional не несет никакой ответственности за любые повреждения и убытки, включая потерю дохода, нанесенные прямым или непрямым, специальным или случайным использованием материалов курса. Компания Postgres Professional не предоставляет каких-либо гарантий на материалы курса. Материалы курса предоставляются на основе принципа «как есть» и компания Postgres Professional не обязана предоставлять сопровождение, поддержку, обновления, расширения и изменения.
Page 2: Темы
- Расширение pgpro_stats
- Агрегированная статистика
- Дополнительные метрики
- Статистика очистки
- Статистика аннулирования кеша
- Трассировка сеансов
Page 3: Расширение pgpro_stats
Статистика запросов
- затраченные ресурсы, планы и события ожиданий
- Основные настройки
- pgpro_stats.max = 5000
- предел количества запросов
- pgpro_stats.track = top
- верхний уровень или все (all)
- pgpro_stats.query_sample_rate = 1.0
- размер выборки (доля запросов)
- pgpro_stats.enable_profile = true
- профиль ожиданий
- pgpro_stats.profile_period = 10 ms
- период семплирования
- Представление pgpro_stats_statements
Комментарии преподавателя
Расширение pgpro_stats собирает статистику по выполняемым операторам. По сравнению с pg_stat_statements добавлен сбор данных о планах запросов и событиях ожидания для каждого типа запроса. Расширения pgpro_stats и pg_stat_statements несовместимы.
Статистика доступна через представление pgpro_stats_statements, максимальное число строк в нем определяет параметр pgpro_stats.max. Значение по умолчанию — 5000.
Параметр pgpro_stats.track определяет, будут отслеживаться лишь только непосредственно выполненные команды SQL (значение top — по умолчанию), или также и вложенные операторы (значение all).
Для снижения нагрузки можно уменьшить размер выборки, заданный параметром pgpro_stats.query_sample_rate. Тогда для вычисления статистики будет случайно выбираться заданная доля запросов.
Семплинг событий ожидания выполняется с периодичностью раз в pgpro_stats.profile_period единиц времени (10 мс по умолчанию), если установлен параметр pgpro_stats.enable_profile.
Статистика ожиданий доступна в поле pgpro_stats_statements.wait_stats типа jsonb. Все показатели представлены в миллисекундах и кратны параметру конфигурации pgpro_stats.profile_period.
Также собирается информация о затраченных ресурсах с точки зрения операционной системы с помощью вызова rusage:
https://postgrespro.ru/docs/enterprise/16/pgpro-stats#PGPRO-STATS-RUSA GE
Page 4: Агрегированная статистика
Статистика запросов, агрегированная по объектам
- весь кластер, база данных, пользователь, адрес, приложение, процесс
- Основные настройки
- pgpro_stats.track_totals = on
- pgpro_stats.track_cluster, pgpro_stats.track_databases и т. п.
- pgpro_stats.max_totals = 1000
- предел количества объектов
- Представление pgpro_stats_totals
Комментарии преподавателя
Модуль pgpro_stats позволяет агрегировать статистику запросов по различным объектам:
● cluster — весь кластер баз данных;
● database — отдельная база данных;
● user — пользователь;
● client_addr — адрес клиента;
● application — приложение;
● backend — обслуживающий процесс;
● session — сеанс.
Необходимость агрегации по конкретному типу объекта настраивается параметрами pgpro_stats.track_cluster, pgpro_stats.track_databases и т. п.
Агрегированная статистика доступна в представлении pgpro_stats_totals. Каждая строка в этом представлении содержит значения по конкретному объекту. Количество объектов, по которым отслеживается статистика, ограничено параметром pgpro_stats.max_totals (по умолчанию — 1000). Когда количество объектов превышает заданное, информация о наименее активно используемых объектах удаляется.
Page 5: Сбор статистики по операторам и планам
Подключим разделяемую библиотеку pgpro_stats. При наличии других загружаемых библиотек pgpro_stats должна указываться в списке параметра shared_preload_libraries последней.
Создадим тестовую базу данных на основе demo:
Для удобства настроим путь поиска:
В схеме bookings копия стандартной демобазы минимального размера.
Подключим расширение:
Выполним несколько запросов к таблице билетов tickets, предварительно добавив индекс по фамилиям пассажиров.
Пара запросов с параллельным последовательным сканированием таблицы.
Посмотрим, что накопилось в статистике операторов:
Page 6: Page 6
Два оператора, отличающиеся константами, объединены в одну запись. Поле calls показывает количество выполнений. В следующих запросах используется индексный доступ:
Теперь у нас два разных плана.
Page 7: Page 7
Для пользователя student получим агрегированную статистику по использованию некоторых системных ресурсов, а также по количеству выполненных запросов и событий ожидания.
Page 8: Page 8
В выводе этого запроса получены количество выполненных запросов, общее время выполнения запросов, а также несколько полей записи в столбце total_exec_rusage: reads — количество байтов, прочитанное из файловой системы; writes — количество байтов, записанное в файловую систему; user_time — время, потраченное на работу запроса в непривилегированном режиме (user space); system_time — время, потраченное на работу запроса на стороне ядра ОС (kernel space). Столбец total_exec_rusage составного типа pgpro_stats_rusage содержит статистику использования ресурсов на этапах планирования и выполнения запросов. Собранная статистика сбрасывается функцией pgpro_stats_statements_reset для заданного пользователя (userid), базы данных (dbid), запроса (queryid) или плана (planid). Если не указать ни один аргумент, будет очищена вся статистика:
Статистика по запросам удалена:
Агрегированная статистика для заданного типа и идентификатора объекта очищается функцией pgpro_stats_totals_reset. Например, сбросим агрегатную статистику по роли student:
Page 9: Page 9
После сброса статистики был только что выполнен единственный запрос. Поэтому queries_executed равно единице. Статистика по базе данных сохранилась, так как она не была стерта:
Page 10: Дополнительные метрики
Произвольные метрики на основе SQL-запросов
- собираются фоновыми рабочими процессами
- кольцевой буфер
- Основные настройки
- pgpro_stats.metrics_buffer_size = 16kB
- pgpro_stats.metrics_workers = 2
- pgpro_stats.metric_N_name
- имя метрики
- pgpro_stats.metric_N_query
- SQL-запрос
- pgpro_stats.metric_N_period = 1 min
- интервал сбора
- pgpro_stats.metric_N_db
- список баз данных
- pgpro_stats.metric_N_user
- пользователь
- Представление pg_stats_metrics
Комментарии преподавателя
Используя pgpro_stats, можно определить дополнительные метрики. Собираемые статистические данные будут накапливаться в кольцевом буфере (представление pgpro_stats_metrics) для последующей передачи их в систему мониторинга.
Это надежнее, чем опрос базы данных системой мониторинга, так как в случае прерывания соединения собранные данные не будут потеряны, а сохранятся в буфере и могут быть прочитаны позднее.
Для определения дополнительной метрики в конфигурацию СУБД необходимо поместить соответствующие параметры. Номер N в имени параметра служит уникальным идентификатором метрики, к которой будет применяться задаваемое значение; он должен быть положительным и уникальным среди всех метрик. Параметры:
● pgpro_stats.metric_N_name — имя метрики;
● pgpro_stats.metric_N_query — запрос для получения метрики;
● pgpro_stats.metric_N_period — периодичность измерений;
● pgpro_stats.metric_N_db — список баз данных;
● pgpro_stats.metric_N_user — пользователь, от имени которого будет собираться метрика. Пользователь должен иметь доступ к базе данных, в которой будет выполняться запрос для сбора метрики.
Обсуждение того, какие именно метрики имеет смысл собирать, выходит за рамки курса, но порекомендуем книгу Алексея Лесовского «Мониторинг PostgreSQL»: https://postgrespro.ru/education/books/monitoring
Page 11: Сбор дополнительных метрик
Предположим, что требуется раз в 30 секунд собирать количество выполнений контрольной точки по требованию. Запишем параметры в файл conf.d/metrics.conf в каталоге данных кластера и перезапустим СУБД.
Добавленная метрика — первая, поэтому N=1.
Заглянем в представление для дополнительных метрик:
Столбец value содержит результат запроса, вычисляющего метрику, в виде массива объектов jsonb. Здесь извлечен первый по порядку (нулевой) элемент, в котором по ключу checkpoints_req получено искомое значение. Поменяем сразу много строк, например, фамилии пассажиров во всех купленных авиабилетах:
Выполним контрольную точку и немного подождем.
В представлении pgpro_stats_metrics появится одна или несколько записей. Обратите внимание на значение checkpoints_req:
Удалим настройки дополнительных метрик:
Снова перезагрузим сервер.
Page 12: Статистика очистки
Собирается ядром Postgres Pro Enterprise
- Представления
- pg_stats_vacuum_database — очистка баз данных
- pg_stats_vacuum_tables — очистка таблиц текущей базы
- pg_stats_vacuum_indexes — очистка индексов текущей базы
Комментарии преподавателя
Представления pg_stats_vacuum_database, pg_stats_vacuum_tables и pg_stats_vacuum_indexes содержат статистику очистки, соответственно, баз данных, таблиц в текущей базе данных и индексов в ней. Все эти представления основаны на одноименных функциях и доступны без установки расширения pgpro_stats.
Данные собираются ядром Postgres Pro Enterprise: стандартный сборщик статистики расширен для получения этой дополнительной информации.
Отслеживается подробная информация на уровне страниц (в количественном и временнóм представлении) и журнальных записей.
Page 13: Статистика очистки
Выключим автоочистку для таблицы tickets:
Поскольку статистика по очистке собирается ядром СУБД, для ее сброса используется стандартная функция:
Статистика очистки для таблицы tickets отсутствует:
Вернем имена пассажиров к верхнему регистру и выполним очистку.
Немного ожидания… Снова проверим статистику очистки для таблицы tickets. Теперь статистика очистки собрана:
Page 14: Page 14
Вернем автоочистку для таблицы tickets:
Page 15: Аннулирование кешей
Сообщения об аннулировании метаданных измененных объектов в локальных кешах процессов
- Представления
- pgpro_stats_inval_status — состояние очереди сообщений
- pgpro_stats_statements
- pgpro_stats_totals
- счетчики сообщений для операторов
Комментарии преподавателя
Обслуживающие процессы кешируют метаданные объектов в своих локальных кешах. Когда процесс меняет метаданные объекта, нужно обновить информацию в кешах других обслуживающих процессов. Для этого процесс отправляет другим процессам сообщение аннулирования (Cache Invalidation), которое помещается в специальную очередь.
Обслуживающие процессы получают сообщения аннулирования из этой очереди. Если объект, для которого получено сообщение аннулирования, находится в кеше, его метаданные в кеше обновляются.
Когда обслуживающий процесс, добавляющий сообщения в очередь, сталкивается с пределом размера очереди, он удаляет сообщения, уже обработанные всеми обслуживающими процессами. Если какие-то обслуживающие процессы не успевают обрабатывать сообщения и задерживают очистку, им передается сигнал для сброса кеша.
В pgpro_stats значения большинства счетчиков сообщений аннулирования увеличиваются при генерации сообщений, а сообщения попадают в очередь после фиксации транзакции. При откате счетчики не уменьшаются, хотя сообщения при этом не попадают в очередь.
Представление pgpro_stats_inval_status содержит одну строку с текущим состоянием очереди аннулирования кеша. Представления pgpro_stats_statements и pgpro_stats_totals для каждого объекта показывают запись со счетчиками сообщений аннулирования кеша.
https://postgrespro.ru/docs/enterprise/16/pgpro-stats#PGPRO-STATS-CAC HE-INVALIDATION-METRICS
Page 16: Аннулирование кешей
Откроем новый сеанс и получим PID обслуживающего процесса:
Пока ни одного сообщения об аннулировании кеша нет:
Изменим, например, параметр хранения таблицы.
Сообщения об аннулировании кеша, сгенерированные текущим обслуживающим процессом:
Здесь: total — общее число сообщений аннулирования; catcache — число сообщений избирательного аннулирования кеша каталога; relcache — число сообщений избирательного аннулирования кеша отношений.
Page 17: Трассировка сеансов
Трассировка сеансов в журнал сообщений или файл
- Трассировка выполняется только для команд, удовлетворяющих критериям фильтрации
- pgpro_stats_trace_insert
- создает фильтр
- pgpro_stats_trace_update — изменяет фильтр
- pgpro_stats_trace_delete — удаляет фильтр
- pgpro_stats_trace_reset
- удаляет все фильтры
- pgpro_stats_trace_show
- показывает фильтры
Комментарии преподавателя
Расширение pgpro_stats позволяет выполнять трассировку сеансов, записывая данные о выполняемых командах в журнал сообщений или в файлы. Регистрируются команды, которые удовлетворяют фильтрам. Фильтры размещаются в таблице в общей памяти. Строки таблицы описывают фильтры, а столбцы содержат условия фильтрации.
Для управления фильтрами расширение pgpro_stats предоставляет функции, показанные на слайде.
Изменения фильтров сразу влияют на трассировку во всех сеансах экземпляра СУБД.
Условия фильтров включают:
● идентифицирующие поля — проверяются на равенство;
● ресурсные поля — проверяются на превышение порога;
● поля, определяющие параметры EXPLAIN.
Например, database_name — идентифицирующее поле: сеанс, в котором выполнена команда, должен быть в указанной базе данных. Если же в фильтре указано ресурсное поле duration, то команда должна выполняться более указанной длительности.
Подробности об условиях фильтров в документации: https://postgrespro.ru/docs/enterprise/16/pgpro-stats#PGPRO-STATS-TRAC E-SHOW-OUTPUT
Page 18: Трассировка сеансов
Откроем второй сеанс и получим PID обслуживающего процесса.
Добавим фильтр pa1, который будет записывать в файл трассировки pa1.trace вывод EXPLAIN ANALYZE для каждой команды, выполняющейся во втором сеансе:
Проверим получившийся фильтр трассировки:
Page 19: Page 19
Во втором сеансе выполним запрос.
Закроем второй сеанс и проверим файл трассировки.
Удалим фильтр трассировки.
Page 20: Итоги
Расширение pgpro\_stats позволяет выявлять и анализировать ресурсоемкие операции
- Собирается статистика по затраченным ресурсам, планам и событиям ожиданий
- Отдельно собирается агрегированная статистика
- Можно использовать метрики, определенные пользователем
- Имеется статистика по очистке и аннулированию кешей
- Можно трассировать сеансы
Page 21: Практика
- Подготовьте СУБД для работы с расширением pgpro_stats. 2. Выполните запрос с двухпроходным хеш-соединением в условиях недостаточной памяти work_mem. 3. Получите отчет pgpro_stats. 4. Выполните этот же запрос в условиях достаточной памяти work_mem и снова получите отчет.
Комментарии преподавателя
Подключите разделяемую библиотеку pgpro_stats, создайте базу данных — копию базы данных demo и подключите к ней расширение.
Запустите транзакцию с установленными локальными параметрами work_mem = ‘12MB’ и hash_mem_multiplier = 1. В транзакции получите реальный план запроса SELECT * FROM bookings b JOIN tickets t ON b.book_ref = t.book_ref
Получите отчет pgpro_stats с помощью представления pgpro_stats_statements, из которого необходимо вывести поля: query, plan, calls, temp_blks_read, temp_blks_written.
Очистите статистику и второй раз запустите транзакцию с настройками work_mem = ‘48MB’ и hash_mem_multiplier = 3 и снова получите такой же отчет. Обратите внимание во втором отчете на отсутствие операций по работе с временными файлами.
Page 22: 1. Подготовка СУБД для работы с расширением pgpro_stats
Подключим разделяемую библиотеку:
Перезагрузим сервер.
2. Запрос при недостатке памяти
Создадим тестовую базу данных на основе demo:
Для удобства настроим путь поиска:
Подключимся к базе данных.
Подключим расширение:
Зададим размер памяти:
Выполняем запрос:
3. Отчет по нагрузке
Соединение хешированием при недостатке оперативной памяти выполняется в двухпроходном режиме и использует
Page 23: Page 23
временные файлы. Проверим, что накопилось в статистике.
По столбцам temp_blks_read и temp_blks_written можно судить об активности использования временных файлов.
4. Отчет по нагрузке при достаточном объеме памяти
Сбросим статистику.
Увеличим значения параметров:
Соединение хешированием станет однопроходным и не будет использовать временные файлы.
Проверим, что накопилось в статистике.
Временные файлы не использовались.
Page 24: Уборка
Удалим созданную базу данных и очистим список загружаемых библиотек.
Page 25: Практика PPEM
- В основном экземпляре создайте из шаблона demo базу данных stats_ppem и подготовьте ее для работы с pgpro_stats. 2. С помощью psql-консоли выполните запрос из оператора EXPLAIN п. 2 задания основной практики. 3. Модифицируйте запрос так, чтобы он ограничивал результаты определенным количеством строк. Выполните запрос. 4. В статистике, собранной расширением pgpro_stats, найдите оба запроса и сравните их представления и планы.
Комментарии преподавателя
Для удобства дальнейшей работы подключитесь к базе как пользователь student с помощью метакоманды \c — student и включите в путь поиска схему bookings (или используйте запросы с квалифицированными именами таблиц): SELECT * FROM bookings.bookings AS b JOIN bookings.tickets AS t ON b.book_ref = t.book_ref;
Дополненный запрос: SELECT * FROM bookings.bookings AS b JOIN bookings.tickets AS t ON b.book_ref = t.book_ref LIMIT 555;
В разделе Мониторинг/SQL-статистика удобно поставить фильтры на базу данных и пользователя и отсортировать данные по количеству возвращенных строк.
Обратите внимание на представление константы в запросе из п. 3.
Page 26: 1. Создание базы из шаблона и установка расширения pgpro_stats
Выберите вкладку «Базы данных» и нажмите «Создать базу данных». При заполнении формы укажите шаблон — базу demo. На вкладке «Параметры» добавьте в shared_preload_libraries библиотеку pgpro_stats. Сохраните измененный параметр и перезапустите сервер. Далее на вкладке «Расширения» нажмите «Установить расширение», выберите базу, в списке расширений найдите pgpro_stats и установите его.
2,3. Выполнение запросов
В списке «Базы данных» найдите stats_ppem и в столбце «Действия» нажмите на пиктограмму «{/}» (открыть PSQL-консоль). Выполните запросы: SELECT * FROM bookings.bookings AS b JOIN bookings.tickets AS t ON b.book_ref = t.book_ref; SELECT * FROM bookings.bookings AS b JOIN bookings.tickets AS t ON b.book_ref = t.book_ref LIMIT 555;
4. Сохраненные планы запросов
На вкладке «SQL-статистика» отфильтруйте запросы для базы stats_ppem и пользователя student. Для просмотра плана запроса нажмите на значок «Раскрыть» в самом левом столбце таблицы. Запросы, различающиеся константами, объединяются расширением в одну запись, а сами эти константы заменяются обозначением параметра; в плане запроса п.3 константа 555 заменена на $1.