Files
WikiJS/IT_Abteilung/DatenBank/PostgreSQL.md

33 KiB
Raw Blame History

title, description, published, date, tags, editor, dateCreated
title description published date tags editor dateCreated
PostgreSQL Profice Dokumentation true 2026-02-23T10:32:43.174Z markdown 2026-02-23T10:09:09.171Z

PostgreSQL & pgvector Vollständige Server-Dokumentation

Systemumgebung: Debian-basierter Server (Debian 12 / Ubuntu 22.04+) Einsatzbereiche: Datenspeicherung und -verarbeitung für n8n und Gitea Komponenten: PostgreSQL 16, pgvector-Erweiterung


Inhaltsverzeichnis

  1. Überblick und Architektur
  2. Installation von PostgreSQL
  3. Installation von pgvector
  4. Grundkonfiguration
  5. Authentifizierung und Zugriffskontrolle
  6. Datenbanken und Benutzer anlegen
  7. PostgreSQL-Grundlagen Wichtige SQL-Befehle
  8. pgvector Vektordatenbank nutzen
  9. Integration in n8n
  10. Integration in Gitea
  11. Backup und Wiederherstellung
  12. Wartung und Monitoring
  13. Performance-Tuning
  14. Fehlerbehebung
  15. Sicherheitshinweise
  16. Schnellreferenz Befehle auf einen Blick

1. Überblick und Architektur

Was ist PostgreSQL?

PostgreSQL ist ein leistungsstarkes, quelloffenes, objektrelationales Datenbanksystem. Es bietet ACID-Konformität, umfangreiche SQL-Unterstützung und Erweiterbarkeit durch Module wie pgvector.

Was ist pgvector?

pgvector ist eine PostgreSQL-Erweiterung, die Vektordatentypen und Ähnlichkeitssuche direkt in der Datenbank ermöglicht. Damit können Embeddings (z. B. aus KI-Modellen) gespeichert und effizient durchsucht werden ideal für RAG-Pipelines (Retrieval-Augmented Generation) in n8n.

Architektur auf diesem Server

@startuml

skinparam shadowing false
skinparam roundCorner 10

package "Debian Server" {

    [n8n\n(Workflows)] as n8n
    [Gitea\n(Git-Server)] as gitea

    package "PostgreSQL 16" {
        database "DB: n8n" as db1
        database "DB: n8n_vectors" as db2
        database "DB: gitea" as db3
        note "Extension: pgvector" as ext
    }
}

n8n --> db1 : Workflow-Daten
n8n --> db2 : Embeddings
gitea --> db3 : Repositories

@enduml

2. Installation von PostgreSQL

2.1 Offizielles PostgreSQL-Repository hinzufügen

Das Debian-Standard-Repository enthält oft ältere Versionen. Für die aktuelle Version wird das offizielle PostgreSQL-Repository empfohlen.

# Systemaktualisierung
sudo apt update && sudo apt upgrade -y

# Abhängigkeiten installieren
sudo apt install -y curl ca-certificates gnupg lsb-release

# PostgreSQL GPG-Schlüssel importieren
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /usr/share/keyrings/postgresql-keyring.gpg

# Repository hinzufügen
echo "deb [signed-by=/usr/share/keyrings/postgresql-keyring.gpg] http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list

# Paketlisten aktualisieren
sudo apt update

2.2 PostgreSQL installieren

# PostgreSQL 16 und Entwicklungsbibliotheken installieren
sudo apt install -y postgresql-16 postgresql-client-16 postgresql-server-dev-16

2.3 Dienststatus prüfen

# Status prüfen
sudo systemctl status postgresql

# Dienst aktivieren (Autostart)
sudo systemctl enable postgresql

# Dienst starten (falls nicht aktiv)
sudo systemctl start postgresql

2.4 Installierte Version prüfen

psql --version
# Erwartete Ausgabe: psql (PostgreSQL) 16.x

3. Installation von pgvector

3.1 Aus dem Paketmanager (empfohlen)

# pgvector für PostgreSQL 16 installieren
sudo apt install -y postgresql-16-pgvector

3.2 Alternative: Aus dem Quellcode kompilieren

Falls das Paket nicht verfügbar ist:

# Abhängigkeiten
sudo apt install -y build-essential git postgresql-server-dev-16

# Quellcode herunterladen
cd /tmp
git clone --branch v0.7.4 https://github.com/pgvector/pgvector.git
cd pgvector

# Kompilieren und installieren
make
sudo make install

3.3 Erweiterung in einer Datenbank aktivieren

Die Aktivierung erfolgt pro Datenbank (siehe Abschnitt 6 für die konkreten Datenbanken):

-- Als Superuser in der gewünschten Datenbank ausführen
CREATE EXTENSION IF NOT EXISTS vector;

-- Prüfen, ob die Erweiterung aktiv ist
SELECT * FROM pg_extension WHERE extname = 'vector';

4. Grundkonfiguration

4.1 Wichtige Konfigurationsdateien

Datei Pfad Zweck
postgresql.conf /etc/postgresql/16/main/postgresql.conf Hauptkonfiguration (Performance, Logging, Netzwerk)
pg_hba.conf /etc/postgresql/16/main/pg_hba.conf Authentifizierung und Zugriffskontrolle
pg_ident.conf /etc/postgresql/16/main/pg_ident.conf Benutzerzuordnung (OS ↔ DB)

4.2 Netzwerk-Konfiguration (postgresql.conf)

Standardmäßig lauscht PostgreSQL nur auf localhost. Für den Zugriff von anderen Diensten auf demselben Server reicht das aus.

sudo nano /etc/postgresql/16/main/postgresql.conf

Wichtige Einstellungen:

# Netzwerk  nur lokal (empfohlen für diesen Server)
listen_addresses = 'localhost'
port = 5432

# Logging
log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d.log'
log_statement = 'ddl'                # Loggt CREATE/ALTER/DROP-Befehle
log_min_duration_statement = 1000    # Loggt Queries >1 Sekunde (in ms)

# Zeichensatz
lc_messages = 'de_DE.UTF-8'

Hinweis: Falls n8n oder Gitea auf einem anderen Server laufen, muss listen_addresses auf die jeweilige IP oder '*' gesetzt und pg_hba.conf entsprechend angepasst werden.

4.3 Konfigurationsänderungen anwenden

# Für die meisten Änderungen reicht ein Reload
sudo systemctl reload postgresql

# Bei Änderungen an listen_addresses oder port: Neustart erforderlich
sudo systemctl restart postgresql

5. Authentifizierung und Zugriffskontrolle

5.1 pg_hba.conf verstehen

Die Datei pg_hba.conf steuert, wer sich wie verbinden darf. Jede Zeile hat das Format:

# TYPE   DATABASE   USER       ADDRESS        METHOD
Methode Beschreibung
peer OS-Benutzer muss mit DB-Benutzer übereinstimmen (nur lokal)
md5 Passwort-Authentifizierung (MD5-Hash)
scram-sha-256 Passwort-Authentifizierung (moderner, empfohlen)
trust Kein Passwort nötig (nur für Entwicklung!)
reject Verbindung ablehnen

5.2 Empfohlene Konfiguration

sudo nano /etc/postgresql/16/main/pg_hba.conf
# Lokale Verbindungen (Socket)
local   all             postgres                                peer
local   all             all                                     scram-sha-256

# IPv4  lokaler Zugriff
host    all             all             127.0.0.1/32            scram-sha-256

# IPv6  lokaler Zugriff
host    all             all             ::1/128                 scram-sha-256

# Optional: Zugriff aus dem internen Netzwerk (falls nötig)
# host  all             all             192.168.1.0/24          scram-sha-256

Danach neu laden:

sudo systemctl reload postgresql

5.3 Passwort-Verschlüsselungsmethode setzen

In postgresql.conf:

password_encryption = scram-sha-256

6. Datenbanken und Benutzer anlegen

6.1 Verbindung als Superuser herstellen

# Als Linux-Benutzer 'postgres' wechseln und psql starten
sudo -u postgres psql

6.2 Benutzer (Rollen) erstellen

-- Benutzer für n8n
CREATE USER n8n_user WITH PASSWORD 'SICHERES_PASSWORT_HIER';

-- Benutzer für n8n-Vektordatenbank (kann auch derselbe sein)
CREATE USER n8n_vector_user WITH PASSWORD 'SICHERES_PASSWORT_HIER';

-- Benutzer für Gitea
CREATE USER gitea_user WITH PASSWORD 'SICHERES_PASSWORT_HIER';

-- Passwort eines bestehenden Benutzers ändern
ALTER USER n8n_user WITH PASSWORD 'NEUES_PASSWORT';

Sicherheitshinweis: Verwende starke, zufällig generierte Passwörter. Beispiel mit openssl:

openssl rand -base64 32

6.3 Datenbanken erstellen

-- Datenbank für n8n (Workflow-Daten)
CREATE DATABASE n8n
    OWNER n8n_user
    ENCODING 'UTF8'
    LC_COLLATE 'de_DE.UTF-8'
    LC_CTYPE 'de_DE.UTF-8'
    TEMPLATE template0;

-- Datenbank für n8n-Vektoren (Embeddings, RAG)
CREATE DATABASE n8n_vectors
    OWNER n8n_vector_user
    ENCODING 'UTF8'
    LC_COLLATE 'de_DE.UTF-8'
    LC_CTYPE 'de_DE.UTF-8'
    TEMPLATE template0;

-- Datenbank für Gitea
CREATE DATABASE gitea
    OWNER gitea_user
    ENCODING 'UTF8'
    LC_COLLATE 'de_DE.UTF-8'
    LC_CTYPE 'de_DE.UTF-8'
    TEMPLATE template0;

Hinweis: Falls die Locale de_DE.UTF-8 nicht verfügbar ist, kann en_US.UTF-8 verwendet oder die Locale vorher generiert werden:

sudo locale-gen de_DE.UTF-8
sudo update-locale

6.4 pgvector in der Vektordatenbank aktivieren

-- Zur Vektordatenbank wechseln
\c n8n_vectors

-- pgvector aktivieren (muss als Superuser erfolgen)
CREATE EXTENSION IF NOT EXISTS vector;

-- Prüfen
\dx

6.5 Berechtigungen vergeben

-- n8n-Benutzer: Volle Rechte auf seine Datenbank
GRANT ALL PRIVILEGES ON DATABASE n8n TO n8n_user;

-- Vektor-Benutzer: Volle Rechte auf die Vektordatenbank
GRANT ALL PRIVILEGES ON DATABASE n8n_vectors TO n8n_vector_user;

-- Gitea-Benutzer: Volle Rechte auf die Gitea-Datenbank
GRANT ALL PRIVILEGES ON DATABASE gitea TO gitea_user;

-- Schema-Berechtigungen (innerhalb der jeweiligen Datenbank)
\c n8n
GRANT ALL ON SCHEMA public TO n8n_user;

\c n8n_vectors
GRANT ALL ON SCHEMA public TO n8n_vector_user;

\c gitea
GRANT ALL ON SCHEMA public TO gitea_user;

6.6 Verbindung testen

# Als n8n_user verbinden
psql -h localhost -U n8n_user -d n8n

# Als gitea_user verbinden
psql -h localhost -U gitea_user -d gitea

# Vektordatenbank testen
psql -h localhost -U n8n_vector_user -d n8n_vectors

7. PostgreSQL-Grundlagen Wichtige SQL-Befehle

7.1 psql-Meta-Befehle (im psql-Prompt)

Befehl Beschreibung
\l Alle Datenbanken auflisten
\c datenbankname Zu einer Datenbank wechseln
\dt Alle Tabellen der aktuellen Datenbank anzeigen
\dt+ Tabellen mit Größeninformationen
\du Alle Benutzer/Rollen anzeigen
\dx Installierte Erweiterungen anzeigen
\d tabellenname Tabellenstruktur anzeigen
\di Alle Indizes anzeigen
\dn Alle Schemas anzeigen
\conninfo Aktuelle Verbindungsinformationen
\timing Ausführungszeit von Queries anzeigen
\q psql beenden

7.2 Datenbank-Verwaltung

-- Datenbank erstellen
CREATE DATABASE meine_db OWNER mein_user;

-- Datenbank löschen (Vorsicht!)
DROP DATABASE meine_db;

-- Datenbankgröße anzeigen
SELECT pg_database.datname,
       pg_size_pretty(pg_database_size(pg_database.datname)) AS groesse
FROM pg_database
ORDER BY pg_database_size(pg_database.datname) DESC;

7.3 Tabellen-Verwaltung

-- Tabelle erstellen
CREATE TABLE beispiel (
    id          SERIAL PRIMARY KEY,
    name        VARCHAR(255) NOT NULL,
    beschreibung TEXT,
    erstellt_am  TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    aktiv       BOOLEAN DEFAULT true
);

-- Spalte hinzufügen
ALTER TABLE beispiel ADD COLUMN email VARCHAR(255);

-- Spalte entfernen
ALTER TABLE beispiel DROP COLUMN email;

-- Tabelle löschen
DROP TABLE beispiel;

-- Tabelle umbenennen
ALTER TABLE beispiel RENAME TO beispiel_alt;

7.4 Daten bearbeiten (CRUD)

-- Einfügen (Create)
INSERT INTO beispiel (name, beschreibung)
VALUES ('Test', 'Ein Testeintrag');

-- Lesen (Read)
SELECT * FROM beispiel;
SELECT name, erstellt_am FROM beispiel WHERE aktiv = true;

-- Aktualisieren (Update)
UPDATE beispiel SET beschreibung = 'Aktualisiert' WHERE id = 1;

-- Löschen (Delete)
DELETE FROM beispiel WHERE id = 1;

7.5 Nützliche Abfragen für die Administration

-- Aktive Verbindungen anzeigen
SELECT pid, usename, datname, client_addr, state, query_start
FROM pg_stat_activity
WHERE state = 'active';

-- Tabellen mit Größe in der aktuellen Datenbank
SELECT schemaname, tablename,
       pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename)) AS groesse
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC;

-- Langsame Queries finden
SELECT query, calls, mean_exec_time, total_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;

8. pgvector Vektordatenbank nutzen

8.1 Grundkonzepte

Vektoren sind numerische Darstellungen (Embeddings) von Texten, Bildern oder anderen Daten, die von KI-Modellen erzeugt werden. pgvector ermöglicht es, diese Vektoren direkt in PostgreSQL zu speichern und Ähnlichkeitssuchen durchzuführen.

8.2 Vektortabelle erstellen

-- Zur Vektordatenbank wechseln
\c n8n_vectors

-- Tabelle mit Vektorspalte (1536 Dimensionen = OpenAI text-embedding-ada-002)
CREATE TABLE dokumente (
    id          SERIAL PRIMARY KEY,
    inhalt      TEXT NOT NULL,
    metadaten   JSONB,
    embedding   vector(1536),
    erstellt_am TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Für andere Embedding-Modelle die Dimension anpassen:
-- OpenAI text-embedding-3-small: vector(1536)
-- OpenAI text-embedding-3-large: vector(3072)
-- Ollama/Llama-basiert:          variiert (z.B. vector(4096))

8.3 Vektordaten einfügen

-- Einzelnen Vektor einfügen
INSERT INTO dokumente (inhalt, metadaten, embedding)
VALUES (
    'PostgreSQL ist ein objektrelationales Datenbanksystem.',
    '{"quelle": "wiki", "kategorie": "datenbank"}',
    '[0.1, 0.2, 0.3, ...]'::vector  -- Hier den vollständigen Vektor einsetzen
);

8.4 Ähnlichkeitssuche

pgvector unterstützt drei Distanzmetriken:

Operator Metrik Beschreibung Verwendung
<-> L2 (Euklidisch) Geometrischer Abstand Allgemeine Ähnlichkeit
<=> Kosinus-Distanz Winkel zwischen Vektoren Empfohlen für Text-Embeddings
<#> Inneres Produkt (negiert) Skalarprodukt Normalisierte Vektoren
-- Die 5 ähnlichsten Dokumente zu einem Abfragevektor finden (Kosinus-Distanz)
SELECT id, inhalt, metadaten,
       1 - (embedding <=> '[0.1, 0.2, 0.3, ...]'::vector) AS aehnlichkeit
FROM dokumente
ORDER BY embedding <=> '[0.1, 0.2, 0.3, ...]'::vector
LIMIT 5;

-- Mit Schwellenwert: Nur Ergebnisse mit >80% Ähnlichkeit
SELECT id, inhalt,
       1 - (embedding <=> '[0.1, 0.2, 0.3, ...]'::vector) AS aehnlichkeit
FROM dokumente
WHERE 1 - (embedding <=> '[0.1, 0.2, 0.3, ...]'::vector) > 0.8
ORDER BY aehnlichkeit DESC;

8.5 Indizes für Vektoren (Performance)

Ohne Index muss PostgreSQL jeden Vektor einzeln vergleichen (Brute-Force). Bei großen Datenmengen sind Indizes entscheidend:

-- HNSW-Index (empfohlen  schneller bei Suchen, langsamer beim Aufbau)
CREATE INDEX ON dokumente
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);

-- IVFFlat-Index (Alternative  schneller beim Aufbau, etwas weniger genau)
CREATE INDEX ON dokumente
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
Index-Typ Vorteile Nachteile
HNSW Schnelle Suche, hohe Genauigkeit Langsamer Aufbau, mehr Speicher
IVFFlat Schneller Aufbau Weniger genau, erfordert Training

Empfehlung: Für die meisten Anwendungsfälle in n8n ist HNSW die beste Wahl.

8.6 Wartung der Vektortabellen

-- Statistiken aktualisieren (wichtig nach großen Datenänderungen)
ANALYZE dokumente;

-- Tabellengröße prüfen
SELECT pg_size_pretty(pg_total_relation_size('dokumente'));

-- Anzahl der gespeicherten Vektoren
SELECT COUNT(*) FROM dokumente;

9. Integration in n8n

9.1 n8n-Hauptdatenbank konfigurieren

n8n verwendet standardmäßig SQLite. Für den produktiven Einsatz wird PostgreSQL empfohlen.

Umgebungsvariablen für n8n setzen

Je nach Installationsart von n8n werden die Variablen unterschiedlich gesetzt:

Variante A: Systemd-Service (direkte Installation)

sudo nano /etc/n8n/environment
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=localhost
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n_user
DB_POSTGRESDB_PASSWORD=SICHERES_PASSWORT_HIER
DB_POSTGRESDB_SCHEMA=public

Variante B: Docker / Docker Compose

# In docker-compose.yml
services:
  n8n:
    image: n8nio/n8n
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=host.docker.internal  # oder IP des Hosts
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n_user
      - DB_POSTGRESDB_PASSWORD=SICHERES_PASSWORT_HIER
      - DB_POSTGRESDB_SCHEMA=public

Wichtig: Nach dem Ändern der Datenbankverbindung muss n8n neu gestartet werden:

sudo systemctl restart n8n

9.2 PostgreSQL-Node in n8n-Workflows

Der PostgreSQL-Node erlaubt es, direkt aus Workflows heraus SQL-Operationen auszuführen.

Credential erstellen

  1. In n8n unter Settings → Credentials eine neue Credential anlegen
  2. Typ: PostgreSQL
  3. Folgende Werte eintragen:
Feld Wert
Host localhost (oder 127.0.0.1)
Port 5432
Database n8n (oder die jeweilige Zieldatenbank)
User n8n_user
Password das vergebene Passwort
SSL disable (bei lokaler Verbindung)

Beispiel: Daten lesen

Im PostgreSQL-Node:

  • Operation: Execute Query
  • Query:
SELECT * FROM meine_tabelle WHERE erstellt_am > '2024-01-01' LIMIT 100;

Beispiel: Daten einfügen

  • Operation: Insert
  • Schema: public
  • Table: meine_tabelle
  • Columns: Über das Mapping der Eingabedaten befüllen

9.3 Vektor-Integration in n8n (pgvector)

n8n bietet native Unterstützung für Vektorspeicher über die AI-Nodes.

Credential für Vektordatenbank erstellen

Erstelle eine separate PostgreSQL-Credential für die Vektordatenbank:

Feld Wert
Host localhost
Port 5432
Database n8n_vectors
User n8n_vector_user
Password das vergebene Passwort
SSL disable

Postgres Chat Memory (Gesprächsverlauf speichern)

Für KI-Workflows mit Gedächtnis:

  1. Node: Postgres Chat Memory
  2. Credential: Die Vektordatenbank-Credential auswählen
  3. Session ID: Dynamisch aus dem Workflow (z. B. {{ $json.sessionId }})
  4. Die Tabelle wird automatisch erstellt

Vector Store Daten einbetten und speichern

  1. Node: Embeddings (z. B. OpenAI Embeddings, Ollama Embeddings)
  2. Node: Postgres Vector Store (Insert-Modus)
  3. Konfiguration:
    • Credential: Vektordatenbank-Credential
    • Table Name: dokumente (oder automatisch erstellen lassen)
    • Embedding Column: embedding
    • Content Column: inhalt

Vector Store Ähnlichkeitssuche

  1. Node: Postgres Vector Store (Retrieve-Modus)
  2. Konfiguration:
    • Query: Der Suchtext (wird automatisch eingebettet)
    • Top K: Anzahl der Ergebnisse (z. B. 5)

Beispiel-Workflow: RAG-Pipeline

┌──────────┐    ┌──────────────┐    ┌───────────────────┐    ┌────────────┐
│ Webhook  │───▶│  Embeddings  │───▶│ Postgres Vector   │───▶│ AI Agent   │
│ (Frage)  │    │  (OpenAI)    │    │ Store (Retrieve)  │    │ (Antwort)  │
└──────────┘    └──────────────┘    └───────────────────┘    └────────────┘

Ablauf:

  1. Eine Frage kommt über den Webhook herein
  2. Die Frage wird in einen Vektor umgewandelt (Embedding)
  3. Die ähnlichsten Dokumente werden aus der Vektordatenbank geholt
  4. Der AI Agent nutzt die Dokumente als Kontext für die Antwort

10. Integration in Gitea

10.1 Gitea-Datenbank konfigurieren

Die Konfiguration erfolgt in der Gitea-Konfigurationsdatei:

sudo nano /etc/gitea/app.ini
[database]
DB_TYPE  = postgres
HOST     = 127.0.0.1:5432
NAME     = gitea
USER     = gitea_user
PASSWD   = SICHERES_PASSWORT_HIER
SSL_MODE = disable
CHARSET  = utf8
LOG_SQL  = false

Danach Gitea neu starten:

sudo systemctl restart gitea

10.2 Gitea-Migration von SQLite zu PostgreSQL

Falls Gitea bisher SQLite verwendet:

# Dump der SQLite-Daten erstellen
gitea dump -c /etc/gitea/app.ini

# In der app.ini auf PostgreSQL umstellen (siehe oben)

# Gitea mit neuer DB starten  Tabellen werden automatisch erstellt
sudo systemctl restart gitea

# Daten über gitea restore-repo oder manuell migrieren

Hinweis: Eine direkte Migration ist komplex. Bei einer bestehenden Gitea-Instanz empfiehlt sich ein frischer Start mit PostgreSQL oder die Nutzung des offiziellen gitea dump/gitea restore-repo-Werkzeugs.

10.3 Gitea-Datenbankstatus prüfen

# Als gitea_user verbinden
psql -h localhost -U gitea_user -d gitea

# Tabellen anzeigen
\dt

# Tabellenzahl prüfen (Gitea erstellt ca. 50+ Tabellen)
SELECT COUNT(*) FROM information_schema.tables
WHERE table_schema = 'public';

11. Backup und Wiederherstellung

11.1 Einzelne Datenbank sichern

# n8n-Datenbank sichern
sudo -u postgres pg_dump -Fc n8n > /backup/n8n_$(date +%Y%m%d_%H%M%S).dump

# Vektordatenbank sichern
sudo -u postgres pg_dump -Fc n8n_vectors > /backup/n8n_vectors_$(date +%Y%m%d_%H%M%S).dump

# Gitea-Datenbank sichern
sudo -u postgres pg_dump -Fc gitea > /backup/gitea_$(date +%Y%m%d_%H%M%S).dump

11.2 Alle Datenbanken sichern

# Vollständiges Backup aller Datenbanken (inkl. Rollen und Konfiguration)
sudo -u postgres pg_dumpall > /backup/postgresql_all_$(date +%Y%m%d_%H%M%S).sql

11.3 Datenbank wiederherstellen

# Aus einem Custom-Format-Dump (.dump)
sudo -u postgres pg_restore -d n8n /backup/n8n_20240101_120000.dump

# Aus einer SQL-Datei
sudo -u postgres psql -d n8n < /backup/n8n_backup.sql

# Datenbank vorher löschen und neu erstellen (bei Bedarf)
sudo -u postgres dropdb n8n
sudo -u postgres createdb -O n8n_user n8n
sudo -u postgres pg_restore -d n8n /backup/n8n_20240101_120000.dump

11.4 Automatisches Backup per Cronjob

sudo nano /etc/cron.d/postgresql-backup
# Tägliches Backup um 02:00 Uhr
0 2 * * * postgres pg_dump -Fc n8n > /backup/n8n_$(date +\%Y\%m\%d).dump 2>&1
0 2 * * * postgres pg_dump -Fc n8n_vectors > /backup/n8n_vectors_$(date +\%Y\%m\%d).dump 2>&1
0 2 * * * postgres pg_dump -Fc gitea > /backup/gitea_$(date +\%Y\%m\%d).dump 2>&1

# Alte Backups nach 30 Tagen löschen
0 3 * * * root find /backup -name "*.dump" -mtime +30 -delete 2>&1
# Backup-Verzeichnis erstellen und Rechte setzen
sudo mkdir -p /backup
sudo chown postgres:postgres /backup
sudo chmod 700 /backup

12. Wartung und Monitoring

12.1 VACUUM Speicher freigeben

PostgreSQL markiert gelöschte Zeilen nur als unsichtbar. VACUUM gibt den Speicher frei.

-- Einzelne Tabelle
VACUUM ANALYZE meine_tabelle;

-- Gesamte Datenbank
VACUUM ANALYZE;

-- Aggressives Vacuum (gibt Speicher an das OS zurück)
VACUUM FULL meine_tabelle;

Hinweis: VACUUM FULL sperrt die Tabelle und sollte nur in Wartungsfenstern ausgeführt werden.

12.2 Autovacuum prüfen

Autovacuum ist standardmäßig aktiv und sollte es bleiben:

-- Autovacuum-Status prüfen
SHOW autovacuum;

-- Letzte Vacuum-Läufe anzeigen
SELECT schemaname, relname, last_vacuum, last_autovacuum, last_analyze
FROM pg_stat_user_tables
ORDER BY last_autovacuum DESC NULLS LAST;

12.3 Datenbankgrößen überwachen

-- Alle Datenbanken mit Größe
SELECT datname, pg_size_pretty(pg_database_size(datname)) AS groesse
FROM pg_database
WHERE datistemplate = false
ORDER BY pg_database_size(datname) DESC;

-- Größte Tabellen in der aktuellen Datenbank
SELECT schemaname || '.' || tablename AS tabelle,
       pg_size_pretty(pg_total_relation_size(schemaname || '.' || tablename)) AS groesse
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname || '.' || tablename) DESC
LIMIT 10;

12.4 Aktive Verbindungen überwachen

-- Alle aktiven Verbindungen
SELECT pid, usename, datname, client_addr,
       state, query_start, query
FROM pg_stat_activity
WHERE datname IS NOT NULL
ORDER BY query_start DESC;

-- Verbindungsanzahl pro Datenbank
SELECT datname, COUNT(*) AS verbindungen
FROM pg_stat_activity
GROUP BY datname;

-- Blockierte Prozesse finden
SELECT blocked_locks.pid AS blockierte_pid,
       blocking_locks.pid AS blockierende_pid,
       blocked_activity.usename AS blockierter_user,
       blocked_activity.query AS blockierte_query
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks
    ON blocking_locks.locktype = blocked_locks.locktype
    AND blocking_locks.database IS NOT DISTINCT FROM blocked_locks.database
    AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
    AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
    AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
    AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
    AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
    AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
    AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
    AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
    AND blocking_locks.pid != blocked_locks.pid
WHERE NOT blocked_locks.granted;

13. Performance-Tuning

13.1 Wichtige Parameter (postgresql.conf)

Die Standardwerte von PostgreSQL sind konservativ. Die folgenden Einstellungen sollten an den verfügbaren Arbeitsspeicher angepasst werden.

# ============================================================
# Speicher (Beispiel für Server mit 8 GB RAM)
# ============================================================

# Gemeinsamer Speicher für Caching (25% des RAM)
shared_buffers = 2GB

# Speicher pro Sortier-/Join-Operation
work_mem = 64MB

# Speicher für Wartungsoperationen (VACUUM, CREATE INDEX)
maintenance_work_mem = 512MB

# OS-Cache-Schätzung (50-75% des RAM)
effective_cache_size = 6GB

# ============================================================
# Write-Ahead-Log (WAL)
# ============================================================

# WAL-Puffergröße
wal_buffers = 64MB

# Checkpoint-Intervall (in Sekunden)
checkpoint_timeout = 15min

# Maximale WAL-Größe zwischen Checkpoints
max_wal_size = 2GB

# ============================================================
# Verbindungen
# ============================================================

# Maximale gleichzeitige Verbindungen
max_connections = 100

# ============================================================
# Planer-Einstellungen
# ============================================================

# Kosten für zufälligen Seitenzugriff (SSD: 1.1, HDD: 4.0)
random_page_cost = 1.1

# Parallele Abfragen
max_parallel_workers_per_gather = 2
max_parallel_workers = 4

13.2 Empfohlene Werte nach RAM-Größe

Parameter 4 GB RAM 8 GB RAM 16 GB RAM 32 GB RAM
shared_buffers 1 GB 2 GB 4 GB 8 GB
work_mem 32 MB 64 MB 128 MB 256 MB
maintenance_work_mem 256 MB 512 MB 1 GB 2 GB
effective_cache_size 3 GB 6 GB 12 GB 24 GB

13.3 Änderungen anwenden

# Konfiguration prüfen (ohne Neustart)
sudo -u postgres psql -c "SELECT name, setting, unit FROM pg_settings WHERE name IN ('shared_buffers', 'work_mem', 'maintenance_work_mem', 'effective_cache_size');"

# Neustart erforderlich für shared_buffers
sudo systemctl restart postgresql

# Reload reicht für work_mem, effective_cache_size etc.
sudo systemctl reload postgresql

14. Fehlerbehebung

14.1 Verbindungsfehler

Problem: connection refused

# Prüfen, ob PostgreSQL läuft
sudo systemctl status postgresql

# Port prüfen
sudo ss -tlnp | grep 5432

# Logs anzeigen
sudo tail -50 /var/log/postgresql/postgresql-16-main.log

Problem: FATAL: password authentication failed

# Passwort zurücksetzen
sudo -u postgres psql -c "ALTER USER n8n_user WITH PASSWORD 'neues_passwort';"

# pg_hba.conf prüfen
sudo cat /etc/postgresql/16/main/pg_hba.conf | grep -v "^#" | grep -v "^$"

Problem: FATAL: database "xxx" does not exist

# Datenbanken auflisten
sudo -u postgres psql -c "\l"

# Datenbank erstellen
sudo -u postgres createdb -O besitzer_user datenbankname

14.2 Performance-Probleme

-- Langsame Queries identifizieren
-- (pg_stat_statements-Erweiterung muss aktiviert sein)
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

SELECT query, calls, mean_exec_time, total_exec_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

-- Fehlende Indizes finden
SELECT schemaname, tablename, seq_scan, idx_scan,
       seq_tup_read, idx_tup_fetch
FROM pg_stat_user_tables
WHERE seq_scan > 1000
ORDER BY seq_scan DESC;

14.3 Speicherprobleme

# Festplattenplatz prüfen
df -h

# PostgreSQL-Datenverzeichnis-Größe
sudo du -sh /var/lib/postgresql/16/main/

# WAL-Dateien prüfen (können sehr groß werden)
sudo du -sh /var/lib/postgresql/16/main/pg_wal/
-- In PostgreSQL: Aufgeblähte Tabellen finden
SELECT schemaname, tablename,
       n_dead_tup,
       n_live_tup,
       round(n_dead_tup::numeric / NULLIF(n_live_tup, 0) * 100, 2) AS dead_prozent
FROM pg_stat_user_tables
WHERE n_dead_tup > 1000
ORDER BY n_dead_tup DESC;

14.4 Logdateien

# Aktuelle Logs anzeigen
sudo tail -f /var/log/postgresql/postgresql-16-main.log

# Nach Fehlern suchen
sudo grep -i "error\|fatal\|panic" /var/log/postgresql/postgresql-16-main.log | tail -20

15. Sicherheitshinweise

15.1 Checkliste

  • Starke Passwörter für alle Datenbankbenutzer verwenden
  • scram-sha-256 als Authentifizierungsmethode nutzen (nicht md5 oder trust)
  • listen_addresses auf localhost beschränken (wenn nur lokaler Zugriff nötig)
  • Minimale Berechtigungen vergeben (kein SUPERUSER für Anwendungsbenutzer)
  • Regelmäßige Backups durchführen und testen
  • PostgreSQL aktuell halten (Sicherheitsupdates zeitnah einspielen)
  • Logdateien regelmäßig prüfen
  • SSL aktivieren bei Netzwerkzugriff von außen

15.2 PostgreSQL aktualisieren

# Verfügbare Updates prüfen
sudo apt update
apt list --upgradable | grep postgresql

# Update durchführen
sudo apt upgrade -y postgresql-16

# Dienst prüfen (wird normalerweise automatisch neu gestartet)
sudo systemctl status postgresql

15.3 SSL für Netzwerkverbindungen aktivieren

Falls PostgreSQL von anderen Servern aus erreichbar sein muss:

# In postgresql.conf
ssl = on
ssl_cert_file = '/etc/postgresql/16/main/server.crt'
ssl_key_file = '/etc/postgresql/16/main/server.key'
# Selbstsigniertes Zertifikat erstellen (für interne Nutzung)
sudo -u postgres openssl req -new -x509 -days 365 -nodes \
  -out /etc/postgresql/16/main/server.crt \
  -keyout /etc/postgresql/16/main/server.key \
  -subj "/CN=postgresql-server"

sudo chmod 600 /etc/postgresql/16/main/server.key
sudo chown postgres:postgres /etc/postgresql/16/main/server.key

sudo systemctl restart postgresql

16. Schnellreferenz Befehle auf einen Blick

Systemd-Befehle

sudo systemctl start postgresql      # Starten
sudo systemctl stop postgresql       # Stoppen
sudo systemctl restart postgresql    # Neustarten
sudo systemctl reload postgresql     # Konfiguration neu laden
sudo systemctl status postgresql     # Status prüfen
sudo systemctl enable postgresql     # Autostart aktivieren

psql-Verbindung

sudo -u postgres psql                # Als Superuser verbinden
psql -h localhost -U user -d dbname  # Als bestimmter Benutzer verbinden

Schnelle Datenbank-Operationen

# Datenbank erstellen
sudo -u postgres createdb -O besitzer datenbankname

# Datenbank löschen
sudo -u postgres dropdb datenbankname

# Benutzer erstellen
sudo -u postgres createuser --pwprompt benutzername

# Backup erstellen
sudo -u postgres pg_dump -Fc dbname > backup.dump

# Backup wiederherstellen
sudo -u postgres pg_restore -d dbname backup.dump

Verbindungsstrings (Connection Strings)

# n8n Hauptdatenbank
postgresql://n8n_user:PASSWORT@localhost:5432/n8n

# n8n Vektordatenbank
postgresql://n8n_vector_user:PASSWORT@localhost:5432/n8n_vectors

# Gitea
postgresql://gitea_user:PASSWORT@localhost:5432/gitea

Letzte Aktualisierung: Datum hier eintragen Autor: Name hier eintragen Version: 1.0