Как смотреть информацию о сессиях не суперпользователям?

«Пост-Грэс-Кью-Эл» свободная объектно-реляционная СУБД. Обмениваемся вопросами и ответами о её работе.
Ответить
AntonS
Сообщения: 116
Зарегистрирован: Пт июн 03, 2022 8:51 am

Как смотреть информацию о сессиях не суперпользователям?

Сообщение AntonS »

Из документации, в pg_stat_activity для каждого серверного процесса будет присутствовать по одной строке с информацией, относящейся к текущей деятельности этого процесса.

Однако на практике в результатах запроса к pg_stat_activity, выполненного обычным пользоваетелем, в столбце query для других процессов insufficient privilege, отсутствуют значения других важных столбцов.

Код: Выделить всё

demo=> SELECT * FROM pg_stat_activity WHERE datname='postgres';
 datid | datname  | pid  | leader_pid | usesysid | usename  |     application_name     | client_addr | client_hostname | client_port | backend_start | xact_start | query_start | state_change | wait_event_type | wait_event | state | backend_xid | backend_xmin | query_id |          query           | backend_type
-------+----------+------+------------+----------+----------+--------------------------+-------------+-----------------+-------------+---------------+------------+-------------+--------------+-----------------+------------+-------+-------------+--------------+----------+--------------------------+--------------
     5 | postgres | 2792 |            |       10 | postgres | pgp-s supervisor         |             |                 |             |               |            |             |              |                 |            |       |             |              |          | <insufficient privilege> |
     5 | postgres | 2836 |            |       10 | postgres | pgp-s manager [postgres] |             |                 |             |               |            |             |              |                 |            |       |             |              |          | <insufficient privilege> |
(2 rows)
Вывод статистики в pg_stat_activity представляет собой таблицу на основе функции pg_stat_get_activity. Если заглянуть в исходный код функции PostgreSQL https://doxygen.postgresql.org/pgstatfu ... ource.html, то эта функция, прежде чем вывести значения о других процессов проверяет, есть ли у пользователя роль pg_read_all_stats:

Код: Выделить всё

#define HAS_PGSTAT_PERMISSIONS      (role)       (has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS) || has_privs_of_role(GetUserId(), role))
Если этой роли у пользователя нет, то для чужих сессий в столбце query выводится "<insufficient privilege>", а еще в ряде столбцов null:

Код: Выделить всё

else
  620  {
  621  /* No permissions to view data about this session */
  622  values[5] = CStringGetTextDatum("<insufficient privilege>");
  623  nulls[4] = true;
  624  nulls[6] = true;
 625  nulls[7] = true;
  626  nulls[8] = true;
  627  nulls[9] = true;
  628  nulls[10] = true;
  629  nulls[11] = true;
  630  nulls[12] = true;
  631  nulls[13] = true;
  632  nulls[14] = true;
  633  nulls[17] = true;
  634  nulls[18] = true;
  635  nulls[19] = true;
  636  nulls[20] = true;
  637  nulls[21] = true;
  638  nulls[22] = true;
  639  nulls[23] = true;
  640  nulls[24] = true;
  641  nulls[25] = true;
  642  nulls[26] = true;
  643  nulls[27] = true;
  644  nulls[28] = true;
  645  nulls[29] = true;
  646  nulls[30] = true;
  647  }
Действительно, документация содержит предопределённую роль pg_read_all_stats, и если назначить её пользователю, то он сможет просматривать информацию о сессиях в pg_stat_activity

Здесь же описана более общая роль pg_monitor, позволяющая Читать/выполнять различные представления и функции для мониторинга. Эта роль включена в роли pg_read_all_settings, pg_read_all_stats и pg_stat_scan_tables.

В последнем предложении на первый взгляд любопытная формулировка, роль pg_monitor включена в роли pg_read ..., по правилу включения ролей разве не должно быть наоборот?

Если заглянуть в англоязычную документацию, то получается действительно включена в роли: This role is a member of pg_read_all_settings, pg_read_all_stats and pg_stat_scan_tables.

И это совпадает с тем, что выводит PostgreSQL:

Код: Выделить всё

postgres=# \drg pg_monitor
                     List of role grants
 Role name  |      Member of       |   Options    | Grantor
------------+----------------------+--------------+----------
 pg_monitor | pg_read_all_settings | INHERIT, SET | postgres
 pg_monitor | pg_read_all_stats    | INHERIT, SET | postgres
 pg_monitor | pg_stat_scan_tables  | INHERIT, SET | postgres
(3 rows)
Ответить