Если пользователь не может быть удален из базы данных, всегда будет выдаваться ошибка Как очистить зависимости?

Аннотация: в этой статье в основном рассказывается, как идентифицировать и очищать различные пользовательские зависимости, а также кратко рассказывается о рекомендуемом методе управления разрешениями.

Эта статья опубликована в сообществе Huawei Cloud Community « Пользователи GaussDB (DWS) всегда сообщают об ошибках, когда их невозможно удалить. Как очистить зависимости?» ", от Малика.

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

В этой статье в основном рассказывается, как идентифицировать и очищать различные зависимости пользователей, а также кратко рассказывается о рекомендуемом методе управления разрешениями.

Общие проблемы, с которыми сталкиваются базы данных postgres — роль «test1» не может быть удалена, потому что от нее зависят некоторые объекты.

Как показано на рисунке ниже, при удалении пользователя test1 появляется следующее приглашение:

testdb=# drop user test1;
ERROR:  role "test1" cannot be dropped because some objects depend on it
DETAIL:  owner of database testdb
3 objects in database postgres

Описание подсказки ERROR:

  • Текущий пользователь является владельцем базы данных testdb.
  • В базе данных postgres есть 3 зависимых объекта.

Хорошо, тогда мы разберемся с этим один раз в соответствии с оперативной информацией

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

Способ 1. Передать владельца БД другому пользователю, например, пользователю-грантодателю следующим образом

testdb=# alter database testdb owner to grantor;
ALTER DATABASE
testdb=# \l
                                   List of databases
   Name    |   Owner   | Encoding |   Collate   | Ctype |    Access privileges
-----------+-----------+----------+-------------+-------------+-------------------------
 testdb | grantor   | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
(4 rows)
-- 可以看到删除后,不会再报owner database的信息
testdb=# drop user test1;
ERROR:  role "test1" cannot be dropped because some objects depend on it
DETAIL: 3 objects in database postgres

Способ 2. Если вам не нужна библиотека, вы также можете удалить ее напрямую

PS: Для объектов, не являющихся базой данных: таблиц или схем и т. д., вы можете использовать следующий метод, чтобы передать их всем другим пользователям.

-- owner转移
testdb=#  REASSIGN OWNED BY test1 TO grantor;
REASSIGN OWNED
-- 清理owner是test1的对象,慎用,会将用户同名的schema也一同清理掉。
testdb=# drop owned by test1;
DROP OWNED

Далее была обработана подсказка нашего владельца, и подсказка следующего шага: 3 объекта в базе данных postgres

Это означает, что в postgres есть 3 объекта, которые зависят от этого пользователя. Из-за зависимости от системной таблицы в библиотеке подробная информация о зависимых объектах не будет распечатываться в других базах данных, поэтому при выполнении пользователя drop в библиотеке postgres будет распечатана конкретная информация.

Подключение к библиотеке postgres выполняется следующим образом:

postgres=# drop user test1;
ERROR:  role "test1" cannot be dropped because some objects depend on it
DETAIL:  privileges for table pg_class
privileges for schema grantor

Как вы можете видеть здесь, есть две зависимости:

  • привилегии для таблицы pg_class: привилегии пользователя test1 в pg_class
  • Разрешения пользователя test1 на схемографе

Затем мы можем напрямую просмотреть разрешения, соответствующие этим двум объектам, и удалить их.

postgres=# select relname,relacl from pg_class where relname = 'pg_class';
 relname | relacl
----------+----------------------------------
 pg_class | {=r/superuser,test1=r/superuser}
(1 row)
postgres=# select nspname,nspacl from pg_namespace where nspname = 'grantor';
 nspname | nspacl
---------+---------------------------------------------------------
 grantor | {grantor=UC/grantor,grantor=LP/grantor,test1=U/grantor}
(1 row)
postgres=# revoke select on table pg_class from test1;
REVOKE
postgres=# revoke usage on schema grantor from test1;
REVOKE
postgres=# drop user test1;
DROP USER

В это время, если пользователь будет удален, других зависимостей не будет.

postgres=# drop user test1;
DROP USER

PS: Как мы будем работать, если мы не знаем конкретный объект и не можем его удалить? Здесь мы создаем кейс в качестве демонстрации, создаем нового пользователя test2 и даем ему разрешение на выбор грантодателя. В это время, мы не можем бросить

testdb2=# drop user test2;
ERROR:  role "test2" cannot be dropped because some objects depend on it
DETAIL: 2 objects in database postgres

Фактическим внутренним хранилищем зависимостей пользователя является системная таблица pg_shdepend, в которой записываются oids и их зависимости для каждого зависимого объекта. Сначала мы получаем oid пользователя, а затем идем в системную таблицу, чтобы найти соответствующую запись зависимости.

testdb2=# select oid ,rolname from pg_roles where rolname = 'test2';
 oid | rolname
------------+---------
 2147484573 | test2
(1 row)
postgres=# select * from pg_shdepend where refobjid = 2147484573;
 dbid | classid | objid | objsubid | refclassid | refobjid | deptype | objfile
-------+---------+------------+----------+------------+------------+---------+---------
 16073 | 2615 | 2147484575 | 0 | 1260 | 2147484573 | o       |
 16073 | 2615 | 2147484025 | 0 | 1260 | 2147484573 | a       |
(2 rows)
这里由于dependType不同,因此有两条记录,一个代表权限依赖(a),一个代表自身是一个对象的owner。

После того, как мы получим classid, он представляет собой идентификатор таблицы записей объекта, который зависит от текущего пользователя, затем мы можем найти эту зависимость в таблице pg_class:

postgres=# select relname,relacl from pg_class where oid = 2615;
 relname | relacl
--------------+----------------
 pg_namespace | {=r/d00467397}
(1 row)

Хорошо, увидев, что таблица записей — это pg_namespace, можно подтвердить, что зависимый пользователь — это схема. Перейдите к pg_namespace здесь, проверьте objid, полученный выше, и вы узнаете конкретный объект

postgres=# select nspname,nspacl from pg_namespace where oid in (2147484575,2147484025);
 nspname | nspacl
---------+---------------------------------------------------------
 test2   |
 grantor | {grantor=UC/grantor,grantor=LP/grantor,test2=U/grantor}
(2 rows)

Здесь вы можете видеть, что есть две схемы, одна — схема с тем же именем, что и у пользователя, а другая — только что уполномоченный доверитель.

postgres=# revoke usage on schema grantor from test2;
REVOKE
postgres=# drop user test2;
DROP USER

 

Нажмите, чтобы подписаться и узнать о свежих технологиях Huawei Cloud впервые~

Выпускники Национального народного университета украли информацию обо всех студентах школы, чтобы создать веб-сайт для оценки красоты, и были задержаны в уголовном порядке.Официально выпущена новая версия QQ для Windows, основанная на архитектуре NT.Соединенные Штаты ограничат использование Китая Amazon, Microsoft и других облачных сервисов, обеспечивающих обучение моделей ИИ Проекты с открытым исходным кодом объявили о прекращении разработки функций функции изображения терминала Количество регистраций потоков превысило 30 миллионов. «Изменение» Deepin использует Asahi Linux, чтобы адаптироваться к рейтингу базы данных Apple M1 в июле: Oracle растет, снова открывая счет
{{о.имя}}
{{м.имя}}

рекомендация

отmy.oschina.net/u/4526289/blog/10086108