5.8 KiB
5.8 KiB
PROJ-30: Volltext-Index: Xapian → Manticore Search Migration
Status: Deployed
Created: 2026-03-28 Last Updated: 2026-04-04
Dependencies
- Requires: PROJ-5 (Speicherung & Indexierung) — bestehende Index-Abstraktion
- Requires: PROJ-21 (Multi-Tenancy) — per-Tenant Index-Isolation
Motivation
Xapian erfordert CGO und libxapian-dev als System-Dependency. Das verhindert:
- Docker-Images (CGO-Build in Containern komplex, Build-Image groß)
- Einfache Cross-Compilation
- Reproduzierbare Builds ohne native Abhängigkeiten
Entscheidung: Manticore Search statt ursprünglich geplantem Bleve.
Warum Manticore statt Bleve
Das primäre Kriterium ist Datenmenge und Performance, nicht Einfachheit. Manticore ist eine in C++ geschriebene Such-Engine (Fork von SphinxSearch) mit MySQL-kompatiblem Protokoll:
| Metrik | Bleve | Manticore |
|---|---|---|
| Suchlatenz bei 1M Docs | 50–200ms | 5–20ms |
| Index-Durchsatz | ~5.000 Docs/s | ~50.000 Docs/s |
| RAM bei 10M Mails | 4–8 GB | 1–2 GB |
| Columnar Storage | Nein | Ja |
| Highlighting | Ja | Ja |
| Fuzzy-Search | Ja | Ja |
| CGO im Go-Code | Nein | Nein (MySQL-Protokoll) |
Manticore läuft als eigener Systemd-Service — kein embedded Mode. Der Trade-off (externer Dienst) ist bei Performance-Priorität gerechtfertigt.
Elasticsearch/OpenSearch wurden als Alternative geprüft — zu schwer, zu viel Infrastruktur für On-Premise.
Architektur nach Migration
PostgreSQL
→ Metadaten: From, To, Subject, Date, message_id, tenant_id
→ Dedup, Audit-Log, User, Tenant, Labels
→ strukturierte Filter-Queries
Manticore Search (Port 9306, MySQL-Protokoll)
→ Volltext-Body + Anhang-Text
→ Ein Index pro Tenant (saubere Mandantentrennung)
→ Real-Time-Index (neue Mail sofort suchbar)
→ Highlighting in Suchergebnissen
→ BM25+ Relevanz-Ranking
Suchanfrage in Go:
→ PostgreSQL: filtert tenant_id, Datum, From/To → IDs
→ Manticore: Volltext-Relevanz über IDs → gerankte Ergebnisse
→ Merge in API-Handler
User Stories
- Als Betreiber möchte ich archivmail ohne CGO kompilieren können (
CGO_ENABLED=0). - Als Nutzer möchte ich auch bei großen Archiven (>1M Mails) schnelle Suchergebnisse (<20ms).
- Als Nutzer möchte ich Treffer im Suchtext hervorgehoben sehen (Highlighting).
- Als Admin möchte ich nach einem Absturz den Index mit einem Kommando neu aufbauen können.
Acceptance Criteria
- Manticore läuft als Systemd-Service auf dem Server (Port 9306, nur localhost)
internal/index/manticore.goersetztxapian.goundxapian_stub.go- Gleiche Interface-Signatur (
IndexMail,Search,Delete,Close) - Go-Integration via
go-sql-driver/mysql(kein CGO) - Pro Tenant ein Manticore Real-Time-Index:
emails_tenant_{id} - Indizierte Felder:
id,subject,from_addr,to_addr,body,attachment_names,date_ts - Suchanfragen: Volltext, FROM:, TO:, SUBJECT:, SINCE:, BEFORE:
- Migration-Kommando:
archivmail reindexbaut alle Tenant-Indizes neu auf CGO_ENABLED=0 go buildfunktioniert nach Migration- Manticore-Port 9306 nur auf localhost gebunden (kein externer Zugriff)
update.shprüft ob Manticore installiert ist und installiert es bei Bedarf
Edge Cases
- Bestehender Xapian-Index wird NICHT automatisch migriert —
reindexliest Roh-Mails aus Storage neu ein - Während
reindexläuft: Suche liefert unvollständige Ergebnisse (Warnung im Log) - Manticore-Dienst nicht erreichbar → Suche gibt Fehler zurück, Metadaten-Suche (PostgreSQL) bleibt verfügbar
- Index beschädigt →
reindexbehebt, kein Datenverlust (Roh-Mails in Storage sind Source of Truth) - Neuer Tenant → Index wird beim ersten Mail-Import automatisch angelegt (
CREATE TABLE IF NOT EXISTS)
Technical Requirements
- Engine: Manticore Search (GPLv2)
- Protokoll: MySQL-kompatibel, Port 9306
- Go-Treiber:
github.com/go-sql-driver/mysql - CGO: Nicht erforderlich im Go-Code
- Index-Typ: Real-Time Index pro Tenant
- Installation: Offizielles Manticore APT-Repository — Paket bleibt über
apt upgradeaktuell - Systemd:
manticore.serviceläuft parallel zuarchivmail.service - Konfiguration: Neuer Abschnitt
manticore:in/etc/archivmail/config.yml
manticore:
dsn: "manticore@tcp(127.0.0.1:9306)/"
enabled: true
Migration Path
1. Manticore-APT-Repo einrichten + Paket installieren:
curl -s https://repo.manticoresearch.com/manticore-repo.noarch.deb -o /tmp/manticore-repo.deb
dpkg -i /tmp/manticore-repo.deb && apt update && apt install -y manticore
# danach: apt upgrade hält Manticore automatisch aktuell
2. manticore.go implementieren (gleiche Interface wie xapian.go)
3. Build-Tag in xapian.go anpassen (beide parallel lauffähig während Entwicklung)
4. Integrations-Tests gegen Manticore
5. xapian.go + xapian_stub.go entfernen
6. `archivmail reindex` auf Server ausführen
7. Alten Xapian-Index-Ordner löschen (/var/archivmail/xapian/)
8. update.sh: Manticore-Installations-Check hinzufügen
Implementation Notes
internal/index/manticore.go— vollständige Implementierung mitManticoreTenantManager+manticoreIndexTenantIndexer-Interface inindex.goabstrahiert Manticore und Legacy-Xapian-Pfad- Morphologie:
lemmatize_de_all,stem_en(Manticore 25.0.0 —stem_denicht verfügbar via MySQL-Protokoll) - fnv64a-Hash leitet uint64-Row-ID aus SHA-256-Mail-ID ab
escapeManticoreMatch()schützt vor Injection in MATCH()-Ausdrückecmd importundcmd import-pilerebenfalls auf Manticore-Backend umgestellt- Deployed auf 131 (bookworm) und 132 (trixie) — Manticore 25.0.0 (bookworm-Paket)
Deployment
- 192.168.1.131: Manticore 25.0.0, 65 Mails indiziert
- 192.168.1.132: Manticore 25.0.0, 14.160 Mails indiziert