F.52. pgpro_usage — статистика отношений и функций в разрезе пользователей #
Расширение pgpro_usage
предоставляет статистику доступа к отношениям и вызовов функций в разрезе пользователей.
Примечание
Если сервер выключен, собранная pgpro_usage статистика хранится в файле $PGDATA/pg_stat/pgpro_usage.stat
. Чтобы сохранить статистику при переключении на резервный сервер, вам нужно вручную скопировать файл с предыдущего основного сервера или восстановить его из резервной копии.
F.52.1. Установка расширения pgpro_usage
#
Расширение pgpro_usage
включено в состав Postgres Pro Enterprise как стандартное расширение. Чтобы задействовать pgpro_usage
, выполните следующие действия:
Добавьте
pgpro_usage
в переменнуюshared_preload_libraries
в файлеpostgresql.conf
:shared_preload_libraries = 'pgpro_usage'
Перезапустите сервер базы данных, чтобы изменения вступили в силу. Чтобы убедиться, что библиотека
pgpro_usage
установлена корректно, вы можете выполнить следующую команду:SHOW shared_preload_libraries;
Создайте расширение
pgpro_usage
, выполнив следующий запрос:CREATE EXTENSION pgpro_usage;
F.52.2. Удаление расширения pgpro_usage
#
Чтобы корректно удалить расширение pgpro_usage
, выполните следующие действия:
Удалите расширение
pgpro_usage
, выполнив следующий запрос:DROP EXTENSION pgpro_usage;
Удалите
pgpro_usage
из переменнойshared_preload_libraries
в файлеpostgresql.conf
.
F.52.3. Функции #
Чтобы собирать статистику доступа отношений и вызовов функций в разрезе пользователей, pgpro_usage
предоставляет SQL-интерфейс, состоящий из нескольких функций и представлений.
F.52.3.1. Функции для сбора статистики отношений в разрезе пользователей #
pg_stat_get_read_req_per_user
(targetoid
oid
,roleoid
oid
) →BIGINT
Возвращает число запросов пользователя/роли, указанной в
roleoid
, на чтение таблицы/индекса, указанного вtargetoid
.pg_stat_get_insert_req_per_user
(targetoid
oid
,roleoid
oid
) →BIGINT
Возвращает число запросов пользователя/роли, указанной в
roleoid
, на вставку данных в таблицу, указанную вtargetoid
.pg_stat_get_update_req_per_user
(targetoid
oid
,roleoid
oid
) →BIGINT
Возвращает число запросов пользователя/роли, указанной в
roleoid
, на обновление данных в таблице, указанной вtargetoid
.pg_stat_get_delete_req_per_user
(targetoid
oid
,roleoid
oid
) →BIGINT
Возвращает число запросов пользователя/роли, указанной в
roleoid
, на удаление данных из таблицы, указанной вtargetoid
.pg_stat_get_truncate_req_per_user
(targetoid
oid
,roleoid
oid
) →BIGINT
Возвращает число запросов пользователя/роли, указанной в
roleoid
, на опустошение таблицы, указанной вtargetoid
.pg_stat_get_grants_given_per_user
(targetoid
oid
,roleoid
oid
) →BIGINT
Возвращает число команд
GRANT
иREVOKE
, выполненных пользователем/ролью, указанной вroleoid
, для таблицы, указанной вtargetoid
.pg_stat_get_last_read_per_user
(targetoid
oid
,roleoid
oid
) →timestamp with timezone
Возвращает дату и время, когда пользователь/роль, указанная в
roleoid
, в последний раз выполнилаSELECT
для таблицы, указанной вtargetoid
.pg_stat_get_last_insert_per_user
(targetoid
oid
,roleoid
oid
) →timestamp with timezone
Возвращает дату и время, когда пользователь/роль, указанная в
roleoid
, в последний раз выполнилаINSERT
для таблицы, указанной вtargetoid
.pg_stat_get_last_update_per_user
(targetoid
oid
,roleoid
oid
) →timestamp with timezone
Возвращает дату и время, когда пользователь/роль, указанная в
roleoid
, в последний раз выполнилаUPDATE
для таблицы, указанной вtargetoid
.pg_stat_get_last_delete_per_user
(targetoid
oid
,roleoid
oid
) →timestamp with timezone
Возвращает дату и время, когда пользователь/роль, указанная в
roleoid
, в последний раз выполнилаDELETE
для таблицы, указанной вtargetoid
.pg_stat_get_last_truncate_per_user
(targetoid
oid
,roleoid
oid
) →timestamp with timezone
Возвращает дату и время, когда пользователь/роль, указанная в
roleoid
, в последний раз выполнилаTRUNCATE
для таблицы, указанной вtargetoid
.
F.52.3.2. Функции для сбора статистики функций в разрезе пользователей #
pg_stat_get_func_calls_per_user
(targetoid
oid
,roleoid
oid
) →BIGINT
Возвращает число вызовов функции, указанной в
targetoid
, пользователем/ролью, указанной вroleoid
.pg_stat_get_func_grants_given_per_user
(targetoid
oid
,roleoid
oid
) →BIGINT
Возвращает число команд
GRANT
иREVOKE
, выполненных пользователем/ролью, указанной вroleoid
, для функции, указанной вtargetoid
.
F.52.3.3. Сервисные функции #
pgpro_usage_reset
(full_reset
bool
default false) →void
Сбрасывает статистику pgpro_usage. Если для параметра
full_reset
задано значениеtrue
, сбрасывается вся статистика. Если для параметраfull_reset
задано значениеfalse
, сброс не затрагивает статистику последнего использования таблиц.pgpro_usage_get_last_reset_time
() →timestamp with time zone
Время последнего сброса статистики pgpro_usage.
F.52.4. Представления #
F.52.4.1. Представление pg_stat_all_tables_per_user
#
Представление pg_stat_all_tables_per_user
содержит по одной строке для каждой комбинации пользователя/роли и таблицы в текущей базе данных (включая TOAST-таблицы) и показывает статистику разных типов запросов пользователей к таблицам.
Таблица F.43. Столбцы pg_stat_all_tables_per_user
Столбец Тип Описание |
---|
OID пользователя/роли |
Имя пользователя/роли |
OID таблицы |
Имя схемы, в которой находится эта таблица |
Имя этой таблицы |
Число запросов этого пользователя/роли на чтение этой таблицы |
Число запросов этого пользователя/роли на вставку данных в эту таблицу |
Число запросов от пользователя/роли на обновление данных в этой таблице |
Число запросов этого пользователя/роли на удаление данных из этой таблицы |
Число запросов пользователя/роли на опустошение этой таблицы |
Число команд |
F.52.4.2. Представление pg_stat_all_tables_last_usage
#
Представление pg_stat_all_tables_last_usage
содержит одну строку для каждой комбинации пользователя/роли и таблицы в текущей базе данных (включая TOAST-таблицы) и показывает дату и время последнего выполнения пользователями операций с таблицами.
Таблица F.44. Столбцы pg_stat_all_tables_last_usage
Столбец Тип Описание |
---|
OID пользователя/роли |
Имя пользователя/роли |
Имя пространства имён |
OID таблицы |
Имя этой таблицы |
Дата и время последнего чтения этой таблицы этим пользователем/ролью |
Дата и время последней вставки данных в эту таблицу этим пользователем/ролью |
Дата и время последнего обновления этой таблицы этим пользователем/ролью |
Дата и время последнего удаления данных из этой таблицы этим пользователем/ролью |
Дата и время последнего опустошения этой таблицы этим пользователем/ролью |
F.52.4.3. Представление pg_stat_all_functions_per_user
#
Представление pg_stat_all_functions_per_user
содержит по одной строке для каждой комбинации пользователя/роли и пользовательской функции/хранимой процедуры/системной функции в текущей базе данных и показывает статистику вызовов функций и выдачи прав пользователями.
Таблица F.45. Столбцы pg_stat_all_functions_per_user
Столбец Тип Описание |
---|
OID пользователя/роли |
Имя пользователя/роли |
OID функции |
Имя схемы, в которой находится функция |
Имя этой функции |
Число вызовов этой функции этим пользователем/ролью |
Число команд |
F.52.4.4. Представление pgpro_usage_stats_privileges_usage
#
Представление pgpro_usage_stats_privileges_usage
содержит по одной строке для каждой комбинации роли, права и объекта (таблицы или функции), на который роли имеют права. Строки показывают, каким образом были выданы права и были ли они использованы.
Таблица F.46. Столбцы pgpro_usage_stats_privileges_usage
Столбец Тип Описание |
---|
Имя пользователя |
Тип права: |
Имя схемы, в которой находится объект (таблица или функция) |
Имя этого объекта (таблицы или функции) |
Имя роли, членство в которой позволило этой роли получить это право |
Имя роли, членство в которой позволило этой роли получить это право, или "public", если это право было выдано всем ролям с помощью |
Тип объекта: |
Было ли использовано это право |
F.52.5. Параметры конфигурации #
pgpro_usage.max
(integer
)Определяет максимальное число пар объект-пользователь, которое хранит статистика. Объектом может быть таблица, функция или процедура. Вы можете уменьшить это значение для экономии памяти или увеличить его при использовании больших баз данных. Если расширению pgpro_usage требуется превысить заданное значение при записи статистики, новая запись не создаётся и отображается предупреждение «WARNING: max number of pgpro_usage records exceeded» (ПРЕДУПРЕЖДЕНИЕ: превышено максимальное число записей pgpro_usage).
Значение по умолчанию —
10000
.
F.52.6. Пример #
Этот пример демонстрирует использование расширения pgpro_usage.
Сначала создадим расширение:
postgres=# create extension pgpro_usage; CREATE EXTENSION
Теперь просмотрим статистику использования. Для этого создадим пользователя, таблицу и процедуру, после чего выдадим пользователю доступ к таблице:
postgres=# CREATE USER u1; CREATE ROLE postgres=# CREATE TABLE t1(val int); CREATE TABLE postgres=# GRANT all on t1 to u1; GRANT postgres=# CREATE PROCEDURE p1() AS $$ BEGIN RAISE NOTICE 'Here we are'; END; $$ LANGUAGE plpgsql; CREATE PROCEDURE
Выведем статистику использования всех таблиц:
postgres=# SELECT * FROM pg_stat_all_tables_per_user; userid | username | relid | nspname | relname | n_reads | n_inserts | n_updates | n_deletes | n_truncates | n_grants_given --------+----------+-------+---------+---------+---------+-----------+-----------+-----------+-------------+---------------- 10 | postgres | 16445 | public | t1 | 0 | 0 | 0 | 0 | 0 | 1 (1 row)
Сделаем то же самое для всех функций:
postgres=# SELECT * FROM pg_stat_all_functions_per_user; userid | username | funcid | nspname | funcname | calls | grants_given --------+----------+--------+---------+----------------------------------------+-------+-------------- 10 | postgres | 16385 | public | pgpro_usage_reset | 0 | 1 10 | postgres | 16386 | public | pgpro_usage | 0 | 1 10 | postgres | 16387 | public | pgpro_usage_full | 0 | 1 10 | postgres | 16397 | public | pg_stat_get_func_calls_per_user | 2 | 0 10 | postgres | 16398 | public | pg_stat_get_func_grants_given_per_user | 1 | 0 10 | postgres | 16399 | public | pg_stat_get_read_req_per_user | 1 | 0 10 | postgres | 16400 | public | pg_stat_get_insert_req_per_user | 1 | 0 10 | postgres | 16401 | public | pg_stat_get_update_req_per_user | 1 | 0 10 | postgres | 16402 | public | pg_stat_get_delete_req_per_user | 1 | 0 10 | postgres | 16403 | public | pg_stat_get_truncate_req_per_user | 1 | 0 10 | postgres | 16404 | public | pg_stat_get_grants_given_per_user | 1 | 0 (11 rows)
Приведённый выше вывод содержит только действия суперпользователя, который выдал доступ к таблице и несколько раз вызвал функции расширения при отправке запросов к приведённым выше представлениям. Столбец grants_given
ненулевой в трёх строках. Они соответствуют отзыву прав у public
при создании расширения. Созданный пользователь не включён в статистику, так как он не выполнял никаких действий.
Восполним этот пробел и подключимся к базе данных как пользователь u1
.
postgres=# \c - u1 You are now connected to database "postgres" as user "u1". postgres=> insert into t1(val) values (1); INSERT 0 1 postgres=> insert into t1(val) values (2); INSERT 0 1 postgres=> select * from t1; val ----- 1 2 (2 rows) postgres=> call p1(); NOTICE: Here we are CALL
Мы выполнили две вставки в таблицу, отправили к ней один запрос и один раз вызвали процедуру. Переключимся обратно на суперпользователя и снова просмотрим статистику:
postgres=> \c - postgres You are now connected to database "postgres" as user "postgres". postgres=# SELECT * FROM pg_stat_all_tables_per_user; userid | username | relid | nspname | relname | n_reads | n_inserts | n_updates | n_deletes | n_truncates | n_grants_given --------+----------+-------+---------+---------+---------+-----------+-----------+-----------+-------------+---------------- 16444 | u1 | 16445 | public | t1 | 1 | 2 | 0 | 0 | 0 | 0 10 | postgres | 16445 | public | t1 | 0 | 0 | 0 | 0 | 0 | 1 (2 rows) postgres=# SELECT * FROM pg_stat_all_functions_per_user; userid | username | funcid | nspname | funcname | calls | grants_given --------+----------+--------+---------+----------------------------------------+-------+-------------- 10 | postgres | 16385 | public | pgpro_usage_reset | 0 | 1 10 | postgres | 16386 | public | pgpro_usage | 0 | 1 10 | postgres | 16387 | public | pgpro_usage_full | 0 | 1 10 | postgres | 16397 | public | pg_stat_get_func_calls_per_user | 4 | 0 10 | postgres | 16398 | public | pg_stat_get_func_grants_given_per_user | 2 | 0 10 | postgres | 16399 | public | pg_stat_get_read_req_per_user | 2 | 0 10 | postgres | 16400 | public | pg_stat_get_insert_req_per_user | 2 | 0 10 | postgres | 16401 | public | pg_stat_get_update_req_per_user | 2 | 0 10 | postgres | 16402 | public | pg_stat_get_delete_req_per_user | 2 | 0 10 | postgres | 16403 | public | pg_stat_get_truncate_req_per_user | 2 | 0 10 | postgres | 16404 | public | pg_stat_get_grants_given_per_user | 2 | 0 16444 | u1 | 16448 | public | p1 | 1 | 0 (12 rows)
Обе таблицы теперь содержат строки, соответствующие операциям пользователя u1
: две вставки и одно чтение таблицы, а также одно выполнение процедуры.
Теперь просмотрим статистику последнего использования. Мы сможем увидеть временные метки, показывающие, когда пользователь выполнил вставку и чтение.
postgres=# select * from pg_stat_all_tables_last_usage; userid | username | nspname | relid | relname | last_read | last_insert | last_update | last_delete | last_truncate --------+----------+---------+-------+---------+-------------------------------+------------------------------+-------------+-------------+--------------- 16444 | u1 | public | 16445 | t1 | 2024-11-30 01:06:24.578642+03 | 2024-11-30 01:06:17.03442+03 | | | (1 row)
Дополним статистику чтением от суперпользователя:
postgres=# select * from t1; val ----- 1 2 (2 rows) postgres=# select * from pg_stat_all_tables_last_usage; userid | username | nspname | relid | relname | last_read | last_insert | last_update | last_delete | last_truncate --------+----------+---------+-------+---------+-------------------------------+------------------------------+-------------+-------------+--------------- 10 | postgres | public | 16445 | t1 | 2024-11-30 01:09:29.994188+03 | | | | 16444 | u1 | public | 16445 | t1 | 2024-11-30 01:06:24.578642+03 | 2024-11-30 01:06:17.03442+03 | | | (2 rows)
Убедимся, что временная метка last_read
обновилась:
postgres=# select * from t1; val ----- 1 2 (2 rows) postgres=# select * from pg_stat_all_tables_last_usage; userid | username | nspname | relid | relname | last_read | last_insert | last_update | last_delete | last_truncate --------+----------+---------+-------+---------+-------------------------------+------------------------------+-------------+-------------+--------------- 10 | postgres | public | 16445 | t1 | 2024-11-30 01:10:28.122489+03 | | | | 16444 | u1 | public | 16445 | t1 | 2024-11-30 01:06:24.578642+03 | 2024-11-30 01:06:17.03442+03 | | | (2 rows)
Просмотрим статистику неиспользуемых прав. Объектов, пользователей и прав может существовать много, поэтому поместим всё, что относится к этому примеру, в отдельную схему. Так будет проще фильтровать результаты. Создаём схему и таблицу внутри неё, выдаём доступ к таблице определённой групповой роли и выдаём членство в этой групповой роли отдельному пользователю:
postgres=# create schema shops; CREATE SCHEMA postgres=# create table shops.buildings(); CREATE TABLE postgres=# create role manager; CREATE ROLE postgres=# grant all on schema shops to manager; GRANT postgres=# grant all on shops.buildings to manager; GRANT postgres=# create user vasya; CREATE ROLE postgres=# grant manager to vasya; GRANT ROLE
Подключимся к базе данных от имени этого пользователя и выполним запрос к таблице:
postgres=# \c - vasya You are now connected to database "postgres" as user "vasya". postgres=> select * from shops.buildings; -- (0 rows)
Теперь переключимся на суперпользователя и просмотрим статистику прав:
postgres=> \c - postgres You are now connected to database "postgres" as user "postgres". postgres=# select * from pgpro_usage_stats_privileges_usage where usename='vasya' and nspname='shops'; usename | access | nspname | targetname | provider | grantee | kind | used ---------+----------+---------+------------+----------+---------+----------+------ vasya | INSERT | shops | buildings | manager | manager | RELATION | f vasya | SELECT | shops | buildings | manager | manager | RELATION | t vasya | UPDATE | shops | buildings | manager | manager | RELATION | f vasya | DELETE | shops | buildings | manager | manager | RELATION | f vasya | TRUNCATE | shops | buildings | manager | manager | RELATION | f (5 rows)
Статистика показывает, что пользователь vasya
имеет полный доступ к таблице shops.buildings
и все эти права он получил не напрямую, а как член групповой роли manager
. Также видно, что из всех прав пользователь vasya
использовал только SELECT
. Обратите внимание, что статистика прав не показывает права суперпользователя, так как суперпользователь имеет полный доступ.