Найти объекты, связанные с ролью PostgreSQL

12

Несколько раз назад я создал пользователя PostgreSQL с именем user1 (PostgreSQL 9.4.9).

Я хочу оставить этого пользователя. Поэтому я сначала отменил все разрешения для таблиц, последовательностей, функций, привилегий по умолчанию и владения:

ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON SEQUENCES FROM user1;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM user1;
ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON FUNCTIONS FROM user1;

REVOKE ALL ON ALL SEQUENCES IN SCHEMA public FROM user1;
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM user1;
REVOKE ALL ON ALL FUNCTIONS IN SCHEMA public FROM user1;

REASSIGN OWNED BY user1 TO postgres;

Однако кажется, что один объект остается связанным с этим пользователем в 2 базах данных:

postgres=# DROP ROLE user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  1 object in database db1
1 object in database db2

Это даже кажется функцией:

postgres=# \c db1
You are now connected to database "db1" as user "postgres".
db1=# DROP ROLE user1;
ERROR:  role "user1" cannot be dropped because some objects depend on it
DETAIL:  privileges for function text(boolean)
1 object in database db2

Но я не могу определить, какой объект принадлежит или связан с user1.

Если я pg_dump -s db1 | grep user1не получу результата! Может ли это быть глобальный объект?

Как я могу определить отсутствующий объект?

Я выполнил команды в каждой базе данных (db1 и db2). Я не хочу user1удалять объекты, принадлежащие , просто хочу переназначить или удалить гранты для этого пользователя.

Николас Пайарт
источник

Ответы:

11

Ответ на заданный вопрос

Чтобы найти функцию в сообщении об ошибке и ее владельца:

SELECT oid::regprocedure AS function
     , pg_get_userbyid(proowner) AS owner
FROM   pg_proc
WHERE  oid = 'text(boolean)'::regprocedure;

Связанные с:

Актуальная проблема

Сообщение об ошибке гласит:

DETAIL: привилегии для функционального текста (логическое значение)

Дело не в собственности, а в привилегиях .

Руководство по DROP ROLE:

Перед удалением роли вы должны удалить все принадлежащие ей объекты (или переназначить их собственность) и отозвать все привилегии, предоставленные этой роли для других объектов .

И для ALTER DEFAULT PRIVILEGES:

Если вы хотите удалить роль, для которой были изменены привилегии по умолчанию, необходимо отменить изменения в ее привилегиях по умолчанию или использовать DROP OWNEDBY, чтобы избавиться от записи привилегий по умолчанию для этой роли .

Выглядит так, как будто вы выполнялись только REASSIGN OWNEDв одной БД, но руководство инструктирует:

Поскольку REASSIGN OWNEDэто не влияет на объекты в других базах данных, обычно необходимо выполнять эту команду в каждой базе данных, которая содержит объекты, принадлежащие роли, которую необходимо удалить.

Жирный акцент мой.

И ты ограничил свои команды с IN SCHEMA public. Отбросьте это предложение, чтобы охватить всю БД. Но не беспокойтесь, есть ...

Простое решение с DROP OWNED

REASSIGN OWNED BY user1 TO postgres;
DROP OWNED BY user1;

Все объекты роли поменяли владельца postgresна первую команду и теперь в безопасности. Формулировка DROP OWNEDнемного вводит в заблуждение, поскольку она также избавляет от всех привилегий и привилегий по умолчанию. Руководство по DROP OWNED:

DROP OWNEDудаляет все объекты в текущей базе данных, которые принадлежат одной из указанных ролей. Любые привилегии, предоставленные данным ролям для объектов в текущей базе данных и для общих объектов (базы данных, табличные пространства), также будут аннулированы.

Повторите эти действия во всех соответствующих БД, затем вы можете перейти к уничтожению:

DROP ROLE user1;
Эрвин Брандштеттер
источник
6

Запрос ниже перечисляет объекты с владельцами. Для всех привилегий нам на самом деле нужно больше.

--r = ordinary table, i = index, S = sequence, v = view, m = materialized view, c = composite type, t = TOAST table, f = foreign table
SELECT 
    n.nspname AS schema_name,
    c.relname AS rel_name,
    c.relkind AS rel_kind,
    pg_get_userbyid(c.relowner) AS owner_name
  FROM pg_class c
  JOIN pg_namespace n ON n.oid = c.relnamespace

UNION ALL

-- functions (or procedures)
SELECT
    n.nspname AS schema_name,
    p.proname,
    'p',
    pg_get_userbyid(p.proowner)
  FROM pg_proc p
  JOIN pg_namespace n ON n.oid = p.pronamespace
Сахап Аски
источник
Я до сих пор не могу найти пропавший объект с этим.
Николас Пайарт
@NicolasPayart: вы выполняете запрос в нужной базе данных?
Эрвин Брандштеттер
1

Вам необходимо сначала подключиться к базе данных. В вашем случае это было бы

\c db1

а также

\c db2

Затем попробуйте снова выполнить операторы REVOKE ALL PRIVILEGES и REASSIGN OWNED / DROP OWNED.

Самуэль Аняэле
источник
1
Эй, спасибо за твой первый ответ. Однако перед публикацией подумайте, что это добавляет к существующим ответам, и опишите это в своем ответе.
Dezso