Files
WikiJS/IT_Abteilung/DatenBank/PostgreSQL.md

1231 lines
34 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: PostgreSQL Profice Dokumentation
description:
published: true
date: 2026-02-23T10:09:09.171Z
tags:
editor: markdown
dateCreated: 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](#1-überblick-und-architektur)
2. [Installation von PostgreSQL](#2-installation-von-postgresql)
3. [Installation von pgvector](#3-installation-von-pgvector)
4. [Grundkonfiguration](#4-grundkonfiguration)
5. [Authentifizierung und Zugriffskontrolle](#5-authentifizierung-und-zugriffskontrolle)
6. [Datenbanken und Benutzer anlegen](#6-datenbanken-und-benutzer-anlegen)
7. [PostgreSQL-Grundlagen Wichtige SQL-Befehle](#7-postgresql-grundlagen--wichtige-sql-befehle)
8. [pgvector Vektordatenbank nutzen](#8-pgvector--vektordatenbank-nutzen)
9. [Integration in n8n](#9-integration-in-n8n)
10. [Integration in Gitea](#10-integration-in-gitea)
11. [Backup und Wiederherstellung](#11-backup-und-wiederherstellung)
12. [Wartung und Monitoring](#12-wartung-und-monitoring)
13. [Performance-Tuning](#13-performance-tuning)
14. [Fehlerbehebung](#14-fehlerbehebung)
15. [Sicherheitshinweise](#15-sicherheitshinweise)
16. [Schnellreferenz Befehle auf einen Blick](#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
```
┌─────────────────────────────────────────────────┐
│ Debian Server │
│ │
│ ┌──────────────┐ ┌────────────────────────┐ │
│ │ n8n │───▶│ PostgreSQL 16 │ │
│ │ (Workflows) │ │ ┌──────────────────┐ │ │
│ └──────────────┘ │ │ DB: n8n │ │ │
│ │ │ DB: n8n_vectors │ │ │
│ ┌──────────────┐ │ │ DB: gitea │ │ │
│ │ Gitea │───▶│ │ │ │ │
│ │ (Git-Server) │ │ │ Extension: │ │ │
│ └──────────────┘ │ │ pgvector │ │ │
│ │ └──────────────────┘ │ │
│ └────────────────────────┘ │
└─────────────────────────────────────────────────┘
```
---
## 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.
```bash
# 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
```bash
# PostgreSQL 16 und Entwicklungsbibliotheken installieren
sudo apt install -y postgresql-16 postgresql-client-16 postgresql-server-dev-16
```
### 2.3 Dienststatus prüfen
```bash
# 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
```bash
psql --version
# Erwartete Ausgabe: psql (PostgreSQL) 16.x
```
---
## 3. Installation von pgvector
### 3.1 Aus dem Paketmanager (empfohlen)
```bash
# 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:
```bash
# 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):
```sql
-- 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.
```bash
sudo nano /etc/postgresql/16/main/postgresql.conf
```
Wichtige Einstellungen:
```ini
# 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
```bash
# 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
```bash
sudo nano /etc/postgresql/16/main/pg_hba.conf
```
```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:
```bash
sudo systemctl reload postgresql
```
### 5.3 Passwort-Verschlüsselungsmethode setzen
In `postgresql.conf`:
```ini
password_encryption = scram-sha-256
```
---
## 6. Datenbanken und Benutzer anlegen
### 6.1 Verbindung als Superuser herstellen
```bash
# Als Linux-Benutzer 'postgres' wechseln und psql starten
sudo -u postgres psql
```
### 6.2 Benutzer (Rollen) erstellen
```sql
-- 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`:
> ```bash
> openssl rand -base64 32
> ```
### 6.3 Datenbanken erstellen
```sql
-- 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:
> ```bash
> sudo locale-gen de_DE.UTF-8
> sudo update-locale
> ```
### 6.4 pgvector in der Vektordatenbank aktivieren
```sql
-- 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
```sql
-- 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
```bash
# 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
```sql
-- 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
```sql
-- 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)
```sql
-- 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
```sql
-- 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
```sql
-- 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
```sql
-- 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 |
```sql
-- 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:
```sql
-- 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
```sql
-- 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)**
```bash
sudo nano /etc/n8n/environment
```
```env
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**
```yaml
# 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:
> ```bash
> 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:**
```sql
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:
```bash
sudo nano /etc/gitea/app.ini
```
```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:
```bash
sudo systemctl restart gitea
```
### 10.2 Gitea-Migration von SQLite zu PostgreSQL
Falls Gitea bisher SQLite verwendet:
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
sudo nano /etc/cron.d/postgresql-backup
```
```cron
# 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
```
```bash
# 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.
```sql
-- 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:
```sql
-- 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
```sql
-- 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
```sql
-- 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.
```ini
# ============================================================
# 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
```bash
# 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`
```bash
# 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`
```bash
# 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`
```bash
# Datenbanken auflisten
sudo -u postgres psql -c "\l"
# Datenbank erstellen
sudo -u postgres createdb -O besitzer_user datenbankname
```
### 14.2 Performance-Probleme
```sql
-- 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
```bash
# 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/
```
```sql
-- 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
```bash
# 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
```bash
# 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:
```bash
# In postgresql.conf
ssl = on
ssl_cert_file = '/etc/postgresql/16/main/server.crt'
ssl_key_file = '/etc/postgresql/16/main/server.key'
```
```bash
# 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
```bash
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
```bash
sudo -u postgres psql # Als Superuser verbinden
psql -h localhost -U user -d dbname # Als bestimmter Benutzer verbinden
```
### Schnelle Datenbank-Operationen
```bash
# 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:** *23.02.2026*
> **Autor:** *Adminisrator*
> **Version:** 1.0