Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!
PostgreSQL
Jak odebrać uprawnienia i usunąć rolę, która jest właścicielem obiektów
Usunięcie użytkownika brzmi jak jedno polecenie, a kończy się komunikatem błędu: PostgreSQL odmawia skasowania roli, która jest właścicielem obiektów albo ma gdzieś nadane uprawnienia. To zabezpieczenie, nie kaprys - baza nie chce zostawić tabel bez właściciela ani wiszących wpisów uprawnień. Cała sztuka polega na uporządkowaniu zależności we właściwej kolejności: najpierw oddajemy własność, potem odbieramy nadania, i dopiero na końcu usuwamy rolę.
Pracownik odchodzi, chcesz posprzątać jego konto i wykonujesz DROP ROLE jan;. Zamiast potwierdzenia dostajesz: ERROR: role "jan" cannot be dropped because some objects depend on it, a poniżej DETAIL: owner of table raporty, owner of sequence raporty_id_seq, privileges for table klienci. Baza wylicza wszystko, co blokuje usunięcie: obiekty, których jan jest właścicielem, oraz uprawnienia, które ma na cudzych tabelach. Próbujesz usunąć samą tabelę, ale to nie Twój obiekt i nie chcesz kasować danych - chcesz je tylko przepisać na kogoś innego. Bywa też trudniej: jan jest właścicielem obiektów w kilku bazach, a komunikat o zależnościach dotyczy każdej z nich osobno.
Każdy obiekt w PostgreSQL - tabela, sekwencja, widok, funkcja, schemat - ma właściciela, którym jest jakaś rola. Gdyby baza pozwoliła usunąć rolę będącą właścicielem, obiekty zostałyby osierocone, bez podmiotu odpowiedzialnego za uprawnienia. Dlatego silnik blokuje DROP ROLE, dopóki istnieje choć jedna taka zależność. Do tego dochodzą uprawnienia nadane roli na obiektach należących do innych (na przykład GRANT SELECT na cudzej tabeli) - te wpisy również trzymają rolę przy życiu. Ważny szczegół: zależności są lokalne dla bazy danych. Rola jest bytem globalnym w klastrze, ale jej własność i uprawnienia dotyczą konkretnych obiektów w konkretnych bazach, więc porządki trzeba zrobić w każdej bazie, w której rola coś posiada lub gdzie ma nadania. PostgreSQL daje na to wygodne polecenia zbiorcze, dzięki którym nie trzeba przechodzić obiekt po obiekcie.
DROP ROLE wylicza część zależności, ale pełen obraz da wyszukanie obiektów, których rola jest właścicielem - w psql pomocne bywa filtrowanie po właścicielu, na przykład \dt pokazuje kolumnę Owner.REASSIGN OWNED BY jan TO archiwum;. To przeniesie tabele, sekwencje, widoki i pozostałe obiekty na rolę archiwum, nie ruszając danych.DROP OWNED BY jan;. Po REASSIGN OWNED zostają głównie wpisy uprawnień, które to polecenie sprząta.jan był właścicielem lub miał nadania - zależności są per-baza, więc jedna baza nie załatwia pozostałych.REVOKE grupa_raportujacych FROM jan;. To domyka powiązania na poziomie ról.DROP ROLE jan;. Bez pozostałych zależności polecenie przejdzie bez błędu.Najprostszy dowód to samo udane DROP ROLE jan; - jeśli przechodzi, żadna zależność już nie została. Zanim je wykonasz, warto potwierdzić, że przepisanie własności zadziałało: SELECT tablename, tableowner FROM pg_tables WHERE tableowner = 'jan'; powinno zwrócić pusty wynik, a te same tabele mają teraz właściciela archiwum. Że rola faktycznie zniknęła z całego klastra, sprawdzisz przez SELECT rolname FROM pg_roles WHERE rolname = 'jan'; - brak wiersza oznacza sukces (rola jest obiektem globalnym, więc wystarczy sprawdzić raz). Jeśli DROP ROLE nadal zgłasza zależności, przeczytaj sekcję DETAIL komunikatu: wskaże bazę i obiekt, który pominąłeś - najczęściej to inna baza, w której nie powtórzyłeś REASSIGN OWNED i DROP OWNED.
Wróć do listy: 100 najczęstszych pytań i problemów z PostgreSQL

Sprawdź szkolenie: Administracja, replikacja i tuning baz danych PostgreSQL
To szkolenie może być dofinansowane z KFS lub BUR.
★★★★★Średnia ocena naszych szkoleń w Google: 5/5

Sprawdź szkolenie: Zaawansowana administracja PostgreSQL (HA, DR, monitoring, skalowanie)
To szkolenie może być dofinansowane z KFS lub BUR.
★★★★★Średnia ocena naszych szkoleń w Google: 5/5
Komentarze (0)
Brak komentarzy...