Entwicklung & Code
LMDB 1.0: Datenbank ohne Server und ohne Write-Ahead-Log
Die freie Embedded-Datenbank LMDB (Lightning Memory-Mapped Database) hat Version 1.0 erreicht. Mit dem ersten Major-Release dokumentieren die Entwickler die API und das Verhalten der Bibliothek neu und stellen eine aktualisierte Dokumentation bereit. Für bestehende Anwendungen gibt es einen eigenen Migrationsleitfaden von der 0.9-Serie.
Weiterlesen nach der Anzeige
LMDB ist eine in Anwendungen eingebettete Key/Value-Datenbankbibliothek für lokale Datenhaltung. Sie richtet sich an Entwickler, die eine transaktionssichere Datenbank ohne separaten Serverprozess benötigen, etwa für Verzeichnisdienste, Caches oder Metadaten. Anders als klassische Datenbanksysteme lädt LMDB Daten nicht in einen eigenen Puffer-Cache, sondern bildet die komplette Datenbank per Memory Mapping in den virtuellen Adressraum des Prozesses ab. Lesezugriffe erfolgen dadurch direkt auf die gemappten Speicherbereiche, ohne zusätzliche Speicherallokationen oder Kopieroperationen.
Memory Mapping statt Datenbank-Cache
Das Grundprinzip von LMDB bleibt auch mit Version 1.0 unverändert. Die Bibliothek verwendet einen B-Baum als Datenstruktur und überlässt das Caching vollständig dem Betriebssystem. Da Datensätze direkt aus dem Speicherabbild gelesen werden, entfallen Zwischenschritte wie malloc() oder memcpy() beim Auslesen von Daten. Das reduziert den Verwaltungsaufwand und kann insbesondere bei leseintensiven Workloads die Leistung steigern. Grundlage dafür ist die Memory-Mapping-Funktion des Betriebssystems, bei der Dateiinhalte transparent in den virtuellen Speicher eingeblendet werden.
Auch das Transaktionsmodell bleibt erhalten. LMDB bietet ACID-Eigenschaften und setzt auf Multi-Version Concurrency Control (MVCC). Neue Daten werden per Copy-on-Write geschrieben, sodass bereits vorhandene Seiten niemals überschrieben werden. Ein Leser sieht dadurch stets einen konsistenten Datenbestand, während Schreibvorgänge parallel vorbereitet werden können. Ein typisches Beispiel ist ein Dienst, der kontinuierlich Konfigurationsdaten ausliest, während ein Verwaltungswerkzeug Änderungen schreibt: Leser arbeiten ohne Sperren weiter und werden durch den Schreibvorgang nicht blockiert.
Ein Schreiber, viele Leser
Das Nebenläufigkeitsmodell von LMDB unterscheidet sich von vielen anderen Datenbanken. Beliebig viele Prozesse oder Threads können gleichzeitig lesen, Schreibtransaktionen werden dagegen vollständig serialisiert. Zu jedem Zeitpunkt darf nur eine Schreibtransaktion aktiv sein. Dadurch schließt das System Deadlocks zwischen konkurrierenden Schreibern aus. Leser blockieren Schreiber nicht, ebenso wenig müssen Leser auf laufende Schreibvorgänge warten.
Die Entwickler verzichten außerdem bewusst auf ein Write-Ahead-Log oder ein Append-only-Protokoll. Statt regelmäßig Logdateien zusammenzuführen oder Datenbanken zu komprimieren, verwaltet LMDB freie Seiten innerhalb der Datenbank selbst und verwendet sie für spätere Schreibvorgänge erneut. Dadurch wächst die Datenbank im Normalbetrieb nicht unbegrenzt an, wie es bei logbasierten Verfahren ohne Wartung passieren kann.
Weiterlesen nach der Anzeige
Hinweise für den Betrieb
Die Release-Notes auf GitHub sowie die Dokumentation weisen auf einige Einschränkungen hin: Lange laufende Lesetransaktionen können verhindern, dass bereits freigegebene Seiten wiederverwendet werden. Dadurch kann die Datenbankdatei unnötig anwachsen. Entwickler sollten deshalb lang andauernde Transaktionen vermeiden und abgebrochene Prozesse regelmäßig auf verwaiste Reader-Einträge prüfen. Dafür stehen unter anderem die Funktion mdb_reader_check sowie das Werkzeug mdb_stat zur Verfügung.
Nicht empfohlen wird außerdem der Einsatz auf Netzwerkdateisystemen. Da LMDB auf Memory Mapping sowie Dateisperren des Betriebssystems setzt, können dort Synchronisationsprobleme auftreten. Auch das gleichzeitige mehrfache Öffnen derselben Datenbank innerhalb eines Prozesses gilt laut Dokumentation als problematisch.
(fo)