Перейти к основному содержимому

Отключение маскирования полей usename и client_addr в Performance Insights

Описание

Проблемы анализа инцидентов

При сохранении данных активности сессий для исключения несанкционированного доступа к этим данным в процессе выполнения функций Performance Insights происходит маскирование следующих полей представлений pg_stat_activity и pg_locks (при включенном параметре performance_insights.masking):

  • параметры запросов;
  • client_addr - адрес и/или имя хоста, с которого была открыта сессия;
  • usename - имя пользователя, открывшего сессию.
примечание

Маскирование внутри функциональности Performance Insights происходит независимо от общего маскирования. Но при заданном маскировании запросов (masking_mode = full) маскирование запросов в Performance Insight будет выполняться независимо от значения параметра performance_insights.masking. Это связано с тем, что Performance Insights пользуется текстами запросов, помещенных в представление pg_stat_activity, и при включенном маскировании тексты запросов в представлении находятся уже в замаскированном виде. Подробнее про общее маскирование описано в разделе «Маскирование запросов».

Так как цель функциональности Performance Insights предоставить администратору СУБД, администратору АС, а также разработчику приложений возможность анализа истории активности СУБД Pangolin, маскирование полей usename и client_addr в выводе функций Performance Insights существенно затрудняет разбор инцидентов, так как делает вывод функций pg_stat_get_activity_history, pg_stat_get_activity_history_last и pg_stat_get_activity_and_lock_status_history неинформативным.

Например:

  • Запрос на вывод снимка pg_stat_activity (запрос выполняется от суперпользователя):

    SELECT datname, usename, client_addr, query, state FROM pg_stat_get_activity_history(NULL, NULL, NULL) ORDER BY query_start DESC LIMIT 6;

    Пример вывода команды:

      datname | usename | client_addr |                         query                       |       state
    ----------+---------+-------------+-----------------------------------------------------+--------------------
    test_db | *** | *** | BEGIN; | idle in transaction
    test_db | *** | *** | INSERT INTO test_schema.test_table VALUES(***, ***);| idle in transaction
    test_db | *** | *** | INSERT INTO test_schema.test_table VALUES(***, ***);| idle in transaction
    test_db | *** | *** | BEGIN; | idle in transaction
    test_db | *** | *** | DELETE FROM test_schema.test_table WHERE id=***; | idle in transaction
    test_db | *** | *** | DELETE FROM test_schema.test_table WHERE id=***; | idle in transaction
    (6 rows)

    Из данного вывода невозможно установить от имени какого пользователя производятся действия по изменению таблицы test_schema.test_table в базе данных test_db, а также IP-адрес хоста, с которого пользователь выполняет данные действия.

  • Запрос на вывод снимка pg_stat_activity и pg_locks с отметками времени выборки (запрос выполняется от суперпользователя):

    SELECT datname, usename, client_addr, query, state,  locktype FROM pg_stat_get_activity_and_lock_status_history(NULL, NULL, NULL) ORDER BY query_start DESC LIMIT 4;

    Пример вывода команды:

      datname | usename | client_addr |                                query                             |   locktype    |        state
    ----------+---------+-------------+------------------------------------------------------------------+---------------+---------------------
    test_db | *** | *** | BEGIN; | virtualxid | idle in transaction
    test_db | *** | *** | DELETE FROM test_schema.test_table WHERE id BETWEEN *** AND ***; | transactionid | idle in transaction
    test_db | *** | *** | DELETE FROM test_schema.test_table WHERE id BETWEEN *** AND ***; | virtualxid | idle in transaction
    test_db | *** | *** | DELETE FROM test_schema.test_table WHERE id BETWEEN *** AND ***; | virtualxid | idle in transaction
    (4 rows)

    Из данного вывода также невозможно установить ни имени пользователя, выполняющего действия по изменению таблицы test_schema.test_table в базе данных test_db, ни IP-адрес хоста, с которого данные действия выполняются.

Настройка

Для обеспечения удобства расследования возможных инцидентов разработано дополнительное значение partial параметра performance_insights.masking для отключения маскирования полей usename и client_addr в выводе работы функций. Маскирование других полей будет производиться без изменения.

к сведению

Дополнительно изменено значение по умолчанию параметра performance_insights.masking на off после установки СУБД вручную (для уменьшения нагрузки на систему), и на partial, после установки при помощи скриптов автоматизации.

Также для удобства в HTML-отчете выводится имя пользователя в поле User в незамаскированном виде при значении параметра performance_insights.masking = 'partial'/'off'. Значение oid в поле UserOid выводится всегда не зависимо от параметра performance_insights.masking.

Управление

примечание

При значении параметра performance_insights.masking = on маскирование остается без изменений.

  1. Пример вывода функции pg_stat_get_activity_history при значении параметра performance_insights.masking = 'partial':

    SELECT datname, usename, client_addr, query, state FROM pg_stat_get_activity_history(NULL, NULL, NULL)  ORDER BY query_start DESC LIMIT 5;

    Вывод:

    datname | usename   | client_addr |                      query                           |      state
    --------+-----------+-------------+------------------------------------------------------ +------------------
    test_db | test_user | 0.0.0.0 | BEGIN; | idle in transaction
    test_db | test_user | 0.0.0.0 | INSERT INTO test_schema.test_table VALUES(***, ***); | idle in transaction
    test_db | test_user | 0.0.0.0 | INSERT INTO test_schema.test_table VALUES(***, ***); | idle in transaction
    test_db | test_user | 0.0.0.0 | BEGIN; | idle in transaction
    test_db | test_user | 0.0.0.0 | DELETE FROM test_schema.test_table WHERE id=***; | idle in transaction
    (5 rows)

    Поля usename и client_addr не замаскированы в выводе, параметры запросов замаскированы.

  2. Пример вывода функции pg_stat_get_activity_history_last при значении параметра performance_insights.masking = 'partial':

    SELECT datname, usename, client_addr, query, state FROM pg_stat_get_activity_history_last(NULL);

    Вывод:

    datname |  usename  | client_addr |                          query                   |        state
    --------+-----------+-------------+-------------------------------------------------- +--------------------
    test_db | test_user | 0.0.0.0 | DELETE FROM test_schema.test_table WHERE id=***; | idle in transaction
    (1 row)

    Поля usename и client_addr не замаскированы в выводе, параметры запросов замаскированы.

  3. Пример вывода функции pg_stat_get_activity_and_lock_status_history при значении параметра performance_insights.masking = 'partial':

    SELECT datname, usename, client_addr, query, state,  locktype FROM  pg_stat_get_activity_and_lock_status_history(NULL, NULL, NULL) ORDER BY query_start DESC LIMIT 4;

    Вывод:

      datname |   usename   | client_addr |                               query                               |   locktype    |        state
    ----------+-------------+-------------+------------------------------------------------------------------ +---------------+---------------------
    test_db | test_user | 0.0.0.0 | BEGIN; | virtualxid | idle in transaction
    test_db | test_user | 0.0.0.0 | DELETE FROM test_schema.test_table WHERE id BETWEEN *** AND ***; | transactionid | idle in transaction
    test_db | test_user | 0.0.0.0 | DELETE FROM test_schema.test_table WHERE id BETWEEN *** AND ***; | virtualxid | idle in transaction
    test_db | test_user | 0.0.0.0 | DELETE FROM test_schema.test_table WHERE id BETWEEN *** AND ***; | virtualxid | idle in transaction
    (4 rows)

    Поля usename и client_addr не замаскированы в выводе, параметры запросов замаскированы.

Сценарии использования

Маскирование параметров запросов в выводе функций при значении параметра performance_insights.masking = partial

  1. От имени суперпользователя проверьте значение параметра performance_insights.masking:

    SHOW performance_insights.masking;

    Параметр имеет значение partial по умолчанию:

    performance_insights.masking
    ------------------------------
    partial
    (1 row)
  2. От имени тестового пользователя perfins_msk_user в тестовой базе данных perfins_msk_db начните транзакцию и вставьте в тестовую таблицу новую запись:

    BEGIN;
    INSERT INTO perfins_msk_schema.perfins_msk_table VALUES(1, 'test data 1');

    Транзакция начинает выполняться:

    BEGIN
    INSERT 0 1
  3. От имени суперпользователя выведите последнюю запись с данными об активности сессий:

    SELECT sample_time, datname, pid, usesysid, usename, client_addr, query
    FROM pg_stat_get_activity_history(NULL, NULL, NULL)
    WHERE datname = 'perfins_msk_db' AND state = 'idle in transaction'
    ORDER BY query_start DESC LIMIT 1 \gx

    Поля usename и client_addr в выводе не замаскированы, параметры запроса в поле query замаскированы. Пример вывода:

    -[ RECORD 1 ]-------------------------------------------------------------------
    sample_time | 2025-08-07 14:01:01.400833+03
    datname | perfins_msk_db
    pid | 19656
    usesysid | 26458
    usename | perfins_msk_user
    client_addr | <IP-Address>
    query | INSERT INTO perfins_msk_schema.perfins_msk_table VALUES(***, ***);
  4. От имени суперпользователя выведите последнюю запись с данными об активности сессий за последний период обновления истории:

    SELECT sample_time, datname, pid, usesysid, usename, client_addr, query
    FROM pg_stat_get_activity_history_last(NULL) \gx

    Поля usename и client_addr в выводе не замаскированы, параметры запроса в поле query замаскированы. Пример вывода:

    sample_time | 2025-08-07 14:01:47.900393+03
    datname | perfins_msk_db
    pid | 19656
    usesysid | 26458
    usename | perfins_msk_user
    client_addr | <IP-Address>
    query | INSERT INTO perfins_msk_schema.perfins_msk_table VALUES(***, ***);
  5. От имени тестового пользователя завершите транзакцию:

    COMMIT;

    Транзакция успешно завершена:

    COMMIT
  6. От имени суперпользователя очистите историю:

    SELECT pg_stat_activity_history_reset();

    История очищена:

    pg_stat_activity_history_reset
    --------------------------------

    (1 row)
  7. От имени тестового пользователя заблокируйте тестовую таблицу и удалите из нее несколько записей:

    BEGIN;
    LOCK TABLE perfins_msk_schema.perfins_msk_table IN ACCESS EXCLUSIVE MODE;
    DELETE FROM perfins_msk_schema.perfins_msk_table WHERE ID%3=0;

    Транзакция начинает выполняться:

    BEGIN
    LOCK TABLE
    DELETE 3
  8. От имени суперпользователя выведите последнюю запись с данными об активности текущих сессий вместе с данными блокировок и затраченными ресурсами:

    SELECT sample_time, datname, pid, usesysid, usename, client_addr, query, locktype, mode
    FROM pg_stat_get_activity_and_lock_status_history(NULL, NULL, NULL)
    WHERE datname = 'perfins_msk_db' AND state = 'idle in transaction'
    ORDER BY query_start DESC LIMIT 1 \gx

    Поля usename и client_addr в выводе не замаскированы, параметры запроса в поле query замаскированы. Пример вывода:

    -[ RECORD 1 ]-------------------------------------------------------------------
    sample_time | 2025-08-07 14:02:55.000837+03
    datname | perfins_msk_db
    pid | 19656
    usesysid | 26458
    usename | perfins_msk_user
    client_addr | <IP-Address>
    query | DELETE FROM perfins_msk_schema.perfins_msk_table WHERE ID%***=***;
    locktype | virtualxid
    mode | ExclusiveLock
  9. Отмените транзакцию от имени тестового пользователя:

    ROLLBACK;

    Транзакция успешно отменена:

    ROLLBACK
  10. От имени суперпользователя очистите историю:

    SELECT pg_stat_activity_history_reset();

    История очищена:

    pg_stat_activity_history_reset
    --------------------------------

    (1 row)