Backups
Warum in deinem Supabase-Dump keine Nutzer stehen
Führe supabase db dump allein aus und du bekommst die Form deiner Datenbank und keine einzige Zeile, und das auth-Schema mit deinen Nutzern fehlt ganz.

Kurz gesagt
- Supabase veröffentlicht sein Backup als drei Befehle. Den, den du vermutlich ausgeführt hast, ist der zweite, und deine Nutzer stecken im dritten.
- Führe supabase db dump ohne weitere Flags aus und du bekommst die Form deiner Tabellen und nichts von ihrem Inhalt, und das auth-Schema mit deinen Nutzern fehlt sogar darin.
- Eine einzige Suche in der Datei, die du schon hast, sagt dir, welches von drei Dingen du in der Hand hältst.
Du hast das Vernünftige getan. Du hast nachgeschlagen, wie man eine Supabase-Datenbank sichert, den gefundenen Befehl ausgeführt und die Datei an einen sicheren Ort gelegt.
Dann brauchst du sie eines Tages. Du spielst die Datei in ein frisches Projekt
ein, und die Wiederherstellung läuft ohne einen einzigen Fehler durch. Jede
Tabelle, die du je angelegt hast, ist da, und jede einzelne davon ist leer.
Deine Nutzer sind noch schlechter dran: Der Teil der Datenbank, in dem sie
leben, ein Schema namens auth, hat die Datei nie erreicht.
Hier ist der Teil, den fast jede Anleitung überspringt: supabase db dump
allein ist keine Kopie deiner Daten. Ohne weitere Flags schreibt es die Form
deiner Datenbank und nichts von ihrem Inhalt, und auth lässt es sogar dabei
weg. Supabase veröffentlicht das Backup als drei Befehle, und deine Konten
fahren im dritten mit.
Es hilft, an ein Hotel zu denken. Deine Tabellen sind die Zimmer und alles darin. Das Gästebuch an der Rezeption, das mit jedem Namen darin, gehört dem Hotel. Und ein Grundriss zeigt dir jedes Zimmer im Haus, ohne einen einzigen Gast hineinzustellen.
Enthält ein Supabase-Backup meine Nutzer?
Das hängt davon ab, welcher Befehl die Datei geschrieben hat, und der Befehl, den die meisten ausführen, tut es nicht.
Deine Nutzer sind keine Zeilen in einer deiner eigenen Tabellen. Supabase hält
sie in einer eigenen Schublade derselben Datenbank, dem auth-Schema,
zusammen mit ihren gehashten Passwörtern, den Anbietern, über die sie sich
angemeldet haben, und den Sitzungen, die sie halten. Deine eigenen Tabellen
sitzen in einer Schublade namens public, und jede user_id-Spalte darin ist
ein Verweis hinüber nach auth.
Ein Schema ist genau das: eine benannte Schublade in einer Datenbank. public
gehört dir. auth gehört Supabase, und storage auch, in dem die Zeile liegt,
die jede hochgeladene Datei beschreibt. Supabases eigene Dokumentation nennt
diese seine verwalteten Schemas und sagt, dass sie
normalerweise nicht gezogen werden müssen, solange du sie nicht verändert hast,
weshalb das Werkzeug sie anders behandelt als deine Tabellen.
Diese Teilung ist es, die einen Befehl zwei Dateien schreiben lässt, die einander gleichen und völlig Verschiedenes enthalten.
Was der Dump-Befehl allein schreibt
Den Grundriss. Keine Zeilen, und nichts aus auth.
Supabases Referenzseite zu dem Befehl sagt es in zwei Sätzen. Er führt
pg_dump mit zusätzlichen Flags aus, um die von Supabase verwalteten Schemas
auszuschließen, und zu den ignorierten
gehören auth, storage und die von Erweiterungen angelegten.
Dieselbe Seite sagt dann, dass der Standard-Dump keine Daten und keine eigenen
Rollen enthält und dass du sie bekommst, indem du mit --data-only und
--role-only danach fragst.
Das hier also, das du vermutlich ausgeführt hast:
supabase db dump --db-url "postgresql://…your connection string…" -f backup.sql
erzeugt eine Datei voller CREATE TABLE-Anweisungen. Jede Spalte, jeder Index,
jede Policy, die du auf deinen eigenen Tabellen geschrieben hast, und keine
einzige Zeile von irgendetwas.
Der Grund, warum das schlimmer ist als eine offensichtlich leere Datei, ist, dass sie funktioniert. Klein ist sie auch nicht erkennbar: Jede Tabellendefinition, jeder Index und jede Policy, die du je geschrieben hast, steht darin, und das ist bei einer echten App eine Menge Text. Ein leeres Backup meldet sich von selbst. Dieses spielt sauber ein, und das Erste, was dir etwas anderes sagt, ist eine Anmeldeseite, an der kein Konto vorbeikommt.
Wie prüfe ich den Dump, den ich schon habe?
Öffne ihn in einem Texteditor und suche nach auth. Was zurückkommt, ordnet
deine Datei einer von drei Gruppen zu.
- Überhaupt keine Treffer. Das
auth-Schema steht in dieser Datei in keiner Form. Das schreibt ein blankessupabase db dump. - Treffer, aber nur in Zeilen, die mit
CREATE,ALTERoderGRANTbeginnen. Du hast den Entwurf des Gästebuchs und niemanden darin. - Eine Zeile
COPY "auth"."users"oderCOPY auth.users, mit Datenzeilen darunter bis zu einer Zeile mit\.Oder eine Folge von Zeilen, die mitINSERT INTO "auth"."users"beginnen. Deine Konten sind drin.
Wenn du es lieber auf der Kommandozeile machst, beantworten zwei greps dieselbe Frage:
grep -c 'auth.*users' backup.sql
grep -n 'COPY .*auth.*users\|INSERT INTO .*auth.*users' backup.sql
Der erste sagt, ob das Schema die Datei überhaupt erreicht hat. Der zweite sagt, ob die Personen es getan haben. Eine Null von beiden, bei einer Datei, auf die du gezählt hast, findest du besser heute heraus als an dem Morgen, an dem du sie brauchst.
Suche bei der Gelegenheit auch nach storage und lies genau, was du findest.
Diese Zeilen sind die Liste deiner hochgeladenen Dateien, und das ist etwas
anderes als die Dateien, denn
kein Datenbank-Backup auf irgendeinem Tarif enthält die.
Wie exportiere ich Supabase-auth-Nutzer?
Mit dem Datenbefehl, der ein anderer Befehl ist als der, der das Schema schreibt.
Supabases Anleitung zu Backup und Wiederherstellung veröffentlicht das Backup als drei Dateien, und es lohnt sich, sie zusammen zu sehen, weil die Form davon die Antwort ist:
supabase db dump --db-url "postgresql://…" -f roles.sql --role-only
supabase db dump --db-url "postgresql://…" -f schema.sql
supabase db dump --db-url "postgresql://…" -f data.sql --use-copy --data-only \
-x "storage.buckets_vectors" -x "storage.vector_indexes"
Die zweite Zeile ist die, die allein ausgeführt wird. Die dritte ist die mit deinen Nutzern darin.
Diese beiden Tatsachen sehen aus wie ein Widerspruch und sind keiner. Der Satz
auf Supabases Referenzseite über das Ausschließen von auth beschreibt den
Schema-Dump, und der Daten-Dump läuft auch durch dieses Schema.
Willst du nur die Konten, dann benenne das Schema und du bekommst allein diese Schublade:
supabase db dump --db-url "postgresql://…" -f users.sql --data-only --use-copy --schema auth
Bevor du dich auf eines davon verlässt, hänge --dry-run an und lies, was
zurückkommt. Es druckt den pg_dump-Befehl, den das Werkzeug ausführen
würde, ohne ihn auszuführen, sodass du selbst siehst, welche Schemas auf deiner
installierten Version enthalten und welche ausgeschlossen sind. Lies diese
Ausgabe einmal und du musst nie wieder diesem Artikel glauben, oder
irgendeinem anderen, was zählt, weil die Flags sich zwischen Releases bewegen
und die Datei so oder so gleich aussieht.
Es gibt auch den direkten Weg, und
dafür ist ein schlichtes pg_dump da:
benenne die Schubladen, die du willst, und es nimmt sie.
pg_dump "postgresql://…" --schema public --schema auth --schema storage \
--no-owner --file backup.sql
Eines noch zur Schema-Datei, weil es erklärt, warum das überhaupt aufgeteilt
ist. Ein neues Supabase-Projekt kommt mit einem bereits gebauten auth-Schema,
in der Version, die der Anmeldedienst heute fährt. Die Version deines alten
Projekts darüberzuspielen würde einen älteren Entwurf auf einen funktionierenden
legen. Hinüberbringen willst du den Inhalt des Gästebuchs, und den hält die
Datendatei.
Was beim Zurückspielen der Nutzer kaputtgeht
Zwei Dinge, und Supabase dokumentiert beide.
Trigger, die eine Spalte zweimal verschlüsseln können. Der Wiederherstellungsbefehl in Supabases Anleitung hat mittendrin eine Anweisung, die man leicht für Beiwerk hält:
psql \
--single-transaction \
--variable ON_ERROR_STOP=1 \
--file roles.sql \
--file schema.sql \
--command 'SET session_replication_role = replica' \
--file data.sql \
--dbname "postgresql://…"
Diese mittlere Zeile schaltet die Trigger für die Dauer ab, und die Anleitung sagt, sie ist dafür da, Spalten beim Einspielen nicht ein zweites Mal verschlüsseln zu lassen. Spiel eine Datendatei ohne sie ein, und die Passwörter kommen bereits verwürfelt an von einem Vorgang, der schon auf sie angewendet worden war, und nichts danach macht das rückgängig.
Eigentümer und Rechte, die das Einspielen anhalten. Ein Dump aus einem
Supabase-Projekt trägt Zeilen, die sich auf Rollen beziehen, an die dich das
neue Projekt nicht lässt. Supabases Hinweise zur Fehlersuche für dieselbe
Anleitung sagen, jede Zeile mit ALTER ... OWNER TO "supabase_admin" in
schema.sql auszukommentieren, und eine bestimmte Zeile
GRANT "postgres" TO "cli_login_postgres" in roles.sql. Beides ist eine
Textänderung vor dem Start, und beides hält das Einspielen an, mit der Zeile,
an der es hängen blieb, auf deinem Bildschirm.
Müssen sich meine Nutzer neu anmelden?
Ihre Passwörter kommen mit. Ihre Sitzungen nicht, außer du nimmst noch etwas mit.
Supabase sagt, du kannst jede Tabelle im auth-Schema migrieren,
Nutzer und ihre gehashten Passwörter eingeschlossen,
sodass niemand ein Passwort zurücksetzen muss, das er schon hatte. Kein
Passwort ist dabei an irgendeiner Stelle lesbar; was umzieht, ist sein Hash.
Eine Sitzung ist etwas anderes. Sie wird durch ein Token belegt, das mit dem
eigenen JWT-Secret deines Projekts signiert wurde, und jedes Projekt hat sein
eigenes. Supabase sagt, dass jedes Token, das schon im Browser von jemandem
liegt, ungültig wird und die Person sich neu anmelden muss, wenn das neue
Projekt mit einem anderen Secret signiert. Du kannst das vermeiden, indem du
das Secret des alten Projekts im neuen setzt, und auf derselben Seite steht
der Preis dafür: Ein Wechsel des JWT-Secrets erzeugt die anon- und
service_role-Schlüssel dieses Projekts neu, sodass deine App die neuen
bekommen muss, bevor sie mit irgendetwas reden kann. Welcher Schlüssel welcher
ist, und welcher davon überhaupt in deine App gehört, ist
das, worüber du sicher sein willst, bevor du einen von beiden einfügst.
Die ehrliche Fassung lautet also, dass eine Wiederherstellung meist alle einmal
zur Anmeldung bittet. Das ist eine Support-Mail. Es ist kein verlorenes Konto,
und der Unterschied zwischen beidem ist, ob das auth-Schema in deiner Datei
war.
Drei Dinge sind trotzdem nicht darin, was immer du mit den Flags machst. Deine hochgeladenen Dateien, weil Storage die Bytes außerhalb der Datenbank hält und kein Dump auf irgendeinem Tarif sie erreicht. Deine Edge Functions, die ein eigener Download sind und deren Import Maps laut Supabase nicht automatisch geholt werden. Und die Einstellungen deines Projekts, die Konfiguration und keine Daten sind und von Hand neu eingetragen werden.
Was diese Woche zu tun ist
Was zu tun ist
- Nimm die neueste Backup-Datei, die du hast, und suche darin nach
auth. Gruppe eins, zwei oder drei aus dem Abschnitt oben, und du weißt es in einer Minute. - Ist es Gruppe eins oder zwei, zieh heute einen Daten-Dump mit
--data-onlyund--use-copy, und leg ihn neben die Schema-Datei statt an ihre Stelle. Du brauchst beide. - Häng
--dry-runan den Befehl, für den du dich entscheidest, und lies die Ausgabe einmal, damit du weißt, welche Schubladen deine Version des Werkzeugs nimmt. - Schreib dir die Reihenfolge der Wiederherstellung dorthin, wo du sie wiederfindest: roles, dann schema, dann
SET session_replication_role = replica, dann data. - Spiel einmal in ein Wegwerf-Projekt ein und versuch dann, dich als echter Nutzer anzumelden. Das ist die einzige Prüfung, die das testet, worum es in diesem Artikel geht.
Das einmal von Hand zu tun lohnt sich, egal wie du am Ende sicherst, denn solange du keinen Dump geöffnet hast, hattest du immer nur das Wort Backup. Ob du es weiter von Hand machst, ist eine eigene Frage, und die drei Wege und was jeder kostet ist der Ort, an dem die beantwortet wird.
Wo Reeve Care hineinpasst
Care zieht die Kopie nach Plan, und das Gästebuch ist darin.
- Deine Konten sind in der Kopie. Das
auth-Schema reist mit deinen eigenen Tabellen, denn eine Kopie einer Supabase-App ohne ihre Nutzer ist eine Kopie der Hälfte. Diestorage-Zeilen, die deine Dateien beschreiben, kommen mit, und die Dateien selbst ebenfalls, sobald du eine Storage-Zugangsinformation hinterlegst. - Die Wiederherstellungs-Schaltfläche spielt deine Tabellen zurück und lässt die Konten in Ruhe.
auth.usersüber ein laufendes Projekt zu spielen meldet alle ab und bringt Konten zurück, die jemand absichtlich gelöscht hat, also bleibt das eine Anfrage mit einem Menschen daran. Ein Druck auf die Schaltfläche in Panik kann also nicht die Kunden abmelden, denen du helfen wolltest. - Die Kopie wird zurückgelesen, bevor sie als gezogen gilt. Das Datum in deinem Dashboard ist der letzte Zeitpunkt, an dem eine Kopie geöffnet und geprüft wurde, nie der Start eines Jobs oder die Ankunft einer Datei.
- Eine Wiederherstellung macht zuerst eine Aufnahme des jetzigen Stands, sodass sie selbst ein Rückgängig hat.
Care beginnt bei €49 im Monat für eine App. Das ist ein Listenpreis, und die Preisseite liegt manchmal unter der Zahl hier und nie darüber.
Wie eine Kopie gezogen, geprüft und zurückgespielt wird, ist Schritt für Schritt auf der Supabase-Backups-Seite gezeichnet.
Bevor du diesen Tab schließt, öffne deinen neuesten Dump und suche darin nach
auth. Das ist der schnellste Weg herauszufinden, ob dir das, was du Backup
genannt hast, deine Kunden zurückgeben würde, und wenn die Antwort nein lautet,
ist eine richtige Wiederherstellung
das Nächste zum Lesen.
FAQ
Enthält ein Supabase-Backup meine Nutzer?
Das hängt davon ab, welcher Befehl die Datei geschrieben hat. Deine Nutzer liegen in einem Schema namens auth, das dem Anmeldedienst gehört. Ein blankes supabase db dump lässt auth weg und enthält überhaupt keine Zeilen, weil der Standard-Dump nur das Schema ist. Die Datenhälfte des Dumps, ein zweiter Befehl mit dem Flag --data-only, ist die, die deine Nutzer trägt. Genau deshalb veröffentlicht Supabase das Backup als drei Befehle.
Warum fehlt auth.users in meinem Dump?
Weil du mit ziemlicher Sicherheit den Schema-Dump ausgeführt hast. Supabase dokumentiert, dass der Befehl die verwalteten Schemas ausschließt, dass zu den ignorierten auth und storage gehören, und dass der Standard-Dump gar keine Daten enthält. Das ist Absicht: Ein neues Projekt kommt mit einem eigenen, vom Anmeldedienst gebauten auth-Schema, und eine ältere Kopie darüberzuspielen würde etwas ersetzen, das funktioniert. Umziehen soll der Inhalt, und den trägt der Daten-Dump.
Wie exportiere ich Supabase-auth-Nutzer?
Mit dem Datenbefehl, der vom Schemabefehl getrennt ist. Führe supabase db dump mit --data-only und --use-copy aus, um eine Datendatei zu schreiben, und die auth-Tabellen kommen mit. Willst du nur die Konten, dann füge --schema auth hinzu und bekommst eine Datei mit ausschließlich diesem Schema. Bevor du dich auf eines von beiden verlässt, hänge --dry-run an: Es druckt den pg_dump-Befehl, den die CLI ausführen würde, ohne ihn auszuführen, sodass du auf deiner Version nachlesen kannst, welche Schemas enthalten sind.
Überstehen Passwörter eine Supabase-Wiederherstellung?
Ja, wenn das auth-Schema in der Datei war. Supabase sagt, du kannst jede Tabelle im auth-Schema migrieren, gehashte Passwörter eingeschlossen, sodass niemand sie zurücksetzen oder neu anlegen muss. Ruinieren kann sie nur eines: die Daten einzuspielen, ohne vorher die Trigger abzuschalten. Deshalb setzt Supabase SET session_replication_role = replica mitten in seinen eigenen Wiederherstellungsbefehl. Lässt du die Zeile weg, wird eine bereits verschlüsselte Spalte beim Einspielen ein zweites Mal verschlüsselt.
Bleiben meine Nutzer nach einer Wiederherstellung angemeldet?
Nicht, wenn das neue Projekt mit einem anderen Secret signiert. Eine Sitzung wird durch ein Token belegt, das mit dem JWT-Secret des Projekts signiert wurde, und Supabase sagt, dass ein neues Secret vorhandene Tokens ungültig macht, sodass sich alle neu anmelden. Du kannst das alte Secret mitnehmen und alle angemeldet lassen, aber Supabase sagt auch, dass ein Wechsel des JWT-Secrets die anon- und service_role-Schlüssel in diesem Projekt neu erzeugt, sodass deine App die neuen braucht.
Was lässt ein Supabase-Dump sonst noch weg?
Deine hochgeladenen Dateien, vor allem. Storage hält für jede Datei eine Zeile in deiner Datenbank und die Datei selbst woanders, also enthält kein Datenbank-Dump auf keinem Tarif die Bytes. Edge Functions sind ein eigener Download, und Supabase merkt an, dass Import Maps und deno.json-Dateien nicht automatisch geholt werden. Projekteinstellungen, Auth-Provider und Secrets sind Konfiguration und keine Daten und liegen im Dashboard, also werden sie in einem neuen Projekt von Hand neu eingetragen.