Статистика запросов

Модуль статистики запросов mxstat собирает информацию о выполнении запросов, включая:

  • Время выполнения запроса
  • Потребление ресурсов запросом

1. Развертывание

Модуль входит в расширение matrixmgr и устанавливается по умолчанию вместе с системой.

[mxadmin@mdw ~]$ gpconfig -s shared_preload_libraries
Values on all segments are consistent
GUC          : shared_preload_libraries
Master  value: matrixts,matrixmgr,matrixgate,telemetry,mars
Segment value: matrixts,matrixmgr,matrixgate,telemetry,mars

Для просмотра статистики необходимо создать базу данных matrixmgr и установить в ней расширение matrixmgr. (Эта база данных и расширение создаются по умолчанию после инициализации кластера MatrixDB.)

createdb matrixmgr
psql -d matrixmgr
matrixmgr=# CREATE EXTENSION matrixmgr CASCADE;
NOTICE:  installing required extension "matrixts"
CREATE EXTENSION

2. Структура таблиц

После успешного развертывания в схеме matrixmgr_internal базы данных matrixmgr появляются следующие таблицы и представления:

  • mx_query_execute_history
  • mx_query_execute_history_with_text
  • mx_query_usage_history
  • mx_querytext
  • mxstat_execute
  • mxstat_usage

2.1 mxstat_execute

Представление с информацией о выполнении запросов.

Это представление отображает статистику по запросам, выполненным с момента последнего сбора истории (интервал по умолчанию: 5 минут). Оно включает следующие поля:

Столбец Тип Описание
seg integer Идентификатор сегмента, где был сгенерирован и отправлен план запроса
userid oid OID пользователя
dbid oid OID базы данных
queryid bigint Идентификатор запроса, генерируемый расширением для группировки аналогичных запросов
nestlevel integer Глубина вложенности
query text Текст запроса
calls_begin bigint Количество запусков запроса
calls_alive bigint Количество запросов, выполнявшихся на момент последнего сбора
calls_end bigint Количество запросов, завершившихся нормально
total_time double precision Общее время выполнения для данного класса запросов, в миллисекундах
min_time double precision Минимальное время выполнения для данного класса запросов, в миллисекундах
max_time double precision Максимальное время выполнения для данного класса запросов, в миллисекундах
mean_time double precision Среднее время выполнения для данного класса запросов, в миллисекундах
stddev_time double precision Стандартное отклонение времени выполнения, в миллисекундах
sample_planid bigint Идентификатор плана выполнения
sample_start timestamp with time zone Время начала самого медленного запроса
sample_parse_done timestamp with time zone Время завершения парсинга самого медленного запроса
sample_plan_done timestamp with time zone Время завершения планирования самого медленного запроса
sample_exec_start timestamp with time zone Время начала выполнения самого медленного запроса
sample_exec_end timestamp with time zone Время завершения выполнения самого медленного запроса

2.2 mxstat_usage

Представление с информацией о потреблении ресурсов запросами.

Это представление отображает статистику использования ресурсов для запросов, выполненных с момента последнего сбора истории (интервал по умолчанию: 5 минут). Оно включает следующие поля:

Столбец Тип Описание
seg integer Идентификатор сегмента, на котором выполнен запрос
userid oid OID пользователя
dbid oid OID базы данных
queryid bigint Идентификатор запроса, генерируемый расширением для группировки аналогичных запросов
nestlevel integer Глубина вложенности
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_blks_written bigint Общее количество записей временных блоков
blk_read_time double precision Общее время, затраченное на чтение блоков, в миллисекундах
blk_write_time double precision Общее время, затраченное на запись блоков, в миллисекундах
ru_utime double precision Время процессора пользователя
ru_stime double precision Время процессора системы
ru_maxrss bigint Физическая память, использованная процессом (включая общие библиотеки), в КБ
ru_ixrss bigint Общий размер разделяемой памяти
ru_idrss bigint Общий размер неразделяемой данных
ru_isrss bigint Общий размер неразделяемого стека
ru_minflt bigint Количество мелких ошибок страниц (без ввода-вывода)
ru_majflt bigint Количество крупных ошибок страниц (требующих ввода-вывода)
ru_nswap bigint Количество свопов
ru_inblock bigint Количество инициированных операций ввода
ru_oublock bigint Количество инициированных операций вывода
ru_msgsnd bigint Количество отправленных сообщений
ru_msgrcv bigint Количество полученных сообщений
ru_nsignals bigint Количество полученных сигналов
ru_nvcsw bigint Количество добровольных переключений контекста
ru_nivcsw bigint Количество принудительных переключений контекста

2.3 mx_query_execute_history

Это партиционированная таблица, хранящая исторические данные из представления mxstat_execute, собираемые по умолчанию каждые 5 минут. Ее структура совпадает с mxstat_execute, с дополнительным столбцом ts_bucket, указывающим метку времени сбора.

2.4 mx_query_usage_history

Это партиционированная таблица, хранящая исторические данные из представления mxstat_usage, собираемые по умолчанию каждые 5 минут. Ее структура совпадает с mxstat_usage, с дополнительным столбцом ts_bucket, указывающим метку времени сбора.

2.5 mx_querytext

Хранит соответствие между queryid и querytext. Как и другие исторические таблицы, она периодически сохраняет данные, чтобы исторические запросы могли извлекать свой SQL-текст.

2.6 mx_query_execute_history_with_text

Представление, объединяющее mx_query_execute_history и mx_querytext по queryid, позволяющее получать как статистику исторических запросов, так и их SQL-текст.

3. Использование

3.1 Метод классификации запросов

Модуль mxstat не регистрирует каждый отдельный запрос. Вместо этого он группирует аналогичные запросы и агрегирует их статистику. Запросы классифицируются на основе их разобранной структуры.

Например, следующие запросы все вставляют данные в таблицу test1 с разными параметрами. Они генерируют один и тот же queryid и группируются в один класс:

INSERT INTO test1 VALUES(1);
INSERT INTO test1 VALUES(2);
INSERT INTO test1 VALUES(3);

Следующие запросы отличаются только параметрами условия, но в остальном идентичны, поэтому также группируются в один класс:

SELECT * FROM test1 WHERE c1 = 1;
SELECT * FROM test1 WHERE c1 = 2;
SELECT * FROM test1 WHERE c1 = 3;

Следующие запросы, хотя и похожи, работают с разными таблицами и не группируются вместе:

SELECT * FROM test1 WHERE c1 = 1;
SELECT * FROM test2 WHERE c1 = 1;
SELECT * FROM test3 WHERE c1 = 1;

3.2 Примеры использования

Ниже приведены примеры использования mxstat для просмотра статистики запросов.

Пример 1

Выполните следующие три SQL-запроса:

select pg_sleep(5);
select pg_sleep(10);
select pg_sleep(15);

Затем запросите представление mxstat_execute:

matrixmgr=# select * from matrixmgr_internal.mxstat_execute where query like '%pg_sleep%';
 seg | userid | dbid  |       queryid        | nestlevel |        query        | calls_begin | calls_alive | calls_end | total_time | min_time
| max_time  |     mean_time      |    stddev_time    |    sample_planid     |         sample_start          |       sample_parse_done       |
     sample_plan_done        |       sample_exec_start       |        sample_exec_end
-----+--------+-------+----------------------+-----------+---------------------+-------------+-------------+-----------+------------+----------
+-----------+--------------------+-------------------+----------------------+-------------------------------+-------------------------------+--
-----------------------------+-------------------------------+-------------------------------
  -1 |     10 | 16384 | -2007749946425010549 |         0 | select pg_sleep($1) |           3 |           0 |         3 |      30041 | 5009.054
| 15018.717 | 10013.666666666666 | 4086.427819588182 | -2693056513545111817 | 2022-03-25 13:58:58.503851-04 | 2022-03-25 13:58:58.503933-04 | 2
022-03-25 13:58:58.503994-04 | 2022-03-25 13:58:58.504008-04 | 2022-03-25 13:59:13.522725-04
(1 row)

Результат показывает, что запрос был вызван три раза. Текст запроса нормализован: значения параметров заменены на $ с номером параметра. Общее, минимальное, максимальное и среднее время выполнения соответствуют ожиданиям. Записаны временные метки для каждой фазы самого медленного выполнения (т.е. pg_sleep(15)).

Далее проверьте использование ресурсов с помощью queryid из mxstat_execute:

matrixmgr=# select * from matrixmgr_internal.mxstat_usage where queryid = -2007749946425010549;
 seg | userid | dbid  |       queryid        | nestlevel | rows | shared_blks_hit | shared_blks_read | shared_blks_dirtied | shared_blks_writte
n | local_blks_hit | local_blks_read | local_blks_dirtied | local_blks_written | temp_blks_read | temp_blks_written | blk_read_time | blk_write
_time | ru_utime | ru_stime | ru_maxrss | ru_ixrss | ru_idrss | ru_isrss | ru_minflt | ru_majflt | ru_nswap | ru_inblock | ru_oublock | ru_msgs
nd | ru_msgrcv | ru_nsignals | ru_nvcsw | ru_nivcsw
-----+--------+-------+----------------------+-----------+------+-----------------+------------------+---------------------+-------------------
--+----------------+-----------------+--------------------+--------------------+----------------+-------------------+---------------+----------
------+----------+----------+-----------+----------+----------+----------+-----------+-----------+----------+------------+------------+--------
---+-----------+-------------+----------+-----------
  -1 |     10 | 16384 | -2007749946425010549 |         0 |    3 |               0 |                0 |                   0 |
0 |              0 |               0 |                  0 |                  0 |              0 |                 0 |             0 |
    0 | 0.001297 | 0.000431 |     20568 |        0 |        0 |        0 |         6 |         0 |        0 |          0 |          0 |
 0 |         0 |           0 |      122 |         0
(1 row)

Результат показывает, что запрос выполнялся только на мастер-узле (seg = -1).

Пример 2

Рассмотрим другой пример:

create table test1(c1 int, c2 int) distributed by(c1);

Запросите mxstat_execute:

matrixmgr=# select * from matrixmgr_internal.mxstat_execute where query like '%create table test1%';
 seg | userid | dbid  |       queryid        | nestlevel |                         query                         | calls_begin | calls_alive |
calls_end | total_time | min_time | max_time | mean_time | stddev_time | sample_planid |         sample_start          | sample_parse_done | sa
mple_plan_done |       sample_exec_start       |        sample_exec_end
-----+--------+-------+----------------------+-----------+-------------------------------------------------------+-------------+-------------+-
----------+------------+----------+----------+-----------+-------------+---------------+-------------------------------+-------------------+---
---------------+-------------------------------+-------------------------------
  -1 |     10 | 16384 | -6276724884379903029 |         0 | create table test1(c1 int, c2 int) distributed by(c1) |           1 |           0 |
        1 |     46.221 |   46.221 |   46.221 |    46.221 |           0 |             0 | 2022-03-25 14:08:51.754458-04 |                   |
               | 2022-03-25 14:08:51.754735-04 | 2022-03-25 14:08:51.800956-04
(1 row)

Проверьте использование ресурсов:

matrixmgr=# select * from matrixmgr_internal.mxstat_usage where queryid = -6276724884379903029;
 seg | userid | dbid  |       queryid        | nestlevel | rows | shared_blks_hit | shared_blks_read | shared_blks_dirtied | shared_blks_writte
n | local_blks_hit | local_blks_read | local_blks_dirtied | local_blks_written | temp_blks_read | temp_blks_written | blk_read_time | blk_write
_time | ru_utime | ru_stime | ru_maxrss | ru_ixrss | ru_idrss | ru_isrss | ru_minflt | ru_majflt | ru_nswap | ru_inblock | ru_oublock | ru_msgs
nd | ru_msgrcv | ru_nsignals | ru_nvcsw | ru_nivcsw
-----+--------+-------+----------------------+-----------+------+-----------------+------------------+---------------------+-------------------
--+----------------+-----------------+--------------------+--------------------+----------------+-------------------+---------------+----------
------+----------+----------+-----------+----------+----------+----------+-----------+-----------+----------+------------+------------+--------
---+-----------+-------------+----------+-----------
  -1 |     10 | 16384 | -6276724884379903029 |         0 |    0 |             295 |               59 |                  21 |
0 |              0 |               0 |                  0 |                  0 |              0 |                 0 |             0 |
    0 | 0.004053 |        0 |     22744 |        0 |        0 |        0 |       429 |         0 |        0 |          0 |          0 |
 0 |         0 |           0 |        6 |         0
   1 |     10 | 16384 | -6276724884379903029 |         0 |    0 |             261 |               82 |                  19 |
0 |              0 |               0 |                  0 |                  0 |              0 |                 0 |             0 |
    0 | 0.001691 | 0.001558 |     19284 |        0 |        0 |        0 |       510 |         0 |        0 |          0 |          0 |
 0 |         0 |           0 |        0 |         1
   0 |     10 | 16384 | -6276724884379903029 |         0 |    0 |             314 |               34 |                  19 |
0 |              0 |               0 |                  0 |                  0 |              0 |                 0 |             0 |
    0 | 0.002537 | 0.000193 |     18508 |        0 |        0 |        0 |       574 |         0 |        0 |          0 |          0 |
 0 |         0 |           0 |        1 |         1
   2 |     10 | 16384 | -6276724884379903029 |         0 |    0 |             261 |               82 |                  19 |
0 |              0 |               0 |                  0 |                  0 |              0 |                 0 |             0 |
    0 | 0.003043 |  2.9e-05 |     19292 |        0 |        0 |        0 |       514 |         0 |        0 |          0 |          0 |
 0 |         0 |           0 |        0 |         2
(4 rows)

Результат показывает, что использование ресурсов зафиксировано на всех сегментах, так как команда CREATE TABLE выполняется на каждом сегменте.

Пример 3

В предыдущих примерах nestlevel равно 0, поскольку не было вложенного выполнения. Следующий пример демонстрирует вложенное выполнение, обычно достигаемое через UDF.

CREATE OR REPLACE FUNCTION nest_query() RETURNS SETOF RECORD
AS $$ SELECT 1;$$
LANGUAGE SQL;

Это создает UDF с именем nest_query, которая внутри выполняет SELECT 1. Вызовите функцию:

Примечание: По умолчанию mxstat не отслеживает вложенные операторы. Установите mxstat_statements.track в 'all'.

mxadmin=# SET mxstat_statements.track TO 'all';
SET
mxadmin=# select nest_query();
 nest_query
------------
 (1)
(1 row)

Теперь запросите информацию о выполнении внутренних операторов. Поскольку 1 является константой, нормализованный запрос использует $1:

matrixmgr=# select * from matrixmgr_internal.mxstat_execute where query like '%SELECT $1%';
 seg | userid | dbid  |       queryid        | nestlevel |   query   | calls_begin | calls_alive | calls_end | total_time | min_time | max_time
 | mean_time | stddev_time |    sample_planid    |         sample_start          |       sample_parse_done       |       sample_plan_done
  |       sample_exec_start       |        sample_exec_end
-----+--------+-------+----------------------+-----------+-----------+-------------+-------------+-----------+------------+----------+---------
-+-----------+-------------+---------------------+-------------------------------+-------------------------------+-----------------------------
--+-------------------------------+-------------------------------
  -1 |     10 | 16384 | -4554727679305370053 |         1 | SELECT $1 |           1 |           0 |         1 |      0.031 |    0.031 |    0.031
 |     0.031 |           0 | -382705668420232707 | 2022-03-25 14:35:30.668124-04 | 2022-03-25 14:35:30.668373-04 | 2022-03-25 14:35:30.668403-0
4 | 2022-03-25 14:35:30.668408-04 | 2022-03-25 14:35:30.668439-04
(1 row)

Здесь nestlevel равно 1, что указывает на один уровень вложенности. Более глубокая вложенность увеличивает это значение. mxstat отслеживает до 31 уровней вложенности.

4. Конфигурация

mxstat предоставляет следующие параметры GUC для управления поведением мониторинга:

Имя Тип Описание
mxstat_statements.max integer Количество хеш-слотов для хранения данных о времени выполнения запросов. По умолчанию: 5000
mxstat_statements.usage_multiple integer Множитель для хеш-слотов, используемых для хранения данных о потреблении ресурсов относительно данных о времени. Более высокое значение гарантирует, что каждый запрос найдет свою запись о ресурсах. По умолчанию: 2
mxstat_statements.track string top: Отслеживать только верхнеуровневые запросы (без вложенности), по умолчанию.
all: Отслеживать все вложенные запросы.
none: Отключить отслеживание
mxstat_statements.track_utility boolean Отслеживать ли выполнение утилитарных операторов. По умолчанию: true
mxstat_statements.save boolean Сохранять ли статистику из памяти на диск при перезапуске кластера. По умолчанию: true
mxstat_statements.harvest_interval integer Интервал (в секундах) для сбора статистики из разделяемой памяти в исторические таблицы. По умолчанию: 300 (5 минут)