15%

15% auf alle Hosting-Dienste sparen

Teste deine Fähigkeiten und erhalte Rabatt auf jeden Hosting-Plan

Benutze den Code:

Skills
Anfangen
24.10.2024

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 postgres

Nach der Verbindung:

l

Dies 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 5432

Oder mit der c-Kurzform innerhalb einer bestehenden Sitzung:

c myapp_db appuser

Dies 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:

ParameterZweckBeispielwert
sslmodeTLS-Durchsetzungsstuferequire, verify-full
connect_timeoutSekunden bis zum Verbindungsfehler10
application_nameIdentifiziert den Client in pg_stat_activitymyapp_worker
optionsServerseitige 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

psql

Verwenden 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:strongpassword

Berechtigungen korrekt setzen, sonst ignoriert PostgreSQL die Datei:

chmod 600 ~/.pgpass

Vergleich: Methoden zum Datenbankwechsel

MethodeKontextNeuer Prozess erforderlichUnterstützt BenutzerwechselSkriptfähig
q + psql -dShellJaJaJa
c dbnamepsql interaktivNein (psql übernimmt es)JaEingeschränkt
Verbindungs-URIShell / AppJaJaJa
UmgebungsvariablenShellJaJaJa
pgAdmin GUIGUI-ClientNeinJaNein
Verbindungspooler (PgBouncer)AnwendungNeinAbhängig vom ModusJa

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.

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:

DatenbankZweckSicher zum Verbinden?Sicher zum Ändern?
postgresStandard-Admin-DatenbankJaMit Vorsicht
template1Vorlage für CREATE DATABASEJaJa, Änderungen werden übernommen
template0Saubere Basis-VorlageSeltenNein
pg_catalogKein Datenbank, ein SchemaN/ANiemals

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-256

Nach dem Bearbeiten von pg_hba.conf die Konfiguration neu laden, ohne den Server neu zu starten:

sudo systemctl reload postgresql

Oder 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 dbname innerhalb von psql. Schnell, kein neuer Prozess.
  • Shell-Skript, das über mehrere Datenbanken iteriert: Verwenden Sie psql -U postgres -d $dbname -c "..." in einer Schleife mit -t -A für eine saubere Ausgabe.
  • Anwendung, die sich mit einer Datenbank verbindet: Verwenden Sie einen Verbindungs-URI mit sslmode=require und einem Verbindungspool (PgBouncer oder integriertes Treiber-Pooling).
  • Anwendung, die Daten aus zwei Datenbanken benötigt: Implementieren Sie postgres_fdw auf 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, ohne psql zu verlassen.
  • Automatisierte Bereitstellung / Infrastructure-as-Code: Verwenden Sie Umgebungsvariablen oder .pgpass mit 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_connections in postgresql.conf an 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.

15%

15% auf alle Hosting-Dienste sparen

Teste deine Fähigkeiten und erhalte Rabatt auf jeden Hosting-Plan

Benutze den Code:

Skills
Anfangen