Мониторинг производительности с помощью хранилища запросов
ОБЛАСТЬ ПРИМЕНЕНИЯ: База данных Azure для PostgreSQL — гибкий сервер
Хранилище запросов — это функция База данных Azure для PostgreSQL гибкого сервера, который позволяет отслеживать производительность запросов с течением времени. Хранилище запросов упрощает устранение проблем с производительностью, помогая быстро находить самые длительные и наиболее ресурсоемкие запросы. Хранилище запросов автоматически записывает журнал запросов и статистику среды выполнения и сохраняет их для проверки. В журнале выполняется сортировка данных по времени, чтобы можно было видеть шаблоны использования во времени. Данные для всех пользователей, баз данных и запросов хранятся в базе данных с именем azure_sys
в База данных Azure для PostgreSQL гибком экземпляре сервера.
Включение хранилища запросов
Хранилище запросов доступно для использования без дополнительных расходов. Это функция согласия, поэтому она не включена по умолчанию на сервере. Хранилище запросов можно включить или отключить глобально для всех баз данных на определенном сервере и не может быть включен или отключен для каждой базы данных.
Внимание
Не включите хранилище запросов на ценовую категорию с возможностью ускорения, так как это приведет к снижению производительности.
Включение хранилища запросов в портал Azure
- Войдите в портал Azure и выберите экземпляр гибкого сервера База данных Azure для PostgreSQL.
- Выберите параметры сервера в разделе "Параметры" меню.
- Найдите параметр
pg_qs.query_capture_mode
. - Задайте значение
top
илиall
в зависимости от того, хотите ли вы отслеживать запросы верхнего уровня или также вложенные запросы (те, которые выполняются внутри функции или процедуры), и нажмите кнопку "Сохранить". Разрешить до 20 минут для первого пакета данных сохраняться вazure_sys
базе данных.
Включение выборки ожидания хранилища запросов
- Найдите параметр
pgms_wait_sampling.query_capture_mode
. - Установите значение
all
и нажмите Сохранить.
Сведения в хранилище запросов
Хранилище запросов состоит из двух хранилищ:
- хранилище статистики времени выполнения для хранения статистических сведений о выполнении запросов;
- хранилище статистики ожидания для хранения статистических сведений об ожидании.
Ниже приведены распространенные сценарии использования хранилища запросов:
- Определение количества выполнения запроса в заданном окне времени.
- Сравнение среднего времени выполнения запроса в течение нескольких периодов времени, чтобы увидеть большие вариации.
- Определение самых длительных запросов за последние несколько часов.
- Определение основных N-запросов, ожидающих ресурсов.
- Понимание характера ожиданий конкретного запроса.
С целью экономии места к статистическим данным о выполнении запросов в хранилище статистики времени выполнения применяется агрегирование за фиксированный настраиваемый период. Данные в этих хранилищах можно запрашивать с использованием представлений.
Доступ к сведениям о хранилище запросов
Данные хранилища запросов хранятся в azure_sys
базе данных на База данных Azure для PostgreSQL гибком экземпляре сервера.
Следующий запрос возвращает сведения о запросах, записанных в хранилище запросов:
SELECT * FROM query_store.qs_view;
И этот запрос возвращает сведения о статистике ожидания:
SELECT * FROM query_store.pgms_wait_sampling_view;
Поиск запросов ожидания
Типы событий ожидания объединяют разные события ожидания в группы по принципу сходства. Хранилище запросов предоставляет тип события ожидания, конкретное имя события ожидания и запрос. Возможность сопоставлять эти сведения об ожидании со статистикой времени выполнения запроса позволяет получить более глубокое понимание аспектов, влияющих на характеристики производительности запросов.
Ниже приведены некоторые примеры получения дополнительных сведений о рабочей нагрузке с помощью статистики ожидания в хранилище запросов:
Наблюдение | Действие |
---|---|
Ожидание высокой блокировки | Проверьте текст затронутых запросов и выявите целевые сущности. Просмотрите хранилище запросов для других запросов, которые часто выполняются и /или имеют высокую длительность и изменяют ту же сущность. Найдя такие запросы, рекомендуется изменить логику приложения, чтобы улучшить параллелизм, или использовать менее строгий уровень изоляции. |
Ожидается большое число операций ввода-вывода в буфер | Найдите запросы с большим количеством физических операций чтения в хранилище запросов. Если они соответствуют запросам с большим количеством операций ввода-вывода, рекомендуется включить функцию автоматической настройки индекса, чтобы узнать, может ли он создавать некоторые индексы, которые могут уменьшить количество физических операций чтения для этих запросов. |
Ожидание высокой памяти | Найдите лучшие запросы, потребляющие память, в хранилище запросов. Вероятнее всего, эти запросы препятствуют дальнейшей обработке затронутых запросов. |
Варианты конфигурации
Если хранилище запросов включено, он сохраняет данные в окнах агрегирования длины, определенных параметром сервера pg_qs.interval_length_minutes (по умолчанию — 15 минут ). Для каждого окна оно хранит до 500 отдельных запросов на окно. Атрибуты, которые отличают уникальность каждого запроса, являются userid (идентификатор пользователя, выполняющего запрос), dbid (идентификатор базы данных, в контексте которого выполняется запрос) и queryid (целочисленное значение, уникально определяющее выполняемый запрос). Если количество отдельных запросов достигает 500 в течение настроенного интервала, 5% записываемых запросов будут освобождены, чтобы освободить место для получения дополнительных возможностей. Те, которые были освобождены, сначала являются теми, которые были выполнены наименьшее количество раз.
Для настройки параметров хранилище запросов доступны следующие параметры:
Параметр | Description | По умолч. | Диапазон |
---|---|---|---|
pg_qs.interval_length_minutes (*) |
Интервал записи в минутах для хранилища запросов. Определяет частоту сохраняемости данных. | 15 |
1 - 30 |
pg_qs.is_enabled_fs |
Только для внутреннего использования: этот параметр используется в качестве переопределения функции. Если оно отображается как отключенное, хранилище запросов отключено, несмотря на значение, заданное для pg_qs.query_capture_mode . |
on |
on , off |
pg_qs.max_plan_size |
Максимальное количество байтов, сохраненных из текста плана запроса по хранилищу запросов; более длинные планы усечены. | 7500 |
100 - 10000 |
pg_qs.max_query_text_length |
Максимальная длина запроса, которую можно сохранить; более длинные запросы усечены. | 6000 |
100 - 10000 |
pg_qs.parameters_capture_mode |
Указывает, следует ли и когда записывать позиционные параметры запроса. | capture_parameterless_only |
capture_parameterless_only , capture_first_sample |
pg_qs.query_capture_mode |
Инструкции для отслеживания. | none |
none , , top all |
pg_qs.retention_period_in_days |
Период хранения в днях для хранилища запросов. Старые данные автоматически удаляются. | 7 |
1 - 30 |
pg_qs.store_query_plans |
Следует ли сохранять планы запросов в хранилище запросов. | off |
on , off |
pg_qs.track_utility |
Следует ли хранить запросы отслеживать команды служебной программы. | on |
on , off |
(*) Параметр статического сервера, для которого требуется перезапуск сервера, чтобы изменить его значение, вступают в силу.
Следующие параметры применяются специально к статистике ожидания:
Параметр | Description | По умолч. | Диапазон |
---|---|---|---|
pgms_wait_sampling.history_period |
Частота ( в миллисекундах), при которой выборка событий ожидания выполняется. | 100 |
1 - 600000 |
pgms_wait_sampling.is_enabled_fs |
Только для внутреннего использования: этот параметр используется в качестве переопределения функции. Если он отображается как off , выборка ожидания отключена, несмотря на значение, заданное для pgms_wait_sampling.query_capture_mode . |
on |
on , off |
pgms_wait_sampling.query_capture_mode |
Какие операторы pgms_wait_sampling расширения должны отслеживаться. |
none |
none , all |
Примечание.
pg_qs.query_capture_mode
pgms_wait_sampling.query_capture_mode
заменяет. В противном pg_qs.query_capture_mode
none
pgms_wait_sampling.query_capture_mode
случае параметр не действует.
Используйте портал Azure, чтобы получить значение параметра или задать другое значение.
Представления и функции
Вы можете запросить информацию, записанную в хранилище запросов, или удалить ее с помощью некоторых представлений и функций, доступных в схеме query_store
azure_sys
базы данных. Любой пользователь в общедоступной роли PostgreSQL может использовать эти представления для просмотра данных в хранилище запросов. Эти представления доступны только в базе данных azure_sys.
Запросы нормализуются, просматривая их структуру и игнорируя ничего не семантического значения, таких как литералы, константы, псевдонимы или различия в регистре.
Если два запроса семантически идентичны, даже если они используют разные псевдонимы для одинаковых ссылочных столбцов и таблиц, они идентифицируются с одинаковыми query_id. Если два запроса отличаются только в литеральных значениях, используемых в них, они также идентифицируются с одинаковыми query_id. Для запросов, определенных с тем же query_id, их sql_query_text заключается в том, что запрос, который выполнялся сначала с момента начала записи хранилища запросов, или с момента последнего отмены сохраненных данных, так как функция query_store.qs_reset была выполнена.
Как работает нормализация запросов
Ниже приведены некоторые примеры, чтобы иллюстрировать работу этой нормализации.
Предположим, что вы создаете таблицу со следующей инструкцией:
create table tableOne (columnOne int, columnTwo int);
Вы включаете хранилище запросов сбор данных, а один или несколько пользователей выполняют следующие запросы в этом точном порядке:
select * from tableOne;
select columnOne, columnTwo from tableOne;
select columnOne as c1, columnTwo as c2 from tableOne as t1;
select columnOne as "column one", columnTwo as "column two" from tableOne as "table one";
Все предыдущие запросы используют одинаковые query_id. И текст, который хранилище запросов сохраняется, заключается в том, что первый запрос, выполняемый после включения сбора данных. Таким образом, это было бы select * from tableOne;
.
Следующий набор запросов после нормализации не соответствует предыдущему набору запросов, так как предложение WHERE делает их семантической по-разному:
select columnOne as c1, columnTwo as c2 from tableOne as t1 where columnOne = 1 and columnTwo = 1;
select * from tableOne where columnOne = -3 and columnTwo = -3;
select columnOne, columnTwo from tableOne where columnOne = '5' and columnTwo = '5';
select columnOne as "column one", columnTwo as "column two" from tableOne as "table one" where columnOne = 7 and columnTwo = 7;
Однако все запросы в этом последнем наборе используют одинаковые query_id, а текст, используемый для их идентификации, состоит в том, что первый запрос в пакете select columnOne as c1, columnTwo as c2 from tableOne as t1 where columnOne = 1 and columnTwo = 1;
.
Наконец, найдите ниже некоторые запросы, не соответствующие query_id из них в предыдущем пакете, и причина, по которой они не:
Запрос:
select columnTwo as c2, columnOne as c1 from tableOne as t1 where columnOne = 1 and columnTwo = 1;
Причина несоответствия: список столбцов относится к тем же двум столбцам (columnOne и ColumnTwo), но порядок, в котором они называются, обратно, от columnOne, ColumnTwo
предыдущего пакета до ColumnTwo, columnOne
этого запроса.
Запрос:
select * from tableOne where columnTwo = 25 and columnOne = 25;
Причина несоответствия: порядок, в котором выражения, вычисляемые в предложении WHERE, ссылаются обратно из columnOne = ? and ColumnTwo = ?
предыдущего пакета ColumnTwo = ? and columnOne = ?
в этот запрос.
Запрос:
select abs(columnOne), columnTwo from tableOne where columnOne = 12 and columnTwo = 21;
Причина несоответствия: первое выражение в списке столбцов больше не columnOne
совпадает, но функция abs
, вычисляемая поверх columnOne
(abs(columnOne)
), которая не является семантической эквивалентной.
Запрос:
select columnOne as "column one", columnTwo as "column two" from tableOne as "table one" where columnOne = ceiling(16) and columnTwo = 16;
Причина несоответствия: первое выражение в предложении WHERE больше не оценивает равенство columnOne
с литеральным, но с результатом функции ceiling
, вычисляемой по литералу, которая не является семантически эквивалентной.
Представления
query_store.qs_view
Это представление возвращает все данные, сохраненные в вспомогательных таблицах хранилища запросов. Данные, которые по-прежнему записывайте в памяти для текущего активного периода времени, не отображаются до тех пор, пока время не завершится, и его в памяти переменные данные собираются и сохраняются в таблицах, хранящихся на диске. Это представление возвращает другую строку для каждой отдельной базы данных (db_id), пользователя (user_id) и запроса (query_id).
Имя | Тип | Ссылки | Description |
---|---|---|---|
runtime_stats_entry_id |
bigint | Идентификатор из таблицы runtime_stats_entries. | |
user_id |
oid | pg_authid.oid | Идентификатор пользователя, выполнившего инструкцию. |
db_id |
oid | pg_database.oid | OID базы данных, в которой была выполнена инструкция. |
query_id |
bigint | Внутренний хэш-код, вычисляемый из дерева синтаксического анализа инструкции. | |
query_sql_text |
varchar(10000) | Текст репрезентативной инструкции. Разные запросы с одной структурой объединяются в кластеры: этот текст — текст для первого запроса в кластере. Значение по умолчанию для максимальной длины текста запроса равно 6000 и может быть изменено с помощью параметра pg_qs.max_query_text_length хранилища запросов. Если текст запроса превышает это максимальное значение, оно усечено до первых pg_qs.max_query_text_length символов. |
|
plan_id |
bigint | Идентификатор плана, соответствующего этому запросу. | |
start_time |
TIMESTAMP | Запросы агрегируются по временным периодам. Параметр pg_qs.interval_length_minutes сервера определяет интервал времени этих окон (по умолчанию — 15 минут). Этот столбец соответствует времени начала окна, в котором была записана запись. |
|
end_time |
TIMESTAMP | Время окончания, соответствующее периоду времени для этой записи. | |
calls |
bigint | Количество раз, когда запрос выполняется в этом окне времени. Обратите внимание, что для параллельных запросов число вызовов для каждого выполнения соответствует 1 для внутреннего процесса, который управляет выполнением запроса, а также множество других единиц для каждого внутреннего рабочего процесса, который запускает совместную работу, выполняя параллельные ветви дерева выполнения. | |
total_time |
double precision | Общее время выполнения запроса в миллисекундах. | |
min_time |
double precision | Минимальное время выполнения запроса в миллисекундах. | |
max_time |
double precision | Максимальное время выполнения запроса в миллисекундах. | |
mean_time |
double precision | Среднее время выполнения запроса в миллисекундах. | |
stddev_time |
double precision | Стандартное отклонение времени выполнения запроса в миллисекундах. | |
rows |
bigint | Общее количество строк, полученных или затронутых инструкцией. Обратите внимание, что для параллельных запросов число строк для каждого выполнения соответствует количеству строк, возвращаемых клиенту серверным процессом, который управляет выполнением запроса, а также суммой всех строк, запущенных для совместной работы при выполнении параллельных ветвей дерева выполнения, возвращается во внутренний процесс, который управляет выполнением запроса. | |
shared_blks_hit |
bigint | Общее количество попаданий в общий кэш блоков инструкцией. | |
shared_blks_read |
bigint | Общее количество общих блоков, прочитанных инструкцией. | |
shared_blks_dirtied |
bigint | Общее количество общих блоков, грязных инструкцией. | |
shared_blks_written |
bigint | Общее количество общих блоков, написанных инструкцией. | |
local_blks_hit |
bigint | Общее количество попаданий в кэш локальных блоков инструкцией. | |
local_blks_read |
bigint | Общее количество локальных блоков, считываемых инструкцией. | |
local_blks_dirtied |
bigint | Общее количество локальных блоков, грязных инструкцией. | |
local_blks_written |
bigint | Общее количество локальных блоков, написанных инструкцией. | |
temp_blks_read |
bigint | Общее количество блоков temp, считываемых инструкцией. | |
temp_blks_written |
bigint | Общее количество блоков temp, написанных инструкцией. | |
blk_read_time |
double precision | Общее время, затраченное оператором на чтение блоков, в миллисекундах (если track_io_timing включен, в противном случае — ноль). | |
blk_write_time |
double precision | Общее время, затраченное оператором на запись блоков, в миллисекундах (если track_io_timing включен, в противном случае — ноль). | |
is_system_query |
boolean | Определяет, выполняется ли роль с user_id = 10 (azuresu). Этот пользователь имеет права суперпользователя и используется для выполнения операций плоскости управления. Так как эта служба является управляемой службой PaaS, только корпорация Майкрософт является частью этой роли суперпользователя. | |
query_type |
text | Тип операции, представленной запросом. Возможные значения: unknown , select , insert delete merge update , utility , . undefined nothing |
|
search_path |
text | Значение search_path задано во время записи запроса. | |
query_parameters |
text | Текстовое представление объекта JSON со значениями, передаваемыми в позиционные параметры параметризованного запроса. Этот столбец заполняет значение только в двух случаях: 1) для непараметризованных запросов. 2) Для параметризованных запросов, если pg_qs.parameters_capture_mode задано capture_first_sample значение , и если хранилище запросов может получить значения для параметров запроса во время выполнения. |
|
parameters_capture_status |
text | Тип операции, представленной запросом. Возможные значения succeeded : (запрос не был параметризован или был параметризованным запросом и значениями успешно записан), disabled (запрос был параметризован, но параметры не были записаны из-за того, что задано значение ), (запрос был параметризован, но параметры не были записаны, так как too_long_to_capture pg_qs.parameters_capture_mode capture_parameterless_only длина результирующего JSON, который будет отображаться в query_parameters столбце этого представления, считается чрезмерно длинным для сохранения хранилища запросов), too_many_to_capture (запрос был параметризован, но параметры не были записаны, так как общее количество параметров, считается чрезмерным для сохранения хранилища запросов) serialization_failed (запрос был параметризован, но по крайней мере одно из значений, переданных в качестве параметра, не может быть сериализовано в текст). |
query_store.query_texts_view
Это представление возвращает текстовые данные запроса в хранилище запросов. Для каждой отдельной query_sql_text существует одна строка.
Имя | Тип | Description |
---|---|---|
query_text_id |
bigint | Идентификатор для таблицы query_texts |
query_sql_text |
varchar(10000) | Текст репрезентативной инструкции. Разные запросы с одной структурой объединяются в кластеры: этот текст — текст для первого запроса в кластере. |
query_type |
smallint | Тип операции, представленной запросом. В версии PostgreSQL <= 14 возможные значения : 0 (неизвестно), 2 1 (select), (обновление), 3 (вставка), (удаление), 4 5 (служебная программа), 6 (ничего). В версии PostgreSQL >= 15 возможные значения : 0 (неизвестно), 2 1 (select), (update), 3 (insert), 4 (delete), (merge), 5 6 (utility), 7 (nothing). |
query_store.pgms_wait_sampling_view
Это представление возвращает данные событий ожидания в хранилище запросов. Это представление возвращает другую строку для каждой отдельной базы данных (db_id), пользователя (user_id), запроса (query_id) и события (события).
Имя | Тип | Ссылки | Description |
---|---|---|---|
start_time |
TIMESTAMP | Запросы агрегируются по временным периодам. Параметр pg_qs.interval_length_minutes сервера определяет интервал времени этих окон (по умолчанию — 15 минут). Этот столбец соответствует времени начала окна, в котором была записана запись. |
|
end_time |
TIMESTAMP | Время окончания, соответствующее периоду времени для этой записи. | |
user_id |
oid | pg_authid.oid | Идентификатор объекта пользователя, выполнившего инструкцию. |
db_id |
oid | pg_database.oid | Идентификатор объекта базы данных, в которой была выполнена инструкция. |
query_id |
bigint | Внутренний хэш-код, вычисляемый из дерева синтаксического анализа инструкции. | |
event_type |
text | Тип события, для которого ожидается серверная часть. | |
event |
text | Имя события ожидания, если серверная часть в настоящее время ожидает. | |
calls |
integer | Количество раз, когда было записано одно и то же событие. |
Примечание.
Список возможных значений в представлении и event
столбцах query_store.pgms_wait_sampling_view
см. в event_type
официальной документации по pg_stat_activity и поиск информации, ссылающейся на столбцы с одинаковыми именами.
query_store.query_plans_view
Это представление возвращает план запроса, который использовался для выполнения запроса. Для каждой отдельной базы данных и идентификатора запроса существует одна строка. Хранилище запросов записывает только планы запросов для неуловимых запросов.
Имя | Тип | Ссылки | Description |
---|---|---|---|
plan_id |
bigint | Хэш-значение из нормализованного плана запроса, созданного ОБЪЯСНИМ. Он находится в нормализованной форме, так как он исключает предполагаемые затраты на узлы плана и использование буферов. | |
db_id |
oid | pg_database.oid | OID базы данных, в которой была выполнена инструкция. |
query_id |
bigint | Внутренний хэш-код, вычисляемый из дерева синтаксического анализа инструкции. | |
plan_text |
varchar(10000) | План выполнения инструкции с заданными затратами=false, buffers=false и format=text. Идентичные выходные данные, аналогичные выходным данным, созданным с помощью EXPLAIN. |
Функции
query_store.qs_reset
Эта функция отменяет все статистические данные, собранные до сих пор по хранилищу запросов. Она удаляет статистику для уже закрытых периодов времени, которые уже сохраняются в таблицах на диске. Она также отменяет статистику для текущего периода времени, которое существует только в памяти. Только члены роли администратора сервера (azure_pg_admin
) могут выполнять эту функцию.
query_store.staging_data_reset
Эта функция удаляет все статистические данные, собранные в памяти по хранилищу запросов (т. е. данные в памяти, которые еще не удалены на таблицы дисков, поддерживающие сохраняемость собранных данных для хранилища запросов). Только члены роли администратора сервера (azure_pg_admin
) могут выполнять эту функцию.
Режим только для чтения
Если экземпляр гибкого сервера База данных Azure для PostgreSQL находится в режиме только для чтения, например если default_transaction_read_only
параметр установлен on
или если режим только для чтения включен из-за достижения емкости хранилища, хранилище запросов не записывает данные.
Включение хранилища запросов на сервере с репликами чтения не включает хранилище запросов на любой из реплик чтения. Даже если включить его на любой из реплик чтения, хранилище запросов не записывает запросы, выполняемые на репликах чтения, так как они работают в режиме только для чтения, пока не будет повышен их до первичного.