Zum Inhalt springen
sw
en

Tippe um zu suchen

Datenbanken & Data

PostgreSQL Grundlagen fuer IT-Admins

Cluster-Konzept, initdb, psql, Rollen, pg_hba.conf und pgAdmin: PostgreSQL sauber administrieren im KMU-Alltag.

13 Min Lesezeit Anfänger Zuletzt aktualisiert:

Warum PostgreSQL im KMU-Umfeld immer haeufiger auftaucht

Wer in einem Schweizer KMU IT macht, kommt frueher oder spaeter an PostgreSQL vorbei - auch wenn der Betrieb primaer auf Microsoft-Produkte setzt. Viele Fachapplikationen (ERP-Zusatzmodule, Ticketsysteme, Monitoring-Tools wie Zabbix oder Grafana, Web-Apps auf Basis von Django oder Node) bringen PostgreSQL als Backend mit, oft “versteckt” in einem Docker-Container oder als Managed-Service in Azure respektive AWS. Im Gegensatz zu SQL Server ist PostgreSQL komplett quelloffen, lizenzkostenfrei und laeuft nativ auf Linux, Windows und in praktisch jeder Cloud. Das macht es zur logischen Wahl fuer Softwarehersteller, die ihre Kunden nicht an eine Lizenzpflicht binden wollen.

Fuer dich als Admin heisst das: Du musst PostgreSQL nicht lieben, aber du solltest die Grundbegriffe sauber im Griff haben, sobald eine Applikation “die Datenbank ist down” meldet. Dieser Artikel deckt das Fundament ab, das du fuer Betrieb, Absicherung und erste Fehlersuche brauchst - ohne dich gleich zum DBA auszubilden.

Architektur: Was ist ein “Cluster” bei PostgreSQL?

Der Begriff Cluster ist bei PostgreSQL missverstaendlich, wenn man aus der Microsoft-Welt kommt. Ein PostgreSQL-Cluster hat nichts mit Hochverfuegbarkeit oder mehreren Knoten zu tun (das waere bei PostgreSQL “Replikation” oder “Failover-Cluster”). Ein Cluster ist schlicht: eine Sammlung von Datenbanken, die von genau einem laufenden postgres-Serverprozess verwaltet wird und in genau einem Datenverzeichnis (Data Directory) liegt.

Ein Server kann mehrere Cluster gleichzeitig betreiben - jedes mit eigenem Datenverzeichnis, eigenem Port und eigener postgresql.conf. Das ist zum Beispiel praktisch, wenn du auf einem Testserver PostgreSQL 15 und PostgreSQL 17 parallel laufen lassen willst, um eine Migration zu testen.

Die wichtigsten Bestandteile eines Clusters

ElementZweckTypischer Pfad (Linux)
Data DirectoryEnthaelt alle Datenbankdateien, WAL-Logs, Konfiguration/var/lib/postgresql/17/main
postgresql.confServer-weite Einstellungen (Speicher, Verbindungen, Logging)im Data Directory
pg_hba.confSteuert, wer sich wie authentifizieren darfim Data Directory
pg_ident.confMapping von Betriebssystem-Usern auf DB-Rollenim Data Directory
postgres-Prozess (Postmaster)Nimmt Verbindungen entgegen, startet Worker-Prozesse-
Datenbank postgresStandard-Wartungsdatenbank, wird von Tools genutzt-
Datenbank template1Vorlage fuer neu erstellte Datenbanken-

Cluster initialisieren mit initdb

Auf Linux erledigt das Paketinstallationsskript initdb meist automatisch (z. B. via apt install postgresql). Manuell sieht das so aus:

# Data Directory initialisieren (als postgres-User)
initdb -D /var/lib/postgresql/17/main --encoding=UTF8 --locale=de_CH.UTF-8

# Server manuell starten (fuer Tests, produktiv laeuft das ueber systemd)
pg_ctl -D /var/lib/postgresql/17/main -l logfile start

Auf Windows nutzt der Installer (siehe unten) eine grafische Oberflaeche, ruft intern aber ebenfalls initdb auf. Wichtig: Die Locale (de_CH.UTF-8 oder de_DE.UTF-8) legst du bei der Initialisierung fest und kannst sie danach fuer die Datenbank-Kollation nicht mehr aendern, ohne den Cluster neu zu erstellen und die Daten umzuladen. Plane das bewusst, bevor du produktiv gehst.

Installation unter Windows

Fuer Windows laedst du den Installer von der offiziellen EnterpriseDB-Seite (postgresql.org verweist dorthin) herunter. Der Installer richtet automatisch einen Windows-Dienst ein, legt das Data Directory an und fragt nach dem Passwort fuer den Superuser postgres.

# Nach Installation: Dienst-Status pruefen
Get-Service -Name "postgresql-x64-17"

# Dienst neu starten (z.B. nach Config-Aenderung)
Restart-Service -Name "postgresql-x64-17"

# Data Directory finden (Standard)
# C:\Program Files\PostgreSQL\17\data

Unter Linux (Debian/Ubuntu) laeuft die Installation ueber die Paketquellen des PostgreSQL Global Development Group (PGDG), damit du nicht auf die oft veraltete Distributions-Version angewiesen bist:

# PGDG-Repository einbinden (Debian/Ubuntu Beispiel)
sudo apt install -y postgresql-common
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
sudo apt install -y postgresql-17

# Dienst-Status
systemctl status postgresql

Mehr zu systemd-Diensten generell findest du in systemd unter Linux.

Die wichtigsten Einstellungen in postgresql.conf

postgresql.conf ist die zentrale Konfigurationsdatei. Sie wird bei jedem Neustart (oder bei manchen Parametern per pg_reload_conf()) neu eingelesen. Die wichtigsten Parameter fuer den Alltag:

# postgresql.conf - Auszug mit typischen Anpassungen fuer einen KMU-Server

listen_addresses = '*'          # Standard: nur localhost. '*' fuer Netzwerkzugriff
port = 5432                     # Standardport, bei Mehrfach-Cluster anpassen

max_connections = 100           # Anzahl gleichzeitiger Verbindungen
shared_buffers = 2GB            # Faustregel: ca. 25% des verfuegbaren RAM
work_mem = 32MB                 # Speicher pro Sortier-/Hash-Operation
effective_cache_size = 6GB      # Schaetzung, wie viel RAM fuer OS-Caching frei ist

log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_min_duration_statement = 500   # Statements > 500ms werden geloggt (Slow-Query-Log)

wal_level = replica             # noetig fuer Backups per pg_basebackup / Replikation

Ob eine Einstellung einen Neustart braucht, siehst du direkt in der Datenbank:

SELECT name, context, setting, unit
FROM pg_settings
WHERE name IN ('shared_buffers', 'work_mem', 'listen_addresses');
-- context = 'postmaster' -> Neustart noetig
-- context = 'sighup' -> pg_reload_conf() reicht

psql: Die CLI, die du kennen musst

psql ist das PostgreSQL-Aequivalent zu sqlcmd oder dem SQL Server Management Studio - nur eben als Terminalclient. Fast jede Administrationsaufgabe laesst sich damit erledigen, ohne dass eine GUI installiert sein muss.

# Verbindung als postgres-User zur Wartungsdatenbank
psql -U postgres -h localhost -d postgres

# Verbindung zu einer spezifischen Datenbank mit anderem User
psql -U app_user -h db01.firma.local -p 5432 -d bestellsystem

Innerhalb von psql gibt es Backslash-Befehle (Meta-Commands), die dir viel Tipparbeit ersparen:

BefehlWirkung
\lAlle Datenbanken auflisten
\c dbnameZu einer anderen Datenbank wechseln
\dtTabellen im aktuellen Schema auflisten
\dnSchemas auflisten
\duRollen (User/Gruppen) auflisten
\d tabellennameStruktur einer Tabelle anzeigen (Spalten, Indizes, FKs)
\xErweiterte Ausgabe umschalten (praktisch bei breiten Ergebnissen)
\timingAusfuehrungszeit jeder Query anzeigen
\qpsql beenden
\i pfad/datei.sqlSQL-Skript aus Datei ausfuehren
\!Kurz in die Shell wechseln
-- Typischer Health-Check per psql
SELECT datname, numbackends, xact_commit, xact_rollback
FROM pg_stat_database
WHERE datname NOT IN ('template0', 'template1');

-- Groesse aller Datenbanken anzeigen
SELECT datname, pg_size_pretty(pg_database_size(datname)) AS groesse
FROM pg_database
ORDER BY pg_database_size(datname) DESC;

-- Aktive Verbindungen und laufende Queries pruefen
SELECT pid, usename, datname, state, query, query_start
FROM pg_stat_activity
WHERE state != 'idle';

Rollen- und Rechteverwaltung

PostgreSQL kennt kein getrenntes Konzept von “Login” und “Rolle” wie SQL Server (Login vs. Datenbank-User) - hier ist alles eine Rolle. Eine Rolle kann Login-Rechte haben (dann ist sie faktisch ein “User”) oder nicht (dann funktioniert sie wie eine Gruppe).

-- Login-Rolle fuer eine Applikation anlegen
CREATE ROLE app_user WITH LOGIN PASSWORD 'ein-sehr-langes-passwort' 
  CONNECTION LIMIT 20;

-- Gruppenrolle ohne Login (fuer Rechtebuendelung)
CREATE ROLE reporting_readonly;

-- Rolle einer Gruppenrolle zuweisen (Rechte werden vererbt)
GRANT reporting_readonly TO app_user;

-- Superuser anlegen (mit Vorsicht!)
CREATE ROLE admin_seya WITH LOGIN PASSWORD 'noch-laengeres-passwort' SUPERUSER;

Rechte auf Objektebene vergibst du granular ueber GRANT/REVOKE - analog zu SQL Server, aber mit eigener Terminologie (Schema-Ebene ist zentral):

-- Leserechte auf alle Tabellen in einem Schema
GRANT USAGE ON SCHEMA berichte TO reporting_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA berichte TO reporting_readonly;

-- Wichtig: Default Privileges fuer KUENFTIGE Tabellen setzen,
-- sonst muss GRANT nach jeder neuen Tabelle wiederholt werden
ALTER DEFAULT PRIVILEGES IN SCHEMA berichte
  GRANT SELECT ON TABLES TO reporting_readonly;

-- Vollzugriff auf eine Datenbank fuer eine Applikations-Rolle
GRANT ALL PRIVILEGES ON DATABASE bestellsystem TO app_user;

Prinzip der geringsten Rechte in der Praxis

Fuer eine typische KMU-Applikation empfiehlt sich diese Rollenstruktur:

  1. app_owner - besitzt das Schema, darf DDL ausfuehren (fuer Migrationen/Deployments)
  2. app_user - darf nur DML (SELECT/INSERT/UPDATE/DELETE), keine Struktur aendern
  3. reporting_readonly - nur SELECT, fuer BI-Tools oder Power BI-Anbindung
  4. postgres (Superuser) - nur fuer Wartungsarbeiten, niemals als Applikations-Login verwenden

Diese Trennung verhindert, dass ein kompromittierter Applikations-Account gleich die ganze Datenbankstruktur zerstoeren kann - ein Kernprinzip, das auch in IT-Security-Grundlagen fuer KMU beschrieben ist.

pg_hba.conf: Das Herzstueck der Zugriffskontrolle

pg_hba.conf (Host-Based Authentication) entscheidet, WER sich von WO mit WELCHER Methode verbinden darf - bevor ueberhaupt Rollen-Rechte greifen. Man kann sich das wie eine Firewall auf Verbindungsebene vorstellen: Jede Zeile ist eine Regel, die von oben nach unten geprueft wird. Die erste passende Zeile gewinnt.

# pg_hba.conf - TYPE  DATABASE  USER      ADDRESS          METHOD

# Lokale Unix-Socket-Verbindungen (nur Linux) ueber OS-User
local   all           postgres                             peer

# Lokale TCP-Verbindungen (localhost)
host    all           all       127.0.0.1/32               scram-sha-256
host    all           all       ::1/128                    scram-sha-256

# Applikationsserver im internen Netz, nur auf eine DB beschraenkt
host    bestellsystem app_user  10.20.30.0/24              scram-sha-256

# Reporting-Tool aus dem Buero-VLAN, nur lesend moeglich (Rolle steuert das)
host    all           reporting_readonly 10.20.40.50/32    scram-sha-256

# Replikation fuer einen Standby-Server
host    replication   replicator 10.20.30.99/32            scram-sha-256

Authentifizierungsmethoden im Vergleich

MethodeWie funktioniert esWann sinnvoll
trustKeine Pruefung, jeder Client wird akzeptiertNIE ausser localhost in isolierten Testumgebungen
peerNutzt den Betriebssystem-Usernamen (nur lokale Unix-Sockets)Wartungszugriff auf Linux, z. B. postgres-Systemuser
md5Passwort-Hash, veraltetes VerfahrenNur fuer Legacy-Clients, die scram-sha-256 nicht unterstuetzen
scram-sha-256Challenge-Response-Verfahren, Passwort wird nie im Klartext uebertragenStandard-Empfehlung fuer alle Passwort-Logins seit PostgreSQL 10+
certClient-Zertifikat via TLS erforderlichHochsicherheitsumgebungen, Server-zu-Server-Verbindungen
ldapDelegiert Pruefung an einen LDAP/Active-Directory-ServerZentrale Benutzerverwaltung im Unternehmensnetz
rejectVerbindung wird explizit abgelehntUm bestimmte Netze/User gezielt auszuschliessen

Nach jeder Aenderung an pg_hba.conf reicht ein Reload (kein Neustart des Dienstes noetig):

SELECT pg_reload_conf();
# Alternativ auf Betriebssystemebene
sudo systemctl reload postgresql

Datenbanken und Schemas anlegen - die Struktur dahinter

Eine haeufige Verwechslung: In PostgreSQL ist eine Datenbank NICHT dasselbe wie ein Schema. Ein Cluster enthaelt mehrere Datenbanken, jede Datenbank enthaelt mehrere Schemas, jedes Schema enthaelt Tabellen, Views, Funktionen etc. Standardmaessig landet alles im Schema public.

-- Neue Datenbank anlegen, mit Owner und Encoding
CREATE DATABASE bestellsystem
  WITH OWNER = app_owner
  ENCODING = 'UTF8'
  LC_COLLATE = 'de_CH.UTF-8'
  LC_CTYPE = 'de_CH.UTF-8'
  TEMPLATE = template0;

-- Innerhalb der Datenbank: Schema fuer Modultrennung anlegen
\c bestellsystem
CREATE SCHEMA verkauf AUTHORIZATION app_owner;
CREATE SCHEMA archiv AUTHORIZATION app_owner;

-- Tabelle explizit im Schema anlegen
CREATE TABLE verkauf.auftraege (
    id SERIAL PRIMARY KEY,
    kunde_id INT NOT NULL,
    erstellt_am TIMESTAMPTZ DEFAULT now()
);

Schemas sind das Werkzeug, um innerhalb einer Datenbank logisch zu trennen - zum Beispiel Module einer Applikation, Mandanten (Multi-Tenant-Ansatz) oder Staging- vs. Produktivdaten. Fuer viele kleine Applikationen reicht eine Datenbank mit mehreren Schemas voellig aus; separate Cluster oder Datenbanken lohnen sich erst, wenn du unterschiedliche Backup-Zyklen, Versionen oder Zugriffsisolation auf Datenbankebene brauchst.

Entscheidungshilfe: Eine Datenbank mit Schemas oder mehrere Datenbanken?

Brauchen die Anwendungen unterschiedliche PostgreSQL-Major-Versionen?
  -> JA: separate Cluster
  -> NEIN: weiter

Muessen Backup-/Restore-Zyklen komplett unabhaengig sein?
  -> JA: separate Datenbanken (pg_dump pro DB)
  -> NEIN: weiter

Reicht rollenbasierte Trennung (GRANT/REVOKE) fuer die Isolation aus?
  -> JA: ein Schema pro Modul/Mandant in EINER Datenbank
  -> NEIN (z.B. regulatorische Trennung gefordert): separate Datenbanken

pgAdmin: Die grafische Oberflaeche

Fuer alle, die nicht jeden Tag in psql leben wollen, gibt es pgAdmin - das inoffizielle Standard-GUI-Tool fuer PostgreSQL, vergleichbar mit dem SQL Server Management Studio. pgAdmin laeuft entweder als Desktop-Anwendung (Windows/Linux/macOS) oder als Web-App im Server-Modus, die du zentral fuer ein Team bereitstellen kannst.

Wichtige Funktionen im Alltag:

  • Query Tool: SQL-Editor mit Syntax-Highlighting und Ausfuehrungsplan-Visualisierung (EXPLAIN ANALYZE grafisch)
  • Server-Baum: Navigiert durch Cluster, Datenbanken, Schemas, Tabellen ohne SQL schreiben zu muessen
  • Backup/Restore-Dialog: GUI-Wrapper um pg_dump/pg_restore
  • Dashboard: Live-Ansicht von aktiven Sessions, Locks und Transaktionsraten
  • Grant Wizard: Rechtevergabe per Klick statt GRANT-Statements

Alternativen zu pgAdmin, die in der Praxis ebenfalls verbreitet sind: DBeaver (universeller DB-Client fuer viele Datenbanktypen, gut wenn du auch SQL Server oder MySQL betreust) und DataGrip von JetBrains (kostenpflichtig, aber sehr komfortabel fuer Entwickler).

Backup-Grundlagen kurz angerissen

Auch wenn ein eigener Artikel zu Backup-Strategien sinnvoll waere, gehoeren die zwei Standard-Tools hierher, weil du sie im Tagesgeschaeft brauchst:

# Logisches Backup einer einzelnen Datenbank (portabel, gut fuer Migrationen)
pg_dump -U postgres -Fc bestellsystem -f bestellsystem_2026-07-07.dump

# Restore aus einem Custom-Format-Dump
pg_restore -U postgres -d bestellsystem_neu bestellsystem_2026-07-07.dump

# Physisches Backup des kompletten Clusters (fuer Point-in-Time-Recovery)
pg_basebackup -U replicator -D /backup/base -Fp -Xs -P

Fuer produktive Systeme gilt auch hier die 3-2-1-Regel fuer Backups: mindestens drei Kopien, zwei verschiedene Medien, eine davon extern/offsite. pg_dump allein reicht fuer echte Disaster-Recovery-Faelle in der Regel nicht aus, weil es nur den Stand zum Ausfuehrungszeitpunkt sichert - fuer Point-in-Time-Recovery brauchst du WAL-Archivierung zusaetzlich zum physischen Basisbackup.

Haeufige Stolpersteine im KMU-Alltag

  • “Password authentication failed” trotz korrektem Passwort: Meist liegt es an der falschen pg_hba.conf-Zeile, die vorher zieht (z. B. peer statt scram-sha-256 fuer die gewaehlte Verbindungsart) - nicht am Passwort selbst.
  • Verbindung von aussen funktioniert nicht: listen_addresses steht noch auf localhost statt *, ODER die Windows-/Linux-Firewall blockiert Port 5432. Beide Stellen pruefen, siehe auch TCP/IP-Grundlagen.
  • Datenbank waechst ungebremst trotz geloeschter Daten: PostgreSQL nutzt MVCC (Multi-Version Concurrency Control) - geloeschte/geaenderte Zeilen werden nicht sofort physisch entfernt. Regelmaessiges VACUUM (idealerweise Autovacuum aktiv lassen) ist Pflicht, sonst blaeht sich die Datenbank auf (“Bloat”).
  • Zu viele offene Verbindungen (“too many clients”): Jede Verbindung kostet RAM. Ab einigen Dutzend gleichzeitigen App-Verbindungen lohnt sich ein Connection Pooler wie PgBouncer davor.

Weiterlernen

Videos

YouTube
PostgreSQL #1 - Wie installiere ich PostgreSQL? Die ersten Schritte!

Kommentare

Frage, Verbesserungsvorschlag oder eigene Erfahrung zu diesem Artikel? Schreib einen Kommentar. Neue Beiträge erscheinen nach kurzer Moderation.

  • Lade Kommentare …
Kommentar schreiben