sendeffect WEBanizer GmbH · Infrastructure & Operations Intern · Vertraulich

Migrationsanalyse

Bestandsinfrastruktur im Profil — Grundlage für die neue Cloud-Umgebung

Hardware-, Datenbank- und Sizing-Analyse der alten sendeffect/IEM-Server. Sie liefert die belastbare Zahlenbasis dafür, wie groß die neue VM-Infrastruktur initial dimensioniert werden muss, um die Daten zu migrieren.

Stand19.06.2026
VerantwortlichSilvan Usleber
Bezugold-infra-migration-analysis
StatusLiving Document
Heute

Alt-Infrastruktur

10 Bare-Metal-Server (5× DB · 2× Web · 3× MTA)
~140 CPU-Kerne · ~1,3 TB RAM
~2,9 TB Datenbanken (logisch)
10/10 auf EOL-Betriebssystemen
−73 %
der Tenants entfallen (inaktiv)
Ziel ~550 GB
Ziel

Neue Cloud (OpenStack)

5 VMs (App+DB · KumoMTA · Monitoring)
~34 vCPU · ~168 GB RAM
~2,55 TB SSD + ~1 TB Backups
100 % aktuelle, gepatchte OS
01

Management Summary

Das Wichtigste in Kürze für die Kapazitätsentscheidung

10
Bestandsserver (Bare Metal), verteilt auf DB-, Web- und Versand-Tier
557 → 153
Tenants gesamt → aktiv. Rund 73 % sind nach der 1-Jahres-Regel inaktiv
~550 GB
Reale Zieldatenmenge auf Platte (aktive Tenants + komplette Statistik-Historie)
10 /10
Server laufen auf End-of-Life-Betriebssystemen — Migration ist auch sicherheitsgetrieben

Die Bestandsflotte umfasst zehn Bare-Metal-Server mit zusammen rund 140 CPU-Kernen, etwa 1,3 TB RAM und mehreren Terabyte Datenbankvolumen. In Summe halten die fünf datenbanktragenden Server rund 2.891 GB logisches Datenvolumen.

Entscheidend für das Sizing sind zwei Hebel, die die Datenmenge drastisch reduzieren. Erstens: Von rund 557 Tenants sind nur 153 aktiv (Login, Versand oder Job innerhalb des letzten Jahres) — rund 73 % können entfallen. Zweitens: Das logische Volumen aus information_schema überzeichnet den realen Plattenbedarf um etwa das 1,7-fache (auf Server 03 verifiziert: 1.106 GB logisch vs. 656 GB real). Auf realer Plattenbasis schrumpft das Migrationsziel damit auf ~550 GB (aktive Tenants inkl. kompletter Statistik) bzw. ~240 GB für die reinen Kerndaten.

Hinzu kommt ein operativer Treiber: alle zehn Server laufen auf abgekündigten Betriebssystemen (Debian 8/9, Ubuntu 16.04/18.04). Ein DB-Server läuft seit über acht Jahren ohne Reboot — also ohne Kernel-Patches. Das verschärft die Dringlichkeit der Migration unabhängig von der reinen Kapazitätsfrage.

✓ Kernempfehlung Initial-Buchung

Start mit fünf OpenStack-VMs (~34 vCPU / ~168 GB RAM / ~2,55 TB SSD + ~1 TB Backup-Objektspeicher): 2× All-in-one-LAMP (App+DB), 2× KumoMTA und 1× Monitoring. Phasenstart mit je einem Knoten möglich (18 vCPU / 88 GB / ~1,4 TB). Der primäre Hebel ist RAM (Buffer-Pool), nicht die vCPU-Zahl — die aktuelle Pilot-VM mit 4 vCPU / 8 GB ist als Produktiv-DB zu klein.

02

Untersuchungsumfang

Welche Server analysiert wurden — und mit welcher Rolle

Ziel der Analyse ist die vollständige Inventarisierung der alten sendeffect/IEM-Infrastruktur (Hardware sowie Datenbank- und Migrations-Footprint), um sie der neuen VM-Umgebung gegenüberzustellen und den initialen Ressourcenbedarf für die Datenmigration zu schätzen. Alle Bestandsserver werden nach der Migration außer Betrieb genommen. Die Hostnamen folgen dem Schema 11335-NN.root.easyname.cloud; Zugangsdaten unterscheiden sich pro Server.

Vollständiges Inventar (Stand 17.06.2026) — alle Server profiliert.
TierServerRolleDB-AnalyseStatus
Datenbank03reine DBvollständigHW + DB erfasst
05reine DBvollständigHW + DB erfasst
07gemischt (Web + DB)vollständigHW + DB erfasst
08gemischt (Web + DB)vollständigHW + DB erfasst
12gemischt (Web + DB)vollständigHW + DB erfasst
Web02nur Webkeine DBHW erfasst
04nur Webkeine DBHW erfasst
Versand (MTA)06PowerMTA-Relayn/aaktiv, im Scope
10PowerMTA-Relayn/aaktiv, im Scope
13PowerMTA-Relay (laststärkster)n/aaktiv, im Scope
Aux09se2ifo / ifo-Institut (Custom)~1,4 GBim Scope (Sonderfall)

Außerhalb des Scope: Server 11 (einzelne, fremde Kundenwebsite) und 01 (bereits abgebaut). Die Server unterscheiden sich stark in Spezifikation, Alter und Größe — sie wurden einzeln erfasst und nicht voneinander hochgerechnet.

03

Methodik & Zählweise

Wie die Zahlen entstanden sind — und wie sie zu lesen sind

Tenancy-Modell: Tenant = künftige Instanz

Jede sendlx_<N>-Datenbank entspricht einer IEM-Installation (ein vHost sf<N>.sendsfx.com) mit vielen Nutzern. Entscheidend: jede Nutzerzeile (userid/ownerid) ist selbst ein Tenant. In der neuen Umgebung wird jeder dieser Nutzer zu einer eigenen Instanz (eigene DB + Webroot). Die Zahl der neuen Instanzen richtet sich also nach der Zahl der aktiven Nutzer, nicht nach der Zahl der alten Datenbanken.

Aktiv-Regel (vereinbart)

Ein Nutzer gilt als aktiv, wenn er innerhalb des letzten Jahres eingeloggt war ODER versendet ODER einen Job ausgeführt hat. Login allein reicht nicht — die API versendet auch ohne Login. Signale: users.lastloggedin, MAX(stats_newsletters.starttime) je Absender und MAX(jobs.jobtime) je Owner.

⚠ Wichtige Lesehilfe: logisch vs. real auf Platte

data_length + index_length aus information_schema überzeichnet den tatsächlichen Plattenbedarf. Auf Server 03 verifiziert: 1.106 GB logisch gegenüber 656 GB real per df (~1,7×) — Ursache sind aufgeblähte Index-Statistiken bei Compact-Tabellen, keine Kompression. Alle GB-Angaben in diesem Bericht sind, sofern nicht anders vermerkt, logische Obergrenzen; real auf Platte ≈ 0,6×. Die KEEP-Prozentsätze sind Verhältnisse und davon unberührt. Ein Dump-and-Reload nach MariaDB landet nahe der realen Plattenbasis.

Sizing-Ansatz (bewusst „leichtgewichtig")

  • Pro-DB-/Tabellen-Größen über information_schema.tables (sofort verfügbar) — echte Zeilenzahlen via COUNT(*), da table_rows stark unterschätzt.
  • Subscriber-Zuordnung zum Owner über list_subscribers ⋈ lists gruppiert nach Owner — jeder Subscriber gehört genau einem Owner.
  • Statistik-Zuordnung ohne Scan der großen Tabellen: stats_newsletters trägt Pro-Kampagnen-Rollups; KEEP-Anteil daraus auf die realen Tabellengrößen anwenden.

Sicher aus der Migration ausschließbar

Bounce-Logs (list_subscriber_bounces_misc), Arbeits-/Temp-Tabellen (*_temp, aaa_*) und rekonstruierbare Suppression-Hashes (hashblacklist_*, list_subscriber_md5/sha*). Die Frage der Statistik-Aufbewahrung (komplette Historie vs. rollierendes Fenster) ist die größte verbleibende Stellschraube und in Abschnitt 10 als offener Punkt geführt.

04

Datenbank-Tier im Detail

Fünf Server (03, 05, 07, 08, 12) — Hardware, Datenbank und Migrationsszenarien

Jeder DB-Server wurde einzeln erfasst. Pro Server zeigen wir das Hardware-Profil, die Datenbank-Eckdaten und die vier Migrationsszenarien (jeweils logische GB). Die Balken sind je Server relativ zum „Alles"-Szenario skaliert.

03
11335-03 · DB-Host 10.254.25.71
reine DB · der mit Abstand größte Datenträger
Debian 8 · EOLDRBD-repliziert
Modell
HP DL360 Gen9 · Bare Metal
CPU
2× Xeon E5-2620 v3 · 12C/24T
RAM
251 GiB
Disk (/data)
5,0 TB DRBD · 656 GB real
DB-Engine
Percona 5.6.48
Datenvolumen
1.106 GB logisch · 33 Schemata
Tenants
37 aktiv / 123 gesamt
Instanzen
9× sendlx
Migrationsszenarien (logisch)
Alles (volle DBs)1.106 GB
Kern + alle Stats, aktiv446 GB
Kern + Stats ≤1 J., aktiv347 GB
Nur Kern, aktiv337 GB

Datenhaltung durch aktive Nutzer: Hier halten die aktiven Nutzer die Daten — der Inaktiv-Filter spart nur ~33 GB. Dominanter Hebel ist das Statistik-Fenster (~109 GB komplette Historie vs. ~10 GB nur ≤1 Jahr). Dominiert von sendlx_27 (~263 GB, 99 % aktiv) und sendlx_6 (~157 GB). Vollständig verwerfbar: sendlx_25 und sendlx_26 (vorher verifizieren).

05
11335-05 · DB-Host 10.254.25.46
reine DB · stärkste Reduktion durch Inaktiv-Filter
Uptime 8,3 JahreDebian 8 · EOL
Modell
HP DL360 Gen9 · Bare Metal
CPU
2× Xeon E5-2620 v4 · 16C/32T
RAM
252 GiB · Buffer-Pool 128 GiB
Disk
3,8 TB (2,2 TB belegt)
DB-Engine
Percona 5.6.47
Datenvolumen
184 GB logisch · 47 Schemata
Tenants
15 aktiv / 93 gesamt
Instanzen
7× sendlx
Migrationsszenarien (logisch)
Alles (volle DBs)184 GB
Kern + alle Stats, aktiv17 GB
Kern + Stats ≤1 J., aktiv5 GB
Nur Kern, aktiv4 GB

Stärkste Reduktion über den Inaktiv-Filter: der Inaktiv-Filter dominiert (Kern 64,5 → ~4 GB). Große Instanzen sind quasi tot (sendlx_2 39 M Subscriber @ 0,1 % aktiv; sendlx_4 und 21 vollständig inaktiv). Echter Migrationsinhalt ≈ 110 GB; ein Dump-and-Reload gewinnt zusätzlich ~137 GB Fragmentierung zurück.

⚠ Operatives Risiko

Uptime 3.031 Tage (~8,3 Jahre) — seit acht Jahren keine Kernel-Patches oder Reboots. Erhebliches Betriebs- und Sicherheitsrisiko, das die Migration zusätzlich begründet. Die 2,2 TB belegt auf / sind zu ~1,9 TB nicht datenbankbezogen (für den Operator zu klären, nicht migrationsrelevant).

07
11335-07.root.easyname.cloud
gemischt (Web + DB) · der erste vollständig analysierte Server
Debian 9 · EOLDB vollständig
Modell
HP DL360 Gen9 · Bare Metal
CPU
2× Xeon E5-2620 v4 · 16C/32T
RAM
188 GiB · Swap 31 GiB
Disk
1,7 TB (1,2 TB belegt)
DB-Engine
Percona 5.7.30 · Buffer-Pool 128 GiB
Datenvolumen
436 GB · 26 Schemata
Tenants
27 aktiv / ~101 gesamt
Instanzen
8× sendlx (sf30–38)
Migrationsszenarien (logisch)
Alles (volle DBs)436 GB
Kern + alle Stats, aktiv93 GB
Kern + Stats ≤1 J., aktiv60 GB
Nur Kern, aktiv57 GB

Charakteristik: Größter Hebel ist hier das Verwerfen der Historie (436 → 121 GB), gefolgt von inaktiven Tenants (121 → 57 GB). Nur 3,4 % aller Opens sind jünger als ein Jahr. Borderline-Fälle vor dem Verwerfen prüfen: sf36 (0 aktiv, 15 GB Opens) und sf32/senddigital (Aktiv-Stichtag um nur 4 Tage verfehlt).

08
11335-08.root.easyname.cloud
gemischt (Web + DB) · dringlichster Migrationskandidat
Last ~33/32 im PeakDisk 94 % vollDebian 9 · EOL
Modell
HP DL380 Gen9 · Bare Metal
CPU
2× Xeon E5-2620 v4 · 16C/32T
RAM
188 GiB
Disk
1,7 TB · 94 % voll (108 GB frei)
DB-Engine
Percona 5.7.34
Datenvolumen
620 GB logisch · 51 Schemata
Tenants
37 aktiv / 113 gesamt
Instanzen
12× sendlx (sf37–49)
Migrationsszenarien (exakt gemessen)
Alles (volle DBs)620 GB
Kern + alle Stats, aktiv220 GB
Kern + Stats ≤1 J., aktiv112 GB
Nur Kern, aktiv103 GB

Dringlich: Last ~33 bei 32 Threads zur deutschen Versand-Hauptzeit (19:00 CEST) und nur noch 108 GB freie Platte. Starker Kandidat für eine frühe Migration. Lesson learned: die Opens-Proxy-Schätzung (~142 GB) überzeichnete den exakten Kern-KEEP (~103 GB) — Kerntabellen müssen über die Subscriber-Ebene attribuiert werden, nicht über den Absender-/Opens-Proxy.

12
11335-12.root.easyname.cloud
gemischt (Web + DB) · jüngste & gesündeste Box
Debian 10 · neueste OSLast ~5 (gesund)
Modell
HP DL360 Gen10 · Bare Metal
CPU
2× Xeon Silver 4110 · 16C/32T
RAM
188 GiB
Disk
2,7 TB (62 % belegt)
DB-Engine
Percona 5.7.27
Datenvolumen
545 GB logisch (228 GB frei)
Tenants
37 aktiv / 115 gesamt
Instanzen
8× sendlx (sf25,50–54,200,969)
Migrationsszenarien (logisch)
Alles (volle DBs)545 GB
Kern + alle Stats, aktiv138 GB
Kern + Stats ≤1 J., aktiv120 GB
Nur Kern, aktiv111 GB

Stark fragmentiert: 228 GB von 545 GB sind freier (reklamierbarer) Platz — ein Dump-and-Reload nach MariaDB gewinnt diese zurück. Dominiert von sendlx_200 (202 M Subscriber, 13 aktive Tenants). Inaktiv: sendlx_969 (24 Nutzer, 0 aktiv, 17 GB Opens verwerfbar).

Flotten-Rollup — alle fünf DB-Server

Alle fünf Server sind exakt vermessen (keine Proxys mehr). Die Tabelle zeigt logische information_schema-GB; die reale Plattenbasis liegt bei ~0,6× (siehe Lesehilfe in Abschnitt 03).

Logisches Datenvolumen je Szenario und Server.
ServerVolle DBsKern aktiv+ Stats ≤1 J.+ alle StatsTenants aktiv
031.10633734744637
05184451715
0743657609327
0862010311222037
1254511112013837
Summe (logisch)~2.891~612~644~914153
≈ real auf Platte~1,7 TB~240~385~550
Erkenntnis

Das Migrationsziel ist serverabhängig: 07 und 05 schrumpfen massiv über inaktive Nutzer, 03 kaum (dort halten aktive Nutzer die Daten — nur das Statistik-Fenster hilft). Selbst auf realer Plattenbasis liegt der aktive Kern bei ~240 GB über drei der fünf DB-Server. Daraus folgt: die neue Umgebung braucht mehrere TB-fähige VMs — die aktuelle Pilot-VM mit nur 100 GB Disk ist ausdrücklich ein Pilot, nicht die Zielkapazität.

05

Web-Tier

Server 02 & 04 — reine Web-Server, ohne Datenbank

Diese beiden Server halten keine Datenbanken; erfasst wurde die Hardware für ein vollständiges Bild der Alt-Flotte. Über ihre Webroots wurde zudem die Zuordnung der reinen DB-Server bestätigt (10.254.25.71 = Server 03, 10.254.25.46 = Server 05).

02
11335-02
nur Web
Debian 9 · EOL
Modell
HP SE1220 · Bare Metal
CPU
2× Xeon L5520 (~2009) · 8C/16T
RAM
31 GiB
Disk
239 GB (166 GB belegt)

Sehr alte CPU (Nehalem-EP). Last ~11 von 16 — geschäftiger Web-Tier.

04
11335-04
nur Web
Debian 9 · EOL
Modell
HP DL380 G6 · Bare Metal
CPU
2× Xeon E5645 (~2010) · 12C/24T
RAM
62 GiB
Disk
206 GB (122 GB belegt)

Kürzlich rebootet (Uptime 14 Tage), aktuell im Leerlauf (Last ~0,45).

06

Versand-Tier: PowerMTA → KumoMTA

Server 06, 10, 13 — alle aktiv und im Scope

Das Versand-Tier wird anders dimensioniert als das DB-Tier: Treiber sind die Spitzen-Versandrate, die Verbindungs-Concurrency, die Anzahl Versand-IPs sowie der (kleine) Live-Spool und die Log-/Accounting-Aufbewahrung. Die drei Bounce-Log-NFS-Shares, die die Web/DB-Boxen einhängen, sind die MTAs selbst — es gibt keine separate Bounce-Infrastruktur.

Versand-Tier — Hardware und PowerMTA-Kennzahlen.
ServerHardwarePMTAVersand-IPsPeak out/h/data belegt
06DL360 Gen9 · 20C/40T · 64 GB · Ubuntu 16.04v4.0r171.832~333K238 GB
10DL360p Gen8 · 24C/48T · 64 GB · Debian 9v5.0r9386~349K176 GB
13DL360 Gen9 · 24C/48T · 128 GB · Ubuntu 18.04v5.0r91.691~802K858 GB
Summe~68C/136T · ~256 GB RAM~3.909~1,48M~1,27 TB

Server 13 ist der laststärkste (pmtad ~69 % CPU, ~2,95 Mrd. ausgehende Nachrichten Lifetime). Alle drei laufen auf EOL-Betriebssystemen — teils mit 230–473 Tagen Uptime, um den Versand nicht zu unterbrechen.

✓ KumoMTA-Einordnung

Die aggregierte Spitzenlast von ~1,48 Mio. Nachrichten/Stunde (~410/s) ist für KumoMTA (Rust/async) moderat — Rohleistung ist nicht der Engpass. Der schwierige Teil sind die ~3.909 Versand-IPs (IP-Pools, Reputations-Kontinuität, Warmup) sowie Spool und Queue. KumoMTA kann alle drei vermutlich auf weniger/kleinere Knoten konsolidieren; dimensioniert wird nach IP-Anzahl, Concurrency, Spool-Disk und Log-Aufbewahrung — nicht nach CPU. Der Live-Spool ist klein (GB-Bereich); /data ist überwiegend Accounting-/Bounce-Log-Historie.

07

Sonderfälle

Server 09, 11 und 01 — Einordnung und Scope-Entscheidung

  • Server 09 (se2ifo / ifo-Institut) — im Scope: sendeffect-eigene Custom-Integration für den Kunden ifo-Institut (Newsletter/Presse). Datenbanken zusammen ~1,4 GB, aktiv. Webroot 2,9 GB, davon 2,6 GB verwerfbare Errorlogs — die eigentliche App ist klein. Kein sendlx_-Tenant, keine MTA. Als kleiner Custom-/Sondermigrations-Posten zu behandeln (mit dem ifo-Kunden abstimmen).
  • Server 11 — außerhalb des Scope: eine einzelne, fremde Kundenwebsite (~5 MB). Keine sendeffect-Produktinfrastruktur.
  • Server 01 — entfällt: bereits vor längerer Zeit außer Betrieb genommen.
08

Zielumgebung & Übersetzung Alt→Neu

Warum sich die alte Kernzahl auf deutlich weniger neue Ressourcen abbildet

Pilot-VM sendeffect-01 (Dogado / group.one OpenStack)

OpenStack Nova / KVM auf AMD EPYC-Rome (Zen 2), 4 vCPU, 8 GiB RAM (kein Swap), 100 GB Disk (vda, ext4, ~92 GB frei), Ubuntu 24.04 / MariaDB 11.8.8 / PHP 8.5. Achtung: innodb_buffer_pool_size steht auf dem Default von 128 MB (ungetunt). Diese VM ist ausdrücklich nur ein Pilot.

Übersetzung der Rechenleistung

  • Das alte DB-Tier bietet ~76 physische Kerne / 152 Threads über fünf Boxen und ~1 TB RAM — ist aber meist im Leerlauf (typische Last 3–10/Box, nur 08 im Peak gesättigt).
  • Neue EPYC-Rome-Kerne sind je Thread ~1,5–2× schneller als die alten Xeons → die aktive Last bildet sich auf deutlich weniger moderne vCPUs ab. vCPUs sind nicht der Engpass.
  • Die IEM-Versandlast ist RAM- und IO-gebunden (Subscriber-Listen-Scans, Stats-Inserts), nicht CPU-gebunden ⇒ der Buffer-Pool (RAM) ist die primäre Stellschraube; auf das heiße Working-Set dimensionieren.

Warum dann massiv weniger RAM?

Das ist der wichtigste Punkt für die Buchung — und auf den ersten Blick wirkt er widersprüchlich, weil die alten Boxen zusammen ~1 TB RAM hatten. Entscheidend ist, wofür dieser Speicher diente: Jede der fünf alten DB-Boxen betrieb einen InnoDB-Buffer-Pool von 128 GiB — zusammen rund 640 GiB. Diese Pools waren pauschal groß konfiguriert und hielten die historischen Daten aller ~557 Tenants vor, von denen 73 % inaktiv sind und faktisch nie abgefragt werden.

In der neuen Umgebung muss der Buffer-Pool nur das heiße Working-Set der 153 aktiven Tenants cachen (aktiver Kern ~240 GB auf Platte, davon zu jedem Zeitpunkt nur ein Bruchteil wirklich „heiß") — nicht die gesamte historische Datenmenge. Damit genügen ~80–90 GB Buffer-Pool über zwei App+DB-VMs (je ~40–45 GB), eingebettet in 128 GB RAM.

Buffer-Pool: alt vs. neu
Alt — 5× 128 GiB~640 GiB
Neu — 2× ~42 GB~85 GB

Rund 7× weniger Buffer-Pool — getrieben durch (1) den Wegfall von 73 % der Tenants, (2) die Dimensionierung auf das heiße Working-Set statt auf die Gesamtdatenmenge und (3) den Wegfall der pauschal überdimensionierten Alt-Konfiguration. RAM bleibt damit der primäre Hebel, der absolute Bedarf ist aber dramatisch kleiner, als die alte TB-Zahl vermuten lässt.

Planungsbasis

Empfehlung: alle Statistik-Historie migrieren (Open-/Click-Daten sind wertvoll; ein zeilenweises Recency-Filtern auf 100M+-Zeilen-Tabellen ist aufwendiger als das schlichte Mitnehmen). Planungsbasis = „aktiv + alle Stats" ≈ ~914 GB logisch / ~550 GB auf Platte. Inaktive Tenants nicht vorab löschen — stattdessen großzügigen Puffer einplanen, um sie aufzunehmen. Die endgültige keep/drop-Entscheidung ist pro Tenant zu treffen und blockiert das Sizing nicht.

09

Empfehlung: OpenStack-Buchung

Empfohlene Reihenfolge und Dimensionierung der ersten Knoten

Architektur = mehrmandantenfähiges All-in-one-LAMP pro VM (Apache + PHP-FPM + MariaDB, eine DB pro Tenant). Übersetzung: alte Flotte ~140 Kerne / ~1,3 TB RAM über 10 Bare-Metal-Boxen → neu braucht deutlich weniger, weil 73 % der Tenants entfallen, EPYC-Kerne stärker sind, KumoMTA effizienter als PowerMTA arbeitet und Dump-and-Reload Fragmentierung beseitigt.

Empfohlene initiale Buchung.
RolleVMsje VMZwischensumme
App+DB (All-in-one LAMP)28 vCPU / 64 GB / 750 GB SSD16 vCPU / 128 GB / 1,5 TB
KumoMTA (PMTA-Ersatz)28 vCPU / 16 GB / ~400 GB SSD · 10 GbE16 vCPU / 32 GB / ~800 GB
Monitoring (Prometheus/Grafana)12 vCPU / 8 GB / 250 GB2 vCPU / 8 GB / 250 GB
Compute gesamt5~34 vCPU / ~168 GB / ~2,55 TB SSD
Backups (Objektspeicher, keine VM)~1 TB

Begründung je Rolle

  • App+DB (RAM ist der Regler): fasst ~550 GB aktiv + alle Stats plus ~40 GB Webroots plus Puffer; Buffer-Pool ~40–45 GB/VM (⚠ Pilot steht auf 128 MB Default — auf ~70 % des RAM tunen). ~75 Tenants/VM. Bei schlechter Cache-Hit-Rate RAM erhöhen / Knoten hinzufügen.
  • KumoMTA (gegen Kumo-Hardwareguide validiert): 8 vCPU/16 GB liegt zwischen „moderat" und „seriöser Startpunkt" → ausreichend für ~410 msg/s. Dedizierter SSD/NVMe-Spool (~300 GB) auf separater Mount-Ebene von den Logs; IOPS > Kapazität; 10 GbE. 2 Knoten für HA, Patch/Reboot ohne Mail-Stillstand und IP-Pool-/Reputations-Segmentierung über ~3.909 IPs.
  • Monitoring: schlank starten mit nur 2 vCores / 8 GB / 250 GB (Prometheus + Grafana + Alertmanager) — das spart initial 2 Kerne gegenüber einer 4-vCore-Auslegung. Erst auf 4/16/500 erhöhen, wenn Loki dazukommt (KumoMTA-/Apache-Logs sind volumenstark — der eigentliche Disk-/RAM-Treiber).
✓ Phasenstart & Resize-Strategie warum lean starten möglich ist

Phasenstart: je 1× App+DB, KumoMTA und Monitoring = 18 vCPU / 88 GB / ~1,4 TB (Monitoring lean mit 2 vCores → 2 Kerne weniger als bei 4-vCore-Auslegung). Die zweiten App+DB- und KumoMTA-Knoten kommen mit dem Migrationsfortschritt dazu (elastisch). Disk wächst live (Cinder-Volume erweitern, kein Downtime) — wachsende Daten (DB-Datadir, MTA-Spool, Monitoring) auf separate Cinder-Volumes legen. vCPU/RAM-Resize = Flavor-Resize mit kurzem Reboot; hinter dem 2-Knoten-HA-Paar einzeln durchführbar → keine nutzerseitige Downtime. Vor dem Rest die Buffer-Pool-Hit-Rate / IO an der ersten großen Tenant-Migration validieren (Prinzip „groß zuerst migrieren").

10

Resilienz & Hochverfügbarkeit

Warum die neue Architektur einen Vorfall wie am 19.06.2026 entschärft

Ein Produktionsvorfall während der Analyse macht greifbar, warum die neue Architektur — eine DB pro Tenant, eigener PHP-FPM-Pool je Tenant — nicht nur sauberer, sondern deutlich ausfallsicherer ist, und welche Maßnahmen das absichern.

⚠ Auslösender Vorfall 19.06.2026

Ein korrupter InnoDB-Index auf sendlx_6.subscribers_data (Server 03, Percona 5.6) brachte die Datenbank in einen Crash-Loop. Der logische Restore des Hosters (mysqldump) lief zum Zeitpunkt der Prüfung bereits über 5 Stunden und war erst zu ~50–60 % fertig — die vollständige Wiederherstellung hätte also noch einmal etwa so lange gebraucht. Die ganze Zeit über hielt er eine Schreibsperre auf der 40-GB-Tabelle. Weil die Alt-Infrastruktur eine geteilte DB (sendlx_6 = viele Tenants) und einen geteilten PHP-FPM-Pool auf dem Web-Knoten 02 nutzte, legte diese eine korrupte Tabelle sämtliche Sites auf 02 lahm (sf12/14/15/16 — inkl. ganz anderer DBs). Zusätzlich zeigte sich, dass die alte Replikation still verstummt war (der Slave-SQL-Thread auf 03 war Stunden zuvor an einem Fehler gestorben) — also kein Failover.

Warum die neue Architektur das entschärft

  • Eine DB pro Tenant: eine korrupte Tabelle betrifft nur die DB dieses einen Tenants — Tabellen und Sperren anderer Tenants bleiben unberührt.
  • Eigener PHP-FPM-Pool je Tenant (eigener User/Socket): ein Tenant, der auf seine DB blockiert, kann die Worker anderer Tenants nicht aushungern. Das ist die eigentliche Behebung der Tenant-übergreifenden Kaskade vom 19.06.
  • Kleinere, frische Tabellen (Dump-and-Reload, modernes Row-Format + full_crc32-Prüfsummen): schnelleres Erkennen, Reparieren und Wiederherstellen.
  • Kleinerer Blast-Radius: von „alle Tenants des Web-Knotens, über mehrere DB-Server hinweg" → „höchstens die Tenants einer VM, meist nur der betroffene".
Verbleibendes geteiltes Risiko

Tenants auf derselben VM teilen sich einen mariadbd-Prozess. Isolierte Tabellenkorruption sperrt zwar keine anderen Tenants — aber eine Korruption, die die Engine in einen Crash-Loop zwingt, nimmt alle DBs dieser VM bis zur Wiederherstellung mit. Gegenmaßnahmen: Replikation/HA (Instanz wegswitchen) und Tenants nicht zu dicht pro VM packen. Echte Pro-Tenant-mariadbd-Instanzen würden selbst Engine-Crashes isolieren — vermutlich Overkill.

Empfohlene Resilienz-Maßnahmen

  • Funktionierende Replikation oder Galera — und überwachen. Die Alt-Infrastruktur hatte Replikation, die still ausfiel → kein Failover im Vorfall. Ein gesunder Replica/Cluster macht aus einer mehrstündigen Wiederherstellung ein Failover von Sekunden. Auf Replication-Lag/-Stopp alarmieren.
  • Physische Backups (Mariabackup), nicht nur logische Dumps. Die lange Wiederherstellungsdauer entstand, weil ein logischer Restore jede Zeile neu einfügt und alle Indizes neu aufbaut. Ein Mariabackup-Restore entspricht eher einer Dateikopie und ist bei großen Datenmengen dramatisch schneller. Beides vorhalten (physisch = schneller Full-Restore; logische Pro-Tenant-Dumps = Granularität/Portabilität) + Binlogs für PITR.
  • Frühe Erkennung / Alerting (Aufgabe der Monitoring-VM): MariaDB-Error-Log nach Loki schicken und auf InnoDB: … corrupt/Prüfsummenfehler alarmieren, damit es vor dem Crash-Loop auffällt. Periodisches mysqlcheck/CHECK TABLE (oder der nächtliche logische Dump, der jede Zeile liest) deckt Korruption proaktiv auf.
  • Redundantes Volume-Backend bei Dogado bestätigen (Ceph/SAN mit Replikation). Echte InnoDB-Korruption ist meist Storage-/Hardware-bedingt, kein DB-Versions-Bug — modernes redundantes Storage ist der größte einzelne Risikoreduzierer, mehr noch als MariaDB 11.8 selbst (das aber hilft: gepflegt, ~10 Jahre InnoDB-Fixes ggü. EOL 5.6/5.7).
11

Risiken & nächste Schritte

Offene Entscheidungen und Folgeaufgaben

⚠ Sicherheit / EOL

Alle zehn Server laufen auf abgekündigten Betriebssystemen (Debian 8/9, Ubuntu 16.04/18.04). Spitzenrisiko: Server 05 mit ~8,3 Jahren Uptime ohne Kernel-Patch. Das ist ein eigenständiger, kapazitätsunabhängiger Grund, die Migration nicht zu verzögern.

Offene Entscheidungen

  • Statistik-Aufbewahrung: komplette Historie vs. rollierendes Fenster — die größte verbleibende Stellschraube. Aktuelle Planungsempfehlung: alle Stats migrieren (siehe Abschnitt 08).
  • Keep/Drop je Tenant: die endgültige Entscheidung erfordert Kontakt mit jedem Kunden auf jeder Instanz (zurückgestellt; blockiert das Sizing nicht, da inaktive Tenants über Puffer aufgefangen werden).
  • Borderline-/inaktive Instanzen vor dem Verwerfen verifizieren: u. a. sf36, sf32/senddigital (07), sendlx_25/26 (03), sendlx_969 (12).
  • se2ifo/ifo: Custom-Migration mit dem ifo-Kunden abstimmen.

Nächste Schritte

  • Per-VM-Tenant-Packing-Plan finalisieren: 153 aktive Tenants (+ Puffer für inaktive) auf die neuen VMs verteilen, sobald die Ziel-VM-Spezifikation (Disk/RAM/Kerne) feststeht.
  • CPU-/RAM-Hotplug auf der öffentlichen OpenStack-Plattform mit Dogado klären (Default oft deaktiviert → Resize via Reboot).
  • Erste große Tenant-Migration als Validierungslauf (Cache-Hit-Rate, IO-Wait, CPU) vor Buchung der restlichen Knoten.
  • Buffer-Pool der App+DB-VMs auf ~70 % des RAM tunen (Pilot steht auf 128 MB Default).