--- title: PostgreSQL Profice Dokumentation description: published: true date: 2026-02-23T10:28:30.295Z 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 @startuml skinparam backgroundColor #1a1a2e skinparam defaultFontColor white skinparam defaultFontSize 14 skinparam roundCorner 10 skinparam shadowing false skinparam rectangle { BackgroundColor #2a2a4a BorderColor #5599bb FontColor white } skinparam package { BackgroundColor #1a1a2e BorderColor #e0e0e0 FontColor white FontSize 18 } skinparam component { BackgroundColor #336791 BorderColor #fff FontColor white } package "Debian Server" { rectangle "n8n\n(Workflows)" as n8n #ff6d5a rectangle "Gitea\n(Git-Server)" as gitea #609926 rectangle "PostgreSQL 16" as pg #2a2a4a { component "DB: n8n" as db1 #336791 component "DB: n8n_vectors" as db2 #8b5cf6 component "DB: gitea" as db3 #609926 component "Extension: pgvector" as ext #5599bb } } 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. ```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