praktisch einsetzen statt nur in der Doku zu lesen
InnoDB kann Tabellen seitenweise komprimieren, ohne dass die Anwendung davon etwas mitbekommt. Der Mechanismus dahinter, die Wahl der richtigen KEY_BLOCK_SIZE und der Trade-off zwischen Speicherplatzersparnis und zusätzlichem CPU-Overhead entscheiden aber darüber, ob sich ROW_FORMAT=COMPRESSED für eine konkrete Tabelle wirklich lohnt. Für Magento-Installationen mit umfangreichen Log- und Archivtabellen kann die Kompression spürbar Plattenplatz und Cache-Druck reduzieren, für heiß beschriebene Kerntabellen kann sie dagegen zur Bremse werden.
Inhaltsverzeichnis
- 1. Warum Tabellenkompression in InnoDB überhaupt ein Thema ist
- 2. Wie InnoDB-Seitenkompression technisch funktioniert
- 3. KEY_BLOCK_SIZE wählen: 1, 2, 4 oder 8 Kilobyte
- 4. CPU-Overhead: was bei jedem Seitenzugriff zusätzlich passiert
- 5. Der Trade-off: Speicherplatzersparnis gegen CPU- und Cache-Verbrauch
- 6. Praxisbeispiel Magento: welche Tabellen sich als Kandidaten eignen
- 7. Alternative: Transparent Page Compression über Punch Hole
- 8. Monitoring und Diagnose: Kompressionsstatistiken richtig lesen
- 9. Praktische Einführung: Vorgehen, Tests und Rollback-Strategie
- 10. Zusammenfassung
- 11. FAQ
1. Warum Tabellenkompression in InnoDB überhaupt ein Thema ist
InnoDB organisiert Daten in Seiten von standardmäßig 16 Kilobyte, die als Einheit zwischen Platte und Buffer Pool bewegt werden. Bei Tabellen mit sehr vielen Zeilen, etwa Protokoll-, Log- oder Archivtabellen, summiert sich die reine Seitenzahl schnell zu erheblichem Speicherplatzverbrauch, selbst wenn die einzelnen Werte pro Zeile klein und stark redundant sind, etwa bei Statusfeldern, wiederkehrenden IDs oder Zeitstempeln in engem Wertebereich.
ROW_FORMAT=COMPRESSED setzt genau hier an: Die physische Seite auf der Platte wird kleiner als 16 Kilobyte gespeichert, indem InnoDB den Seiteninhalt vor dem Schreiben komprimiert. Das reduziert nicht nur den Plattenplatz, sondern bei entsprechender Konfiguration auch die Menge an Daten, die für dieselbe Seitenzahl durch den Buffer Pool und über das Netzwerk zu Replikaten bewegt werden muss.
2. Wie InnoDB-Seitenkompression technisch funktioniert
Beim Anlegen einer Tabelle mit ROW_FORMAT=COMPRESSED und einer gewählten KEY_BLOCK_SIZE komprimiert InnoDB jede 16-Kilobyte-Seite mit zlib, bevor sie auf die Platte geschrieben wird, und speichert das Ergebnis in einem Block der gewählten Zielgröße. Beim Lesen wird die komprimierte Seite von der Platte geladen und im Buffer Pool wieder dekomprimiert, wobei InnoDB zusätzlich zur dekomprimierten Arbeitskopie häufig auch die komprimierte Version im Speicher vorhält, um wiederholtes Dekomprimieren bei erneutem Evict und Reload zu vermeiden.
Wird eine bereits komprimierte Seite durch ein Update so verändert, dass sie nicht mehr in den gewählten Zielblock passt, muss InnoDB die Seite reorganisieren und erneut komprimieren, was zusätzliche CPU-Zeit kostet. Genau dieser Reorganisationsaufwand ist der zentrale Hebel, an dem die Wahl der KEY_BLOCK_SIZE später ansetzt.
-- Tabelle mit Seitenkompression anlegen
CREATE TABLE report_event_archive (
event_id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
event_type SMALLINT UNSIGNED NOT NULL,
object_id INT UNSIGNED NOT NULL,
logged_at DATETIME NOT NULL,
KEY idx_logged (logged_at)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
3. KEY_BLOCK_SIZE wählen: 1, 2, 4 oder 8 Kilobyte
KEY_BLOCK_SIZE gibt die Zielgröße der komprimierten Seite in Kilobyte an und akzeptiert die Werte 1, 2, 4 oder 8, jeweils bezogen auf die unkomprimierte Ausgangsgröße von 16 Kilobyte. Eine kleinere Zielgröße erzwingt eine stärkere Kompression und spart mehr Platz, erhöht aber gleichzeitig das Risiko, dass ein Update den Zielblock sprengt und eine teure Reorganisation samt erneuter Komprimierung auslöst.
In der Praxis bewährt sich ein iteratives Vorgehen: Man startet mit einem moderaten Wert wie 8 Kilobyte, misst das tatsächliche Kompressionsverhältnis unter realistischer Last und reduziert die Zielgröße nur dann weiter, wenn die Reorganisationsrate klein bleibt. Für Zeilen mit stark variabler Länge, etwa Texten unterschiedlicher Größe, ist ein zu aggressiver Wert besonders riskant.
4. CPU-Overhead: was bei jedem Seitenzugriff zusätzlich passiert
Jeder Lesezugriff auf eine Seite, die nicht bereits dekomprimiert im Buffer Pool liegt, kostet zusätzliche CPU-Zeit für die Dekompression, und jeder Schreibzugriff, der eine Seite verändert, kostet CPU-Zeit für die erneute Komprimierung. Bei stark frequentierten, gleichzeitig vielfach parallel beschriebenen Tabellen kann dieser Overhead unter Last spürbar werden, besonders wenn viele CPU-Kerne bereits durch andere Abfragen ausgelastet sind. Auf Systemen mit knapp bemessener CPU-Kapazität, etwa kleineren virtuellen Maschinen mit wenigen Kernen, summiert sich dieser Zusatzaufwand schneller zu einem echten Engpass als auf großzügig dimensionierten Datenbankservern mit reichlich freier Rechenleistung.
Zusätzlich beansprucht InnoDB mehr Buffer-Pool-Speicher als bei unkomprimierten Tabellen, weil komprimierte und dekomprimierte Kopien einer aktiven Seite parallel vorgehalten werden können. Ist der Buffer Pool ohnehin knapp bemessen, kann Kompression den effektiv nutzbaren Cache für andere Tabellen sogar verkleinern, statt Speicherdruck zu lindern.
5. Der Trade-off: Speicherplatzersparnis gegen CPU- und Cache-Verbrauch
Kompression lohnt sich vor allem bei I/O-gebundenen Workloads, bei denen die Plattenzugriffszeit oder das Netzwerk zu Replikaten der eigentliche Engpass ist, während CPU-Kapazität reichlich vorhanden ist. Typische Beispiele sind selten geschriebene, aber gelegentlich vollständig gescannte Reporting- oder Archivtabellen, bei denen weniger Seiten auf der Platte direkt weniger Lesezeit bedeuten.
Bei CPU-gebundenen, stark parallel beschriebenen Workloads mit knapper Rechenleistung kehrt sich der Trade-off dagegen um: Der zusätzliche Dekompressions- und Reorganisationsaufwand kann die Antwortzeiten verschlechtern, obwohl weniger Bytes auf der Platte liegen. Eine pauschale Entscheidung ohne Messung unter realistischer Last ist deshalb riskant.
6. Praxisbeispiel Magento: welche Tabellen sich als Kandidaten eignen
In Magento-Installationen kommen als Kandidaten vor allem Tabellen infrage, die selten aktualisiert, aber gelegentlich in größerem Umfang gelesen werden: Ereignisprotokolle wie report_event, historische Preisindex-Archive, Kundenaktivitätslogs oder Admin-Aktionsprotokolle. Diese Tabellen wachsen kontinuierlich, werden aber überwiegend nur angehängt und selten nachträglich verändert, sodass das Risiko teurer Reorganisationen gering bleibt.
Von einer Kompression heiß beschriebener Tabellen wie quote_item, sales_order_grid oder der Kernindextabellen des Katalogs ist dagegen eher abzuraten, weil dort ständige, oft zeilenverändernde Schreibzugriffe genau das Reorganisationsrisiko erhöhen, das die Kompression teuer macht.
7. Alternative: Transparent Page Compression über Punch Hole
Neben der klassischen ROW_FORMAT=COMPRESSED-Kompression bietet InnoDB mit der Transparent Page Compression einen zweiten Ansatz: Seiten bleiben im Buffer Pool unkomprimiert, werden aber beim Schreiben auf die Platte über Filesystem-Hole-Punching verkleinert, sofern das darunterliegende Dateisystem, etwa ext4 oder XFS, dies unterstützt. Der Buffer Pool profitiert dabei nicht von reduziertem Speicherbedarf, weil dort weiterhin die volle, unkomprimierte Seite liegt.
Diese Variante eignet sich vor allem, wenn ausschließlich der Plattenplatz das Problem ist, CPU-Overhead im Buffer Pool aber vermieden werden soll, ist jedoch stärker vom eingesetzten Dateisystem und Betriebssystem abhängig als die klassische, überall verfügbare KEY_BLOCK_SIZE-Kompression.
8. Monitoring und Diagnose: Kompressionsstatistiken richtig lesen
InnoDB liefert über INFORMATION_SCHEMA.INNODB_CMP und INNODB_CMP_RESET aggregierte Statistiken zu Kompressionsversuchen: COMPRESS_OPS zählt alle Kompressionsversuche, COMPRESS_OPS_OK die davon erfolgreichen, bei denen die Seite ohne Reorganisation in den Zielblock passte. Liegt das Verhältnis von OK zu Gesamtversuchen deutlich unter eins, deutet das auf eine zu aggressiv gewählte KEY_BLOCK_SIZE für das tatsächliche Datenmuster hin.
Zusätzlich liefern COMPRESS_TIME und UNCOMPRESS_TIME die kumulierte CPU-Zeit für Kompression und Dekompression, was sich direkt mit dem gemessenen Speicherplatzgewinn gegenrechnen lässt, um eine fundierte Entscheidung statt einer reinen Bauchentscheidung zu treffen.
-- Kompressionsstatistik je Tabellenraum auswerten
SELECT page_size, compress_ops, compress_ops_ok,
ROUND(compress_ops_ok / NULLIF(compress_ops, 0), 3) AS success_ratio,
compress_time, uncompress_time
FROM information_schema.innodb_cmp;
-- Zaehler nach der Messung zuruecksetzen
SELECT * FROM information_schema.innodb_cmp_reset;
9. Praktische Einführung: Vorgehen, Tests und Rollback-Strategie
Die Umstellung einer bestehenden Tabelle erfolgt über ALTER TABLE ... ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=n und läuft als Online-DDL-Operation, benötigt bei großen Tabellen aber entsprechend Zeit und I/O-Kapazität. Vor der produktiven Umstellung empfiehlt sich ein Testlauf auf einer Kopie mit realistischem Datenvolumen, bei dem sowohl Speicherplatzersparnis als auch Antwortzeiten unter Last gemessen werden.
Sollte sich die Kompression als nachteilig erweisen, lässt sie sich jederzeit mit ALTER TABLE ... ROW_FORMAT=DYNAMIC wieder rückgängig machen. Diese Reversibilität macht Kompression zu einem risikoarmen Experiment, solange man Messwerte vor und nach der Umstellung sauber dokumentiert.
-- Bestehende Tabelle testweise komprimieren
ALTER TABLE report_event_archive
ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4, ALGORITHM=INPLACE, LOCK=NONE;
-- Rollback bei negativem Messergebnis
ALTER TABLE report_event_archive ROW_FORMAT=DYNAMIC;
| KEY_BLOCK_SIZE | Kompressionsgrad | Reorganisationsrisiko | Typischer Einsatz |
|---|---|---|---|
| 8 KB | Moderat, ca. 50 % der Originalgröße | Gering | Erster, sicherer Einstiegspunkt für Tests |
| 4 KB | Deutlich, ca. 25 % der Originalgröße | Mittel | Log- und Archivtabellen mit stabilem Zeilenmuster |
| 2 KB | Hoch, unter 20 % der Originalgröße | Hoch | Sehr kleine, stark redundante Zeilen ohne Updates |
| 1 KB | Sehr hoch, aber selten praktikabel | Sehr hoch | Nur bei minimalen, festen Zeilengrößen sinnvoll |
Mironsoft
Datenbank-Performance, Index-Tuning und Magento-DB-Optimierung
Magento-Shop, der an langsamen Datenbankabfragen leidet?
Wir analysieren MySQL-Datenbanken auf Performance-Bremsen, optimieren Indizes und Abfragen gezielt und richten Backup- und Replikationsstrategien ein, die im Ernstfall wirklich funktionieren.
Performance-Audit
Slow Query Log und Explain-Pläne systematisch auf Engpässe untersuchen.
Index-Optimierung
Indizes gezielt für die tatsächliche Abfragelast des Shops aufbauen.
Backup-Strategie
Zuverlässige Backup- und Restore-Prozesse für produktive Magento-Datenbanken einrichten.
10. Zusammenfassung
ROW_FORMAT=COMPRESSED: Das Wichtigste auf einen Blick
Funktionsprinzip
InnoDB komprimiert 16-Kilobyte-Seiten mit zlib vor dem Schreiben und dekomprimiert sie beim Lesen wieder in den Buffer Pool.
KEY_BLOCK_SIZE
Steuert die Zielgröße der komprimierten Seite (1, 2, 4 oder 8 Kilobyte). Kleinere Werte sparen mehr Platz, erhöhen aber das Reorganisationsrisiko bei Updates.
Trade-off
Lohnt sich bei I/O-gebundenen, selten geänderten Tabellen. Bei CPU-gebundenen, heiß beschriebenen Tabellen kann Kompression Antwortzeiten verschlechtern.
Magento-Kandidaten
Ereignisprotokolle und Archivtabellen wie report_event eignen sich gut, transaktionale Kerntabellen mit häufigen Updates eher nicht.