Auflisten und Wechseln von Datenbanken in PostgreSQL: Der vollständige technische Leitfaden
PostgreSQL verwaltet mehrere isolierte Datenbanken innerhalb einer einzigen Serverinstanz, jede mit eigenem Schema, Rollen und Berechtigungen. Um alle Datenbanken aufzulisten, führen Sie l innerhalb von psql aus oder fragen Sie SELECT datname FROM pg_catalog.pg_database; aus einer beliebigen Sitzung ab. Um die Datenbank zu wechseln, müssen Sie eine neue Verbindung öffnen — PostgreSQL erzwingt eine strikte Sitzungs-zu-Datenbank-Bindung ohne ein sitzungsinternes USE-Befehlsäquivalent.
Dieser Leitfaden behandelt alle verfügbaren Methoden zur Auflistung und Verbindung mit PostgreSQL-Datenbanken, von rohen psql-Befehlen und Systemkatalogabfragen bis hin zu Verbindungsstrings, pg_hba.conf-Überlegungen und Multi-Datenbank-Workflow-Mustern, die in Produktionsumgebungen verwendet werden.
Warum der PostgreSQL-Datenbankwechsel anders funktioniert
Die meisten Entwickler, die von MySQL kommen, erwarten einen USE database_name;-Befehl. PostgreSQL lässt diesen bewusst weg. Jede PostgreSQL-Sitzung ist zum Verbindungszeitpunkt an genau eine Datenbank gebunden, und diese Bindung ist für die gesamte Lebensdauer der Sitzung unveränderlich. Dies ist eine architektonische Entscheidung, die im Prozessmodell von PostgreSQL verwurzelt ist: Der Backend-Prozess (postgres) lädt den Systemkatalog der Datenbank beim Start in den gemeinsamen Speicher, und ein Wechsel der Kataloge mitten in einer Sitzung würde ohnehin einen vollständigen Prozessneustart erfordern.
Das frühzeitige Verstehen dieser Einschränkung verhindert stundenlange Fehlersuche und beeinflusst, wie Sie Multi-Datenbank-Tooling, Verbindungspools und Anwendungskonfigurationen entwerfen.
Alle Datenbanken in PostgreSQL auflisten
Methode 1: Der l-Meta-Befehl in psql
Der schnellste Weg zur Auflistung von Datenbanken ist der l-Meta-Befehl (Alias: list) innerhalb einer interaktiven psql-Sitzung.
psql -U postgresNach der Verbindung:
lDies erzeugt eine formatierte Tabelle ähnlich wie:
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
myapp_db | appuser | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
analytics | analyst | UTF8 | en_US.UTF-8 | en_US.UTF-8 | analyst=CTc/analyst
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |Die Spalten zeigen mehr als nur Namen: Encoding ist wichtig bei der Migration von Daten zwischen Servern, Collate beeinflusst die Sortierreihenfolge und das Indexverhalten, und Access privileges verwenden die ACL-Notation von PostgreSQL (C = CONNECT, T = TEMPORARY, c = CREATE).
Für erweiterte Details einschließlich Tablespace und Verbindungslimits verwenden Sie:
l+Methode 2: Abfrage des pg_database-Systemkatalogs
Für Skripting, Monitoring oder Introspektion auf Anwendungsebene fragen Sie die pg_catalog.pg_database-Ansicht direkt ab. Dies funktioniert von jeder Datenbank im Cluster, da Systemkataloge global sichtbar sind.
SELECT
datname AS database_name,
pg_catalog.pg_get_userbyid(datdba) AS owner,
pg_encoding_to_char(encoding) AS encoding,
datcollate AS collation,
datctype AS ctype,
datconnlimit AS connection_limit,
pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(datname)) AS size
FROM pg_catalog.pg_database
WHERE datistemplate = false
ORDER BY datname;Das Filtern von datistemplate = false schließt template0 und template1 aus den Ergebnissen aus — das sind Systemvorlagen, keine operativen Datenbanken. Die Spalte datconnlimit ist in gemeinsam genutzten Umgebungen entscheidend: Ein Wert von -1 bedeutet unbegrenzt, während jede positive ganze Zahl gleichzeitige Verbindungen zu dieser Datenbank begrenzt.
Produktionstipp: Fügen Sie pg_database_size() zu Ihren Monitoring-Abfragen hinzu. Eine Datenbank, die still und leise über die Tablespace-Kapazität hinauswächst, ist eine häufige Ursache für Schreibfehler, die im Nachhinein schwer zu diagnostizieren sind.
Methode 3: Datenbanken ohne Eingabe von psql auflisten
Für Shell-Skripte und Automatisierungspipelines können Sie die Datenbankliste abrufen, ohne eine interaktive Sitzung zu starten:
psql -U postgres -c "l"Oder für eine saubere, skript-parsierbare Ausgabe:
psql -U postgres -t -c "SELECT datname FROM pg_database WHERE datistemplate = false;"Das Flag -t unterdrückt Spaltenüberschriften und Zeilenanzahlen und gibt nur Rohwerte zurück — ideal für die Weiterleitung an grep, awk oder Bash-Arrays.
Um die Liste in eine Datei zu exportieren:
psql -U postgres -t -A -c "SELECT datname FROM pg_database WHERE datistemplate = false;" > db_list.txt-A deaktiviert die Spaltenausrichtung und erzeugt einen Datenbanknamen pro Zeile.
Zwischen Datenbanken in PostgreSQL wechseln
Da Sie innerhalb einer aktiven Sitzung nicht die Datenbank wechseln können, besteht der richtige Ansatz darin, die aktuelle Verbindung zu beenden und eine neue herzustellen, die auf die gewünschte Datenbank abzielt. Es gibt mehrere Möglichkeiten, dies effizient zu tun.
Methode 1: Beenden und von der Shell aus neu verbinden
Innerhalb von psql die aktuelle Sitzung beenden:
q
Dann mit der Zieldatenbank verbinden:
psql -U postgres -d target_database
Methode 2: c (Connect) innerhalb von psql verwenden
Dies ist die praktischste Methode für interaktive Arbeit. Der c-Meta-Befehl schließt die aktuelle Verbindung und öffnet eine neue zur angegebenen Datenbank — alles innerhalb derselben Terminalsitzung.
c target_database
Sie können auch gleichzeitig Benutzer und Host wechseln:
c target_database admin_user localhost 5432
Syntax: c [database [username [host [port]]]]Wenn Sie c ausführen, zeigt psql eine Bestätigung an:
You are now connected to database "target_database" as user "postgres".Wichtiger Sonderfall: Wenn die Zieldatenbank nicht existiert oder dem aktuellen Benutzer das CONNECT-Privileg fehlt, schlägt c fehl und Sie kehren zur vorherigen Verbindung zurück. Das ist sicherer als es klingt — Sie werden nicht ohne Verbindung zurückgelassen, aber Sie müssen dies in Skripten durch Überprüfung des Exit-Status behandeln.
Methode 3: Als anderer Benutzer verbinden
Um sich mit einer Datenbank unter einer bestimmten Rolle zu verbinden:
psql -d myapp_db -U appuser -h localhost -p 5432Oder mit der c-Kurzform innerhalb einer bestehenden Sitzung:
c myapp_db appuserDies ist besonders nützlich beim Testen von Row-Level-Security (RLS)-Richtlinien oder beim Überprüfen, dass Anwendungsbenutzer nicht auf Tabellen außerhalb ihres Schemas zugreifen können.
Methode 4: Verbindungsstrings verwenden (URI-Format)
PostgreSQL unterstützt das libpq-Verbindungs-URI-Format, das alle Verbindungsparameter in einem einzigen String zusammenfasst. Dies ist die bevorzugte Methode für die Anwendungskonfiguration, CI/CD-Pipelines und Infrastructure-as-Code-Tools.
psql "postgresql://appuser:password@localhost:5432/myapp_db"Oder mit dem postgres://-Schema (beide sind gültig):
psql "postgres://appuser:password@db.example.com:5432/analytics?sslmode=require"Der Parameter ?sslmode=require erzwingt TLS-Verschlüsselung für die Verbindung — eine nicht verhandelbare Anforderung für jede Datenbank, die über localhost hinaus zugänglich ist. Wenn Sie PostgreSQL auf einem VPS oder dedizierten Server hosten, kombinieren Sie Verbindungsstrings immer mit sslmode=require oder sslmode=verify-full und einem gültigen SSL-Zertifikat.
Bemerkenswerte Verbindungs-URI-Parameter:
| Parameter | Zweck | Beispielwert |
|---|---|---|
sslmode | TLS-Durchsetzungsstufe | require, verify-full |
connect_timeout | Sekunden bis zum Verbindungsfehler | 10 |
application_name | Identifiziert den Client in pg_stat_activity | myapp_worker |
options | Serverseitige GUC-Parameter übergeben | -c search_path=myschema |
Methode 5: psql mit Umgebungsvariablen verwenden
Für wiederholte Verbindungen zum selben Cluster setzen Sie Umgebungsvariablen, um die wiederholte Eingabe von Anmeldedaten zu vermeiden:
export PGHOST=localhost
export PGPORT=5432
export PGUSER=postgres
export PGPASSWORD=secret # Use .pgpass file in production instead
export PGDATABASE=myapp_db
psqlVerwenden Sie in der Produktion eine .pgpass-Datei anstelle von PGPASSWORD, um zu vermeiden, dass Anmeldedaten im Shell-Verlauf oder in Prozesslisten offengelegt werden:
# ~/.pgpass format: hostname:port:database:username:password
localhost:5432:myapp_db:appuser:strongpasswordBerechtigungen korrekt setzen, sonst ignoriert PostgreSQL die Datei:
chmod 600 ~/.pgpassVergleich: Methoden zum Datenbankwechsel
| Methode | Kontext | Neuer Prozess erforderlich | Unterstützt Benutzerwechsel | Skriptfähig |
|---|---|---|---|---|
q + psql -d | Shell | Ja | Ja | Ja |
c dbname | psql interaktiv | Nein (psql übernimmt es) | Ja | Eingeschränkt |
| Verbindungs-URI | Shell / App | Ja | Ja | Ja |
| Umgebungsvariablen | Shell | Ja | Ja | Ja |
| pgAdmin GUI | GUI-Client | Nein | Ja | Nein |
| Verbindungspooler (PgBouncer) | Anwendung | Nein | Abhängig vom Modus | Ja |
Mehrere Datenbankverbindungen effizient verwalten
pgAdmin für GUI-basierte Navigation verwenden
pgAdmin listet alle Datenbanken unter jedem registrierten Server im linken Objektbaum auf. Ein Klick auf eine Datenbank und das Öffnen des Query Tools begrenzt automatisch alle Abfragen auf diese Datenbank. Dies ist für explorative Arbeit nützlich, aber nicht für die Automatisierung geeignet.
Fallstrick: pgAdmin verwaltet separate Verbindungsslots pro Datenbank. Wenn Ihr PostgreSQL-Server eine niedrige max_connections-Einstellung hat (Standard ist 100), kann das Öffnen vieler Datenbanken in pgAdmin den Verbindungspool erschöpfen, bevor Ihre Anwendung überhaupt startet.
PgBouncer für Verbindungspooling verwenden
In Produktionsumgebungen mit häufigem Datenbankwechsel reduziert ein Verbindungspooler wie PgBouncer den Overhead erheblich. PgBouncer arbeitet in drei Modi:
- Session-Modus: Eine Serververbindung pro Client-Sitzung. Funktional äquivalent zu direkten Verbindungen.
- Transaktionsmodus: Serververbindung wird nur während einer Transaktion gehalten. Am effizientesten für OLTP-Workloads.
- Statement-Modus: Verbindung wird nach jeder Anweisung zurückgegeben. Nicht kompatibel mit mehrzeiligen Transaktionen.
Beim Betrieb mehrerer Anwendungsdatenbanken auf einer einzigen PostgreSQL-Instanz — ein gängiges Muster beim VPS-Hosting oder VPS mit cPanel — kann PgBouncer im Transaktionsmodus die aktiven Backend-Prozesse um eine Größenordnung reduzieren.
Datenbankübergreifende Abfragen mit dblink und postgres_fdw
Da Sitzungen datenbankbezogen sind, erfordert das Abfragen von Daten über Datenbanken hinweg eine Erweiterung. PostgreSQL bietet zwei Optionen:
dblink — älterer, prozeduraler Ansatz:
SELECT * FROM dblink(
'dbname=analytics user=analyst host=localhost',
'SELECT user_id, event_count FROM events WHERE date = current_date'
) AS remote(user_id INT, event_count BIGINT);postgres_fdw — moderner, standardkonformer Foreign Data Wrapper:
CREATE EXTENSION postgres_fdw;
CREATE SERVER analytics_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'localhost', dbname 'analytics', port '5432');
CREATE USER MAPPING FOR appuser
SERVER analytics_server
OPTIONS (user 'analyst', password 'secret');
CREATE FOREIGN TABLE remote_events (
user_id INT,
event_count BIGINT
)
SERVER analytics_server
OPTIONS (schema_name 'public', table_name 'events');Nach der Einrichtung verhält sich remote_events wie eine lokale Tabelle. postgres_fdw unterstützt Predicate Pushdown, was bedeutet, dass WHERE-Klauseln auf dem Remote-Server ausgeführt werden, nicht lokal — ein entscheidender Leistungsunterschied bei großen Datensätzen.
Systemdatenbanken: Was Sie nicht anfassen dürfen
PostgreSQL wird mit vier Datenbanken in jedem neuen Cluster ausgeliefert:
| Datenbank | Zweck | Sicher zum Verbinden? | Sicher zum Ändern? |
|---|---|---|---|
postgres | Standard-Admin-Datenbank | Ja | Mit Vorsicht |
template1 | Vorlage für CREATE DATABASE | Ja | Ja, Änderungen werden übernommen |
template0 | Saubere Basis-Vorlage | Selten | Nein |
pg_catalog | Kein Datenbank, ein Schema | N/A | Niemals |
template1 wird geklont, wenn Sie CREATE DATABASE ohne Angabe einer Vorlage ausführen. Wenn Sie Erweiterungen installieren oder Schemas in template1 erstellen, erben alle neuen Datenbanken diese. Dies ist nützlich zur Standardisierung von Umgebungen, aber gefährlich, wenn es versehentlich geschieht.
template0 existiert als unberührter Fallback. Es ist die einzige Vorlage, die beim Wiederherstellen eines pg_dump-Archivs mit einer anderen Kodierung oder Locale verwendet werden kann, da es keine benutzerdefinierten Objekte hat, die in Konflikt geraten könnten.
Berechtigungen, pg_hba.conf und Verbindungsfehler
Eine häufige Verwirrungsquelle beim Wechseln von Datenbanken ist der Unterschied zwischen PostgreSQL-Rollenberechtigungen und pg_hba.conf-Authentifizierungsregeln. Beide müssen die Verbindung unabhängig voneinander erlauben.
Rollenebenen-Prüfung: Die Rolle muss das CONNECT-Privileg für die Zieldatenbank haben:
GRANT CONNECT ON DATABASE target_database TO appuser;pg_hba.conf-Prüfung: Die hostbasierte Authentifizierungsdatei (/etc/postgresql/15/main/pg_hba.conf unter Debian/Ubuntu) muss eine passende Regel für den Benutzer, die Datenbank und die Quelladresse haben. Ein typischer Eintrag:
# TYPE DATABASE USER ADDRESS METHOD
host myapp_db appuser 10.0.0.0/8 scram-sha-256Nach dem Bearbeiten von pg_hba.conf die Konfiguration neu laden, ohne den Server neu zu starten:
sudo systemctl reload postgresqlOder innerhalb von psql:
SELECT pg_reload_conf();Häufiges Fehlermuster: Ein Benutzer hat das CONNECT-Privileg auf SQL-Ebene, aber pg_hba.conf hat keine passende Regel. Die Fehlermeldung (FATAL: no pg_hba.conf entry for host) ist eindeutig, aber Entwickler übersehen die Datei oft, weil sie erwarten, dass Datenbankberechtigungen ausschließlich über SQL verwaltet werden.
Praktische Entscheidungsmatrix
Verwenden Sie diese Checkliste, um den richtigen Verbindungsansatz für Ihr Szenario auszuwählen:
- Interaktive Erkundung auf einem lokalen Entwicklungsrechner: Verwenden Sie
c dbnameinnerhalb vonpsql. Schnell, kein neuer Prozess. - Shell-Skript, das über mehrere Datenbanken iteriert: Verwenden Sie
psql -U postgres -d $dbname -c "..."in einer Schleife mit-t -Afür eine saubere Ausgabe. - Anwendung, die sich mit einer Datenbank verbindet: Verwenden Sie einen Verbindungs-URI mit
sslmode=requireund einem Verbindungspool (PgBouncer oder integriertes Treiber-Pooling). - Anwendung, die Daten aus zwei Datenbanken benötigt: Implementieren Sie
postgres_fdwauf der primären Datenbank, anstatt zwei separate Verbindungspools im Anwendungscode zu verwalten. - Überprüfung von RLS oder Berechtigungsisolierung: Verwenden Sie
c dbname role_name, um die Zielrolle zu imitieren, ohnepsqlzu verlassen. - Automatisierte Bereitstellung / Infrastructure-as-Code: Verwenden Sie Umgebungsvariablen oder
.pgpassmit einem Dienstkonto; kodieren Sie niemals Anmeldedaten fest in Skripten. - Hochnebenläufige Produktionsworkload: Setzen Sie PgBouncer im Transaktionsmodus zwischen der Anwendung und PostgreSQL ein. Auf einem dedizierten Server passen Sie
max_connectionsinpostgresql.confan die Speicherkapazität Ihrer Hardware an (jeder Backend-Prozess verwendet ungefähr 5–10 MB RAM). - Multi-Tenant-SaaS mit mandantenspezifischen Datenbanken: Erwägen Sie schema-basierte Multi-Tenancy innerhalb einer einzigen Datenbank anstelle von mandantenspezifischen Datenbanken, um Verbindungspool-Fragmentierung zu vermeiden und Backup-Strategien zu vereinfachen.
Für Teams, die PostgreSQL zusammen mit Webanwendungen betreiben, vervollständigt die Kombination des Datenbankservers mit einer ordnungsgemäß konfigurierten Shared-Hosting– oder VPS-Umgebung und einer registrierten Domain für die Anwendungsschicht den Standard-Produktions-Stack.
FAQ
Kann ich die Datenbank wechseln, ohne meine psql-Sitzung zu schließen?
Ja. Verwenden Sie den c target_database-Meta-Befehl innerhalb von psql. Er schließt die aktuelle Backend-Verbindung und öffnet eine neue zur angegebenen Datenbank, alles innerhalb derselben Terminalsitzung. Sie können optional einen anderen Benutzer, Host und Port im selben Befehl angeben.
Warum hat PostgreSQL keinen USE-Befehl wie MySQL?
Die Architektur von PostgreSQL bindet einen Backend-Prozess beim Start an eine einzige Datenbank. Der Systemkatalog der Datenbank wird für diesen Prozess in den gemeinsamen Speicher geladen, und ein Wechsel der Kataloge mitten in einer Sitzung ist architektonisch äquivalent zum Starten eines neuen Prozesses. Der c-Befehl in psql ist das praktische Äquivalent — er macht den Prozessneustart für den Benutzer nur transparent.
Wie frage ich Daten aus zwei verschiedenen PostgreSQL-Datenbanken gleichzeitig ab?
Verwenden Sie die postgres_fdw-Erweiterung, um einen Foreign Server und Foreign Tables zu erstellen, die auf die Remote-Datenbank verweisen. Nach der Einrichtung können Sie lokale und Remote-Tabellen in einer einzigen Abfrage mit JOIN verknüpfen. Für einmalige Abfragen ist dblink einfacher, aber weniger performant und schwerer zu warten.
Was passiert, wenn ich mich mit template1 verbinde und sie ändere?
Alle Objekte, die Sie in template1 erstellen — Tabellen, Erweiterungen, Schemas — werden in jede neue Datenbank geklont, die mit CREATE DATABASE erstellt wird (es sei denn, TEMPLATE template0 wird explizit angegeben). Dies ist manchmal beabsichtigt (z.B. Vorinstallation von uuid-ossp oder pgcrypto), aber versehentliche Änderungen können alle anschließend erstellten Datenbanken beschädigen.
Wie finde ich heraus, mit welcher Datenbank eine aktuelle psql-Sitzung verbunden ist?
Führen Sie folgendes innerhalb von psql aus:
SELECT current_database();Oder überprüfen Sie die psql-Eingabeaufforderung selbst — standardmäßig zeigt sie dbname=# (Superuser) oder dbname=> (regulärer Benutzer) an, wobei dbname die aktive Datenbank ist.
