InnoDB Buffer Pool: Architektur und Sizing verstehen
AI generated
InnoDB
SQL
MySQL · InnoDB · Performance-Tuning
InnoDB Buffer Pool
Architektur und Sizing verstehen

Der InnoDB Buffer Pool entscheidet darüber, ob eine Abfrage aus dem Arbeitsspeicher in Mikrosekunden beantwortet wird oder eine langsame Festplattenoperation auslöst. Wer innodb_buffer_pool_size falsch dimensioniert oder die LRU-Liste nicht versteht, verschenkt Performance, die keine Indexoptimierung wieder aufholen kann. Dieser Artikel erklärt Aufbau, Sizing-Methodik und Monitoring des Buffer Pools mit echten SQL-Beispielen.

18 Min. Lesezeit innodb_buffer_pool_size · LRU-Liste · Hit Ratio MySQL 8.0 · MariaDB 10.x

1. Was der Buffer Pool wirklich leistet

Der InnoDB Buffer Pool ist der zentrale Cache-Bereich im Arbeitsspeicher, in dem InnoDB Tabellen- und Indexdaten in Form von Pages vorhält. Jede Leseoperation, jede Schreiboperation und jede Änderung an einer Zeile läuft zuerst über den Buffer Pool, bevor irgendetwas auf die Festplatte geschrieben wird. Ohne diesen Cache müsste jede Abfrage direkt gegen den Datenträger arbeiten, was bei rotierenden Festplatten und selbst bei NVMe-SSDs um Größenordnungen langsamer ist als ein Zugriff auf RAM. Der Buffer Pool ist damit keine Optimierung am Rand, sondern die Grundvoraussetzung dafür, dass eine relationale Datenbank überhaupt performant arbeiten kann.

In der Praxis zeigt sich der Effekt sofort: Eine Abfrage, deren benötigte Pages bereits im Buffer Pool liegen, wird typischerweise in unter einer Millisekunde beantwortet. Muss InnoDB dieselbe Page erst von der Platte laden, können mehrere Millisekunden vergehen, bei stark ausgelasteten Systemen mit vielen gleichzeitigen I/O-Operationen auch deutlich mehr. Bei einem typischen OLTP-Workload mit tausenden Abfragen pro Sekunde entscheidet die Trefferquote im Buffer Pool direkt darüber, ob ein Server die Last bewältigt oder in eine I/O-Warteschlange läuft. Die folgenden Abschnitte erklären, wie der Buffer Pool intern organisiert ist und wie man ihn für den eigenen Workload korrekt dimensioniert.

2. Aufbau: Pages, Frames und Buffer Pool Instances

Der Buffer Pool besteht aus einer festen Anzahl von Frames, die jeweils genau eine Page aufnehmen. Die Page-Größe wird über innodb_page_size festgelegt und beträgt standardmäßig 16 KB. Wird eine Page benötigt, die noch nicht im Speicher liegt, lädt InnoDB sie in einen freien oder verdrängten Frame. Intern verwaltet InnoDB dazu mehrere Strukturen gleichzeitig: eine Hash-Tabelle für den schnellen Zugriff auf bereits geladene Pages, die Flush-Liste für modifizierte, noch nicht auf die Platte geschriebene Pages, und die LRU-Liste, die entscheidet, welche Page bei Speicherdruck als erste verdrängt wird.

Damit der Buffer Pool bei vielen gleichzeitigen Threads nicht zum Flaschenhals wird, unterteilt InnoDB ihn in mehrere Instanzen, gesteuert über innodb_buffer_pool_instances. Jede Instanz verwaltet ihre eigenen Strukturen und ihr eigenes Mutex, wodurch Zugriffe aus unterschiedlichen Threads seltener kollidieren. Die Gesamtgröße des Buffer Pools wird gleichmäßig auf die Instanzen aufgeteilt, wobei jede Instanz mindestens 1 GB groß sein sollte, sonst reduziert MySQL die Anzahl der Instanzen automatisch. Der folgende Befehl zeigt die aktuelle Konfiguration und den belegten Speicher:


-- Current buffer pool configuration and memory usage
SHOW VARIABLES LIKE 'innodb_buffer_pool%';

-- Result excerpt:
-- innodb_buffer_pool_size        | 8589934592  (8 GB)
-- innodb_buffer_pool_instances   | 8
-- innodb_buffer_pool_chunk_size  | 134217728   (128 MB)

-- Per-instance statistics
SELECT
    POOL_ID,
    POOL_SIZE,
    FREE_BUFFERS,
    DATABASE_PAGES,
    OLD_DATABASE_PAGES
FROM information_schema.INNODB_BUFFER_POOL_STATS;

3. Die LRU-Liste: Young- und Old-Sublist im Detail

Die LRU-Liste im Buffer Pool funktioniert nicht wie ein klassisches Least-Recently-Used-Verfahren, weil ein naiver LRU-Algorithmus bei großen Scans katastrophal versagen würde. Ein einzelner SELECT ohne WHERE-Klausel über eine große Tabelle würde sonst den kompletten Buffer Pool mit Pages fluten, die nur einmal gelesen werden, und dabei den eigentlichen Arbeitsspeicher für häufig genutzte Daten verdrängen. InnoDB löst dieses Problem, indem die LRU-Liste in zwei Bereiche unterteilt wird: die Young-Sublist am Kopf der Liste für häufig genutzte Pages und die Old-Sublist für kürzlich geladene, noch nicht bewährte Pages.

Neu geladene Pages landen zunächst immer in der Old-Sublist, deren Größe standardmäßig 37 Prozent der Liste ausmacht, gesteuert über innodb_old_blocks_pct. Erst wenn eine Page innerhalb der Old-Sublist mindestens innodb_old_blocks_time Millisekunden lang erneut angefragt wird, wandert sie in die Young-Sublist. Dieser Zeitfilter verhindert, dass ein einmaliger Sequential Scan die Young-Sublist verunreinigt, denn eine Page, die im Rahmen eines Scans zweimal kurz hintereinander gelesen wird, gilt nicht als tatsächlich häufig genutzt. Für Analytics-Workloads mit vielen großen Scans lohnt es sich, innodb_old_blocks_time auf einen höheren Wert wie 1000 zu setzen, um das Verdrängen von Hot-Data noch konsequenter zu verhindern.


-- Inspect LRU configuration relevant to scan resistance
SHOW VARIABLES LIKE 'innodb_old_blocks%';

-- innodb_old_blocks_pct  | 37
-- innodb_old_blocks_time | 1000

-- Adjust for analytics-heavy workloads with frequent large scans
SET GLOBAL innodb_old_blocks_time = 1000;

-- Check how many pages currently sit in the old sublist
SELECT
    POOL_ID,
    DATABASE_PAGES,
    OLD_DATABASE_PAGES,
    ROUND(OLD_DATABASE_PAGES / DATABASE_PAGES * 100, 2) AS old_pct
FROM information_schema.INNODB_BUFFER_POOL_STATS;

4. innodb_buffer_pool_size richtig dimensionieren

Die Faustregel für innodb_buffer_pool_size lautet: so groß wie möglich, ohne das Betriebssystem in den Swap zu drängen. Auf einem dedizierten Datenbankserver werden häufig 60 bis 75 Prozent des verfügbaren RAM für den Buffer Pool reserviert, der Rest bleibt für Betriebssystem, Verbindungs-Threads, Sort-Buffer und andere InnoDB-Strukturen wie den Log Buffer. Diese Faustregel ist ein Startpunkt, keine exakte Formel, denn der tatsächliche Bedarf hängt von der Größe des Working Sets ab, also der Datenmenge, die aktiv gelesen und geschrieben wird.

Eine präzisere Methode ist, die Größe der tatsächlich genutzten InnoDB-Daten zu ermitteln und den Buffer Pool so zu dimensionieren, dass dieses Working Set komplett hineinpasst. Ist der gesamte Datenbestand deutlich größer als der verfügbare RAM, etwa bei einem Datenwarenhaus mit mehreren Terabyte, lohnt sich stattdessen eine Analyse der tatsächlichen Zugriffsmuster, um nur die heißen Tabellen im Buffer Pool zu halten. Auf virtualisierten Systemen mit begrenztem RAM, wie sie bei kleineren Magento-Installationen häufig vorkommen, ist die realistische Working-Set-Größe oft kleiner als vermutet, weil nur ein Bruchteil des Katalogs tatsächlich häufig abgefragt wird.


# /etc/mysql/conf.d/innodb-buffer-pool.cnf
[mysqld]
# Rule of thumb: 60-75% of total RAM on a dedicated DB server
innodb_buffer_pool_size = 12G
innodb_buffer_pool_instances = 8
innodb_buffer_pool_chunk_size = 134217728

# Determine current InnoDB data + index size with SQL:
# SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 2) AS gb
# FROM information_schema.tables WHERE engine = 'InnoDB';

5. Buffer Pool Instances: wann mehrere sinnvoll sind

Mehrere Buffer Pool Instances reduzieren Contention auf die internen Mutexe, bringen aber nur bei ausreichend großem Buffer Pool einen messbaren Vorteil. Bei einer Gesamtgröße unter 1 GB ignoriert MySQL die Einstellung innodb_buffer_pool_instances ohnehin und arbeitet mit nur einer Instanz, weil eine Aufteilung in mehrere Kleinstinstanzen keinen Sinn ergäbe. Erst ab mehreren Gigabyte Gesamtgröße und einer hohen Anzahl gleichzeitiger Verbindungen zeigt sich der Effekt der Parallelisierung deutlich, typischerweise bei Systemen mit mehr als 16 CPU-Kernen und entsprechend vielen parallelen Threads.

Ein häufiger Fehler ist, die Anzahl der Instanzen unabhängig von der Buffer-Pool-Größe zu maximieren. Da jede Instanz mindestens 1 GB groß sein muss, führt eine zu hohe Instanzenzahl bei moderatem RAM dazu, dass MySQL die Konfiguration automatisch reduziert und eine Warnung ins Error-Log schreibt. Als praktikable Regel gilt: Bei einem Buffer Pool unter 8 GB reichen 4 Instanzen, darüber sind 8 Instanzen ein solider Standardwert, der sich in den meisten Produktionsumgebungen bewährt hat.

6. Warm-up nach Neustart: Dump und Load

Nach einem Neustart ist der Buffer Pool vollständig leer, und jede Abfrage muss ihre Pages zunächst von der Platte laden, bis sich der Cache erneut mit den relevanten Daten gefüllt hat. Diese Aufwärmphase kann bei großen Datenbanken mehrere Minuten bis Stunden dauern, in denen die Antwortzeiten spürbar höher liegen als im eingeschwungenen Zustand. InnoDB bietet dafür einen eingebauten Mechanismus: Vor dem Herunterfahren wird mit innodb_buffer_pool_dump_at_shutdown eine kompakte Liste der aktuell im Buffer Pool geladenen Pages auf die Platte geschrieben, nicht die Pages selbst, sondern nur die Information, welche Pages es waren.

Beim nächsten Start liest InnoDB mit innodb_buffer_pool_load_at_startup diese Liste und lädt die entsprechenden Pages proaktiv nach, parallel zum normalen Betrieb. Dadurch erreicht der Server die produktive Trefferquote im Buffer Pool deutlich schneller, ohne auf organisches Aufwärmen durch echten Traffic warten zu müssen. Beide Optionen sind in modernen MySQL-Versionen standardmäßig aktiviert, sollten aber nach jedem Upgrade und in jeder eigenen Konfiguration explizit überprüft werden.


# /etc/mysql/conf.d/innodb-warmup.cnf
[mysqld]
innodb_buffer_pool_dump_at_shutdown = ON
innodb_buffer_pool_load_at_startup = ON
innodb_buffer_pool_dump_pct = 50

7. Monitoring: Hit Ratio und Performance Schema

Die Trefferquote im Buffer Pool, häufig als Hit Ratio bezeichnet, ist die wichtigste Kennzahl, um zu beurteilen, ob die aktuelle Größe ausreicht. Eine gesunde Produktionsumgebung erreicht typischerweise eine Hit Ratio von 99 Prozent oder mehr. Fällt der Wert merklich darunter, etwa nach dem Import großer Datenmengen oder bei wachsendem Datenbestand, ist das ein klares Signal dafür, dass der Buffer Pool vergrößert werden sollte oder dass eine ungewöhnliche Abfrage gerade große Datenmengen durch den Cache spült.

Die Berechnung erfolgt aus den globalen Statusvariablen Innodb_buffer_pool_read_requests für logische Leseanfragen und Innodb_buffer_pool_reads für tatsächliche physische Festplattenzugriffe. Ergänzend liefert das Performance Schema detailliertere Einblicke, etwa welche Tabellen und Indizes den meisten Speicher im Buffer Pool belegen, was bei der Priorisierung von Optimierungsmaßnahmen hilft.


-- Calculate buffer pool hit ratio from global status
SELECT
    ROUND(
      (1 - (
        (SELECT VARIABLE_VALUE FROM performance_schema.global_status
         WHERE VARIABLE_NAME = 'Innodb_buffer_pool_reads') /
        (SELECT VARIABLE_VALUE FROM performance_schema.global_status
         WHERE VARIABLE_NAME = 'Innodb_buffer_pool_read_requests')
      )) * 100, 4
    ) AS hit_ratio_pct;

-- Which tables occupy the most buffer pool memory
SELECT
    object_schema,
    object_name,
    COUNT(*) AS pages,
    ROUND(COUNT(*) * 16384 / 1024 / 1024, 2) AS mb
FROM performance_schema.innodb_buffer_page
WHERE object_schema NOT IN ('mysql', 'information_schema')
GROUP BY object_schema, object_name
ORDER BY pages DESC
LIMIT 10;

8. Typische Fehlkonfigurationen und ihre Symptome

Der häufigste Fehler beim Buffer Pool ist eine zu kleine Größe relativ zum Working Set. Das Symptom zeigt sich meist zuerst in der I/O-Auslastung: Der Server produziert konstant hohe Werte bei physischen Lesezugriffen, obwohl die Anwendung dieselben Daten immer wieder abfragt. Ein zweiter verbreiteter Fehler ist ein zu groß dimensionierter Buffer Pool auf einem System mit wenig RAM, wodurch das Betriebssystem beginnt zu swappen. Swapping ist für eine Datenbank besonders schädlich, weil es die eigentlich gewollte Beschleunigung durch den Cache komplett zunichtemacht und stattdessen noch langsamere Zugriffsmuster erzeugt als ohne Cache.

Ein dritter, subtilerer Fehler betrifft die Instanzenzahl in Kombination mit vielen kleinen Tabellen: Ist innodb_buffer_pool_instances deutlich höher gesetzt als sinnvoll, verteilt sich der ohnehin knappe Speicher zu dünn auf zu viele Instanzen, was die Trefferwahrscheinlichkeit pro Instanz senkt. Wer diese Symptome erkennt, sollte zuerst die Hit Ratio prüfen, dann die tatsächliche Working-Set-Größe ermitteln und erst danach die Konfiguration schrittweise anpassen, statt reflexartig den Wert zu verdoppeln.

9. Sizing-Strategien im Vergleich

Es gibt nicht die eine richtige Größe für den Buffer Pool, sondern unterschiedliche Strategien je nach Workload-Typ und verfügbarem Speicher. Die folgende Tabelle stellt die gängigen Ansätze gegenüber und zeigt, wann welche Strategie sinnvoll ist.

Szenario Strategie Typische Größe Risiko bei Fehlkonfiguration
Dedizierter DB-Server 60 bis 75 Prozent des RAM Mehrere GB bis TB Swap bei Überdimensionierung
Shared Server mit App 30 bis 40 Prozent des RAM 1 bis 4 GB Zu klein für Working Set
Datenwarenhaus, TB-Bestand Working-Set-basiert, nicht Vollbestand 10 bis 50 Prozent des Datenbestands Hit Ratio dauerhaft niedrig
Kleine Cloud-Instanz Konservativ, mit Reserve für OS 512 MB bis 2 GB OOM-Killer bei zu knapper Reserve

Unabhängig vom Szenario gilt: Die Größe des Buffer Pools sollte nach jeder signifikanten Änderung des Datenbestands neu bewertet werden. Ein Onlineshop, dessen Katalog innerhalb eines Jahres von 10.000 auf 100.000 Produkte wächst, braucht mit hoher Wahrscheinlichkeit auch einen größeren Buffer Pool, um dieselbe Hit Ratio zu halten.

Mironsoft

MySQL-Performance-Tuning und Datenbankberatung

Buffer Pool und InnoDB-Konfiguration auf den Prüfstand?

Wir analysieren eure InnoDB-Konfiguration, ermitteln die reale Working-Set-Größe und passen Buffer Pool, Log-Dateien und weitere Parameter an euren tatsächlichen Workload an.

Performance-Audit

Hit Ratio, I/O-Muster und Working Set systematisch analysieren

Sizing-Beratung

Buffer Pool und weitere InnoDB-Parameter datenbasiert dimensionieren

Monitoring-Setup

Dashboards für Hit Ratio und Buffer-Pool-Auslastung aufbauen

10. Zusammenfassung

Der InnoDB Buffer Pool ist der wichtigste einzelne Konfigurationsparameter für die Performance einer MySQL-Datenbank. Er hält Tabellen- und Indexdaten im RAM vor, organisiert Zugriffe über eine scan-resistente LRU-Liste mit Young- und Old-Sublist und lässt sich über mehrere Instanzen parallelisieren, um Contention bei hoher Last zu reduzieren. Die richtige Größe für innodb_buffer_pool_size ergibt sich aus der Working-Set-Größe des eigenen Workloads, nicht aus einer pauschalen Prozentzahl allein.

Monitoring über die Hit Ratio und das Performance Schema zeigt frühzeitig, wann der Buffer Pool an seine Grenzen stößt. In Kombination mit Dump und Load beim Neustart bleibt die Trefferquote auch nach Wartungsfenstern stabil, ohne dass der Server jedes Mal eine lange Aufwärmphase durchlaufen muss. Wer diese Mechanismen versteht, kann die Performance einer MySQL-Installation oft deutlicher verbessern als durch reine Index- oder Query-Optimierung.

InnoDB Buffer Pool: Architektur und Sizing, das Wichtigste auf einen Blick

Sizing-Grundregel

60 bis 75 Prozent des RAM auf dedizierten Servern, aber immer an der realen Working-Set-Größe ausrichten.

LRU-Liste

Young- und Old-Sublist schützen den Buffer Pool vor Verdrängung durch einmalige Sequential Scans.

Monitoring

Hit Ratio aus Innodb_buffer_pool_reads und read_requests berechnen, Zielwert 99 Prozent oder höher.

Warm-up

innodb_buffer_pool_dump_at_shutdown und load_at_startup verkürzen die Aufwärmphase nach Neustarts.

11. FAQ: InnoDB Buffer Pool

1Was ist der InnoDB Buffer Pool?
Der Cache-Bereich im RAM, in dem InnoDB Tabellen- und Indexdaten als Pages vorhält, damit Zugriffe nicht bei jeder Anfrage die Festplatte erreichen müssen.
2Wie groß sollte innodb_buffer_pool_size sein?
60 bis 75 Prozent des RAM auf dedizierten Servern, orientiert an der realen Working-Set-Größe. Zu groß führt zu Swapping, zu klein zu niedriger Hit Ratio.
3Young- vs. Old-Sublist?
Neue Pages landen in der Old-Sublist. Erst nach erneuter Anfrage innerhalb der Zeitschwelle wandern sie in die Young-Sublist. Schützt vor Verdrängung durch Scans.
4Hit Ratio berechnen?
1 minus (Innodb_buffer_pool_reads / read_requests), mal 100. Zielwert 99 Prozent oder mehr in einer gesunden Produktionsumgebung.
5Wann mehrere Instances?
Ab mehreren GB Gesamtgröße und vielen gleichzeitigen Verbindungen. Unter 1 GB ignoriert MySQL die Einstellung ohnehin.
6Was bewirken Dump und Load?
Speichern beim Shutdown, welche Pages geladen waren, und laden sie beim Start proaktiv nach. Verkürzt die Aufwärmphase deutlich.
7Warum sinkt Hit Ratio nach Import?
Neue Pages verdrängen gecachte Daten. Die scan-resistente LRU-Liste mildert den Effekt, verhindert ihn aber nicht vollständig bei sehr großen Importen.
8Kann Buffer Pool zu groß sein?
Ja, bei Speicherdruck beginnt das Betriebssystem zu swappen, was die Datenbank deutlich langsamer macht als ohne großzügigen Cache.
9Working Set ermitteln?
Abfrage gegen information_schema.tables, Summe aus data_length und index_length für InnoDB-Tabellen als grobe Obergrenze.
10innodb_old_blocks_time bei Analytics?
Höherer Wert wie 1000 Millisekunden schützt Hot-Data vor Verdrängung durch große einmalige Scans in gemischten Workloads.