Jedes Datenbankobjekt in PostgreSQL hat einen Owner — die Rolle, der es „gehört”. Owner ist kein Privileg, das man via GRANT bekommt: es ist ein eigener Status, der sich beim Erstellen aus dem aktuellen User ergibt und nur per ALTER … OWNER TO weitergereicht werden kann. Wer Ownership versteht, versteht auch, warum man manche Rollen nicht so einfach loswird.

Was Owner können dürfen

Der Owner eines Objekts darf:

  • das Objekt droppen (DROP TABLE, DROP FUNCTION, …)
  • es umbenennen (ALTER … RENAME TO)
  • es ändern (Spalten hinzufügen, Constraints, …)
  • den Owner wechseln an eine andere Rolle, in der er Mitglied ist
  • seinerseits Privilegien an andere vergeben (GRANT)

Diese Rechte bekommt niemand sonst — auch ein User mit ALL PRIVILEGES darf eine Tabelle nicht droppen, wenn er nicht Owner ist. Es gibt nur zwei Ausnahmen: Superuser (dürfen alles) und Mitglieder der Owner-Rolle (über Inheritance).

SQL Owner und Privilegien sind getrennte Konzepte
CREATE ROLE app_owner;
CREATE ROLE app_user LOGIN PASSWORD 'changeme';

SET ROLE app_owner;
CREATE TABLE orders (id serial primary key, total numeric);
-- orders gehoert jetzt app_owner

GRANT SELECT, INSERT, UPDATE, DELETE ON orders TO app_user;

SET ROLE app_user;
DELETE FROM orders;     -- OK (DELETE-Privileg)
DROP TABLE orders;      -- ERROR: must be owner of table orders

Default-Owner

Wenn du CREATE TABLE foo (...) ohne weiteres ausführst, wird der aktuelle Effektiv-User (current_user) zum Owner. Bei einem SET ROLE app_owner; CREATE TABLE …;-Pattern landet das Eigentum entsprechend bei app_owner.

Das ist wichtig für saubere Setups: Migrations-Tools sollten unter dem Schema-Owner laufen, damit alle erzeugten Objekte zentral diesem User gehören. Sonst hast du nach drei Migrationen eine Mischung von Tabellen-Ownern, die zu späteren Problemen führt.

Owner ändern

SQL ALTER OWNER
ALTER TABLE orders OWNER TO app_owner;
ALTER FUNCTION calculate_tax(numeric) OWNER TO app_owner;
ALTER SCHEMA app OWNER TO app_owner;
ALTER DATABASE myapp OWNER TO app_owner;

Voraussetzungen, um den Owner zu wechseln:

  1. Du musst aktueller Owner sein (oder Superuser).
  2. Du musst Mitglied der Ziel-Rolle sein.
  3. Bei ALTER DATABASE … OWNER TO brauchst du zusätzlich CREATEDB-Recht oder Superuser-Status.

Was passiert beim DROP des Owners?

Hier liegt der häufigste Stolperstein. Wenn du eine Rolle droppen willst, die noch Objekte besitzt, lehnt Postgres ab:

SQL
myapp=# DROP ROLE app_owner;
ERROR:  role "app_owner" cannot be dropped because some objects depend on it
DETAIL:  owner of table orders, owner of schema app, ...

Postgres weigert sich aus gutem Grund: würden die Objekte einfach „herrenlos” sein, könnte niemand mehr sicher mit ihnen arbeiten. Du musst also vorher den Besitz übertragen oder die Objekte droppen.

REASSIGN OWNED + DROP OWNED — das Aufräum-Pattern

Postgres bietet zwei Befehle, die diesen Job übernehmen:

SQL Sauberer Drop einer Rolle mit Besitz
-- 1. Alle Objekte, die app_owner gehoeren, an postgres uebertragen:
REASSIGN OWNED BY app_owner TO postgres;

-- 2. Restliche Privilegien und Default-Privileges der Rolle aufraeumen:
DROP OWNED BY app_owner;

-- 3. Jetzt klappt der DROP:
DROP ROLE app_owner;

Was hier passiert:

  • REASSIGN OWNED überträgt das Eigentum aller Objekte, die app_owner in der aktuellen Datenbank besitzt, an die Ziel-Rolle.
  • DROP OWNED entfernt zusätzlich alle Privilegien, die der Rolle in dieser Datenbank vergeben wurden — sowohl aktive (GRANT … TO app_owner) als auch zukünftige (ALTER DEFAULT PRIVILEGES … GRANTED BY app_owner).
  • Erst dann darf DROP ROLE die Rolle entfernen.

Wichtig: Beide Befehle wirken nur in der aktuellen Datenbank. Wenn die Rolle in mehreren Datenbanken Objekte besitzt, musst du dich der Reihe nach mit jeder verbinden und den Vorgang wiederholen.

Owner-Inspektion im Katalog

Wer wissen will, wem was gehört, fragt den Systemkatalog:

SQL Tabellen-Owner pro Schema
SELECT n.nspname AS schema, c.relname AS object,
       pg_get_userbyid(c.relowner) AS owner, c.relkind
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname NOT IN ('pg_catalog','information_schema')
  AND c.relkind IN ('r','p','v','m','S')
ORDER BY 1, 2;

relkind zeigt: r = ordentliche Tabelle, p = partitionierte Tabelle, v = View, m = Materialized View, S = Sequence.

Für Schemas direkt:

SQL
SELECT nspname AS schema, pg_get_userbyid(nspowner) AS owner
FROM pg_namespace
WHERE nspname NOT LIKE 'pg_%' AND nspname <> 'information_schema';

Häufige Stolperfallen

Owner-Status taucht nicht in pg_class.relacl auf.

\dp my_table zeigt eine Spalte „Access privileges” — der Owner steht da nicht drin. Owner ist ein eigenes Feld (relowner). Wer per \d oder \dp nicht den Owner sieht, fragt mit \d+ oder direkt im Katalog nach.

ALTER OWNER scheitert, wenn du nicht Mitglied der Ziel-Rolle bist.

Du kannst Eigentum nur an eine Rolle übertragen, in der du selbst Mitglied bist (oder Superuser). Sonst könnte man Objekte beliebig „verschenken” — was die Aufräum-Konsistenz brechen würde. Vor ALTER … OWNER TO also kurz \du und prüfen.

REASSIGN OWNED arbeitet nur in der aktuellen Datenbank.

Klassischer Fehler: REASSIGN OWNED BY old_user TO postgres; wird in myapp ausgeführt, dann DROP ROLE old_user versucht — und Postgres bemängelt weiterhin Abhängigkeiten, weil old_user in analytics_db ebenfalls Tabellen besitzt. Lösung: in jede betroffene Datenbank verbinden und den Befehl wiederholen.

DROP OWNED loescht auch Default-Privileges.

Wenn app_owner mal ein ALTER DEFAULT PRIVILEGES FOR ROLE app_owner GRANT … TO app_user gesetzt hat, entfernt DROP OWNED BY app_owner auch diese Regel. Das ist gewollt — sonst hinge die Default-Privilege-Definition an einer nicht mehr existierenden Rolle.

Owner-Wechsel ist nicht reversibel ohne Wissen.

Wer „mal eben” alle Tabellen einer App von old_user auf postgres schiebt, hat eine durcheinander gewürfelte Eigentümer-Landschaft. Das ist gefährlich, wenn neue Migrationen mit Annahmen über den Schema-Owner laufen. Faustregel: Eigentum gehört zur Architektur — nicht ins Reaktive.

Cloud-Postgres limitiert OWNER-Operationen.

Auf RDS/Cloud SQL kannst du Objekte nicht ohne weiteres an postgres (Cloud-Superuser) übergeben — der Anbieter-User ist meist rds_superuser o. ä. Vor dem Aufräumen prüfen, welche Master-Rolle vorgesehen ist, sonst wirst du den User nie ganz los.

Weiterführende Ressourcen

Externe Quellen

/ Weiter

Zurück zu Server-Administration

Zur Übersicht