Lightning Memory-Mapped Database: Difference between revisions

Content deleted Content added
Performance: Correct capitalization of GitHub
 
(39 intermediate revisions by 34 users not shown)
Line 1:
{{Short description|Software library providing an embedded transactional key-value database}}
{{Advert|date=July 2018}}
{{Infobox software
| name = OpenLDAP Lightning Memory-Mapped Database
Line 16:
}}
{{Portal|Free and open-source software}}
'''Lightning Memory-Mapped Database''' ('''LMDB''') is a [[software library]] that provides a high-performancean embedded transactional [[database]] in the form of a [[key-value store]]. LMDB is written in [[C (programming language)|C]] with [[#API and uses|API bindings]] for several [[programming language]]s. LMDB stores arbitrary key/data pairs as byte arrays, has a range-based search capability, supports multiple data items for a single key and has a special mode for appending records at the end of the database (MDB_APPEND) whichwithout giveschecking afor dramatic write performance increase over other similar storesconsistency.<ref name="auto">[http://symaswww.com/mdblmdb.tech/doc/group__internal.html LMDB Reference Guide] {{Webarchive|url=https://web.archive.org/web/20141020182433/http://symas.com/mdb/doc/group__internal.html |date=2014-10-20 }}. Retrieved on 20142023-1003-1921</ref> LMDB is not a [[relational database]], it is strictly a key-value store like [[Berkeley DB]] and [[DBM (computing)|dbmDBM]].
 
LMDB may also be used [[#Concurrency|concurrently]] in a multi-threaded or multi-processing environment, with read performance scaling linearly by design. LMDB databases may have only one writer at a time, however unlike many similar key-value databases, write transactions do ''not'' block readers, nor do readers block writers. LMDB is also unusual in that multiple applications on the same system may simultaneously open and use the same LMDB store, as a means to scale up performance. Also, LMDB does not require a transaction log (thereby increasing write performance by not needing to write data twice) because it maintains data integrity inherently by design.
Line 28:
 
== Technical description ==
Internally LMDB uses [[B+ tree]] data structures. The efficiency of its design and small footprint had the unintended side-effect of providing good write [[#Performance|performance]] as well. LMDB has an [[Application programming interface|API]] similar to [[Berkeley DB]] and [[DBM (computing)|dbm]]. LMDB treats the computer's memory as a single address space, shared across multiple processes or threads using [[Shared memory (interprocess communication)|shared memory]] with [[copy-on-write]] semantics (known historically as a [[single-level store]]). Due to mostMost former modern computing architectures havinghad a 32-bit memory address space limitations, which imposesimposing a hard limit of 4&nbsp; GB on the size of any database using such techniques, the effectiveness of the technique ofthat directly mapping a databasemapped into a [[single-level store]] was strictly limited. However, today's 64-bit processors now mostly implement 48-bit address spaces, giving access to 47-bit addresses or 128 terabytes&nbsp;TB of database size,<ref>{{cite conference | url=http://ldapcon.org/2011/downloads/chu-paper.pdf | title=MDB: A Memory-Mapped Database and Backend for OpenLDAP | last=Chu | first=Howard | conference=LDAPCon | conference-url=http://ldapcon.org/2011/ | year=2011}}.</ref> making databases using shared memory useful once again in real-world applications.
 
Specific noteworthy technical features of LMDB are:
 
* Its use of [[B+ tree]]. With an LMDB instance being in shared memory and the [[B+ tree]] block size being set to the OS page size, access to an LMDB store is extremely memory efficient.<ref>[[B+ tree#Implementation]]</ref>
* New data is written without overwriting or moving existing data. This results in guaranteedguarantees data integrity and [[#Reliability|reliability]] without requiring transaction logs or cleanup services.
* The provision of a unique append-write mode (MDB_APPEND)<ref name="auto"/> which is implemented by allowing the new record to be added directly to the end of the [[B+ tree]]. This reduces the number of reads and writewrites page operations, resulting in greatly-increased performance but requiring that the programmer is responsible forto ensuringensure keys are already in sorted order when storing intoin the DB.
* [[Copy-on-write]] semantics help ensure [[#Reliability|data integrity]] as well as providing transactional guarantees and simultaneous access by readers without requiring any locking, even by the current writer. New memory pages required internally during data modifications are allocated through copy-on-write semantics by the underlying OS: the LMDB library itself never actually modifies older data being accessed by readers because it simply cannot do so: any shared-memory updates ''automatically'' create a completely independent copy of the memory-page being written to.
* As LMDB is memory-mapped, it can return ''direct'' pointers to memory addresses of keys and values through its API, thereby avoiding unnecessary and expensive copying of memory. This results in greatly-increased performance (especially when the values stored are extremely large), and expands the potential use cases for LMDB.
* LMDB also tracks unused memory pages, using a [[B+ tree]] to keep track of pages freed (no longer needed) during transactions. By tracking unused pages, the need for garbage- collection (and a garbage collection phase whichthat would consume CPU cycles) is completely avoided. Transactions whichthat need new pages are first given pages from this unused free pages tree; only after these are used up will it expand into formerly unused areas of the underlying memory-mapped file. On a modern filesystem with [[sparse file]] support, this helps minimise actual disk usage.
 
The file format of LMDB is, unlike that of [[Berkeley DB]], architecture-dependent. This means that a conversion must be done before moving a database from a 32-bit machine to a 64-bit machine,<ref>{{cite web |title=The LMDB file format |url=https://blog.separateconcerns.com/2016-04-03-lmdb-format.html |website=Separate Concern |accessdate=27 February 2020}}</ref> or between computers of differing [[endianness]].<ref>{{cite web |last1=Chu |first1=Howard |title=lmdb - Is the Monero blockchain database portable between 32 and 64 bit architectures, and little/big endian architectures? |url=https://monero.stackexchange.com/a/4526 |website=Monero Stack Exchange}}</ref>
 
=== Concurrency ===
LMDB employs [[multiversion concurrency control]] (MVCC) and allows multiple threads within multiple processes to coordinate simultaneous access to a database. Readers scale linearly by design.<ref>[http://www.lmdb.tech/bench/inmem/scaling.html scaling benchmarks for LMDB]</ref><ref>[http://www.lmdb.tech/bench/inmem/scale2/ in-memory benchmark scaling for LMDB]</ref> While write transactions are globally serialized via a [[mutex]], read-only transactions operate in parallel, including in the presence of a write transaction. They are entirely [[wait free]] except for the first read-only transaction on a thread. Each thread reading from a database gains ownership of an element in a shared memory array, which it may update to indicate when it is within a transaction. Writers scan the array to determine the oldest database version the transaction must preserve without requiring direct synchronization with active readers.
. While write transactions are globally serialized via a [[mutex]], read-only transactions operate in parallel, including in the presence of a write transaction, and are entirely [[wait free]] except for the first read-only transaction on a thread. Each thread reading from a database gains ownership of an element in a shared memory array, which it may update to indicate when it is within a transaction. Writers scan the array to determine the oldest database version the transaction must preserve, without requiring direct synchronization with active readers.
 
== Performance ==
In 2011, Google published software whichthat allowed users to generate micro-benchmarks comparing [[LevelDB]]'s performance to [[SQLite]] and [[Kyoto Cabinet]] in different scenarios.<ref>{{cite web|title=LevelDB Benchmarks|url=http://leveldb.googlecode.com/svn/trunk/doc/benchmark.html|publisher=Google, Inc.|accessdate=8 August 2014|archive-url=https://web.archive.org/web/20110820001028/http://leveldb.googlecode.com/svn/trunk/doc/benchmark.html|archive-date=20 August 2011|url-status=dead}}</ref> In 2012, Symas added support for LMDB and Berkeley DB and made the updated benchmarking software publicly available.<ref>{{cite web|last1=Chu |first1=Howard |title=Database Microbenchmarks |url=http://symaswww.comlmdb.tech/mdbbench/microbench/ |publisher=Symas Corp. |accessdate=8 August 2014 |url-status=deadlive |archive-url=https://web.archive.org/web/20140809204443/http://symas.com/mdb/microbench/ |archive-date= 9 August 2014 }}</ref> The resulting benchmarks showed that LMDB outperformed all other databases in read and batch write operations. SQLite with LMDB excelled onin write operations, and particularly so on synchronous/transactional writes.
 
The benchmarks showed the underlying filesystem as having a big influence on performance. [[JFS (file system)|JFS]] with an external journal performs well, especially compared to other modern systems like [[Btrfs]] and [[ZFS]].<ref>{{cite web | url=http://lmdb.tech/bench/microbench/|title=MDB Microbenchmarks|publisher=Symas Corp.}}, 2012-09</ref><ref>[http://lmdb.tech/bench/microbench/july/ Database Microbenchmarks], Symas Corp., 2012-07.</ref>
Zimbra has tested back-mdb vs back-hdb performance in OpenLDAP, with LMDB clearly outperforming the BDB based back-hdb.<ref>{{cite web | url=http://wiki.zimbra.com/wiki/OpenLDAP_MDB_vs_HDB_performance|title=OpenLDAP MDB vs HDB performance|publisher=Zimbra, Inc.}}</ref> Many other OpenLDAP users have observed similar benefits.<ref>{{cite web|url=https://mishikal.wordpress.com/2013/05/16/openldap-a-comparison-of-back-mdb-and-back-hdb-performance/|title=OpenLDAP: A comparison of back-mdb and back-hdb performance|date=16 May 2013|accessdate=8 May 2017}}</ref>
 
Since the initial benchmarking work done in 2012, multiple follow-on tests have been conducted with additional database engines for both in-memory <ref>{{cite web|last1=Chu|first1=Howard|title=In-Memory Microbenchmark|url=http://symaswww.comlmdb.tech/mdbbench/inmem/|publisher=Symas Corp.|access-date=2014-12-06|archive-url=https://web.archive.org/web/20141209233002/http://symas.com/mdb/inmem/|archive-date=2014-12-09|url-status=deadlive}}</ref> and on-disk <ref>{{cite web|last1=Chu|first1=Howard|title=On-Disk Microbenchmark|url=http://symaswww.comlmdb.tech/mdbbench/ondisk/|publisher=Symas Corp.|access-date=2014-12-06|archive-url=https://web.archive.org/web/20141209233807/http://symas.com/mdb/ondisk/|archive-date=2014-12-09|url-status=deadlive}}</ref> workloads characterizing the performance across multiple CPUs and record sizes. These tests show that LMDB performance is unmatched on all in-memory workloads, and excels in all disk-bound read workloads, as well asand disk-bound write workloads using large record sizes. The benchmark driver code was subsequently published on GitHub<ref>{{cite web|title=Benchmark Drivers|website=[[GitHub]] |url=https://github.com/hyc/leveldb/tree/benches/doc/bench}}</ref> and further expanded in database coverage.
 
== Reliability ==
LMDB was designed from the start to resist data loss in the face of system and application crashes. Its [[copy-on-write]] approach never overwrites currently-in-use data. Avoiding overwrites means the structure on disk/storage is always valid, so application or system crashes can never leave the database in a corrupted state. In its default mode, at worst, a crash can lose data from the last not-yet-committed write transaction. Even with all asynchronous modes enabled, it is only an OS catastrophic failure or hardware power-loss<ref>{{cite web | url=https://bugs.openldap.org/show_bug.cgi?id=7668|title=LMDB Corruption detection}}</ref> event rather than merely an application crash that could potentially result in any data corruption.
 
Two academic papers from the [[USENIX Symposium on Operating Systems Design and Implementation|USENIX OSDI Symposium]]<ref>{{cite web | url=https://www.usenix.org/conference/osdi14|title=OSDI 2014|date=2013-02-08}}</ref> covered failure modes of DB engines (including LMDB) under a sudden power loss or system crash.<ref>{{cite book | url=https://www.usenix.org/conference/osdi14/technical-sessions/presentation/pillai|title=OSDI 2014, All File Systems Are Not Created Equal: On the Complexity of Crafting Crash-Consistent Applications|pages=433–448|isbn=9781931971164|year=2014|last1=Langston|first1=Mark C.|last2=Skelly|first2=Hal}}</ref><ref>{{cite book | url=https://www.usenix.org/conference/osdi14/technical-sessions/presentation/zheng_mai|title=OSDI 2014, Torturing Databases for Fun and Profit|pages=449–464|isbn=9781931971164|year=2014|last1=Langston|first1=Mark C.|last2=Skelly|first2=Hal}}</ref> The paper from Pillai et al., did not find any failure in LMDB that would occur in the real-world file systems considered; the single failure identified by the study in LMDB only relates to hypothetical file systems.<ref>{{cite web | url=http://www.openldap.org/lists/openldap-devel/201410/msg00004.html|title=Archive of discussion regarding the Usenix 2014 pillai paper}}</ref> The Mai Zheng et al. paper claims to point out failures in LMDB, but the conclusion depends on whether fsync or fdatasync is utilised. Using fsync ameliorates the problem. The Selectionselection of fsync orover fdatasync is a compile-time switch whichthat is not the default behavior in current GNU/Linux builds of LMDB, but is the default on macOS, *BSD, Android, and Windows. Default GNU/Linux builds of LMDB are, therefore, the only ones vulnerable to the problem discovered by the zhengmai researchers however, LMDB may simply be rebuilt by GNU/Linux users to utilise fsync instead.<ref>{{cite web | url=http://www.openldap.org/lists/openldap-devel/201410/msg00008.html|title=LMDB Crash consistency discussion}}</ref>
 
When provided with a corrupt database, such as one produced by [[fuzzing]], LMDB may crash. LMDB's author considers the case unlikely to be concerning, but has nevertheless produced a partial fix in a separate branch.<ref name=fuzz>{{cite web |last1=Debroux |first1=Lionel |title=oss-security - Fun with DBM-type databases... |url=https://www.openwall.com/lists/oss-security/2018/06/17/1 |website=openwall.com |date=16 Jun 2018}}</ref>
 
== Open source license ==
In June 2013, [[Oracle Corporation|Oracle]] changed the license of [[Berkeley DB]] (a related project) from the [[Sleepycat license]] to the [[Affero General Public License]],<ref>{{cite web | url=https://oss.oracle.com/pipermail/bdb/2013-June/000056.html|title=Berkeley DB Release Announcement|date=11 June 2013 |publisher=[[Oracle Corporation]] |quote=Starting with the 6.0 / 12c releases, all Berkeley DB products are licensed under the GNU AFFERO GENERAL PUBLIC LICENSE (AGPL), version 3. This license is published by the Free Software Foundation (FSF) (1) and approved by the Open Source Initiative (2). Please review the terms of the license to ensure compliance before upgrading to the 12c release. Previous releases of Berkeley DB software will continue to be distributed under the Sleepycat license.}}</ref> thus restricting its use in a wide variety of applications. This caused the [[Debian|Debian project]] to exclude the library from 6.0 onwards. It was also criticized that this license is not friendly to commercial redistributors. The discussion was sparked over whether the same licensing change could happen to LMDB. Author Howard Chu made clearclarified that LMDB is part of the OpenLDAP project, which had its BSD -style license before he joined, and it will stay like it. No copyright is transferred to anybody by checking in, which would make a similar move like Oracle's impossible.<ref>{{cite mailing list | url=http://lists.debian.org/debian-devel/2013/07/msg00031.html |title=Berkeley DB 6.0 license change to AGPLv3 |date=July 2, 2013 |mailing-list=debian-devel |publisher=[[Debian]] |author=Ondřej Surý}}</ref><ref>{{cite news |url=http://www.infoworld.com/d/open-source-software/oracle-switches-berkeley-db-license-222097 |title=Oracle switches Berkeley DB license |author=Simon Phipps |date=July 5, 2013 |publisher=[[InfoWorld]]}}</ref><ref>{{cite web | url=http://developers.slashdot.org/story/13/07/05/1647215/oracle-quietly-switches-berkeleydb-to-agpl|title=Oracle Quietly Switches BerkeleyDB to AGPL|date=5 July 2013 |publisher=[[Slashdot]]}}</ref><ref>{{cite web |url=http://programmers-in-ua.blogspot.com/2013/07/oracle-berkeley-db.html |title=Oracle меняет лицензию Berkeley DB |publisher=[[Blogspot]] |website=Programmers in Ukraine |date=July 22, 2013 |language=ru |trans-title=Oracle Berkeley DB license changes}}</ref><ref>{{cite web | url=http://www.lemondeinformatique.fr/actualites/lire-oracle-passe-berkeley-db-sous-licence-gnu-agpl-54287.html|title=Oracle passe Berkeley DB sous licence GNU AGPL |language=fr |trans-title=Oracle Berkeley DB passes under GNU AGPL |date=July 8, 2013 |author= Jean Elyan |publisher=Le Monde Informatique}}</ref><ref>{{cite web | url=http://www.abclinuxu.cz/zpravicky/berkeley-db-6.0-vydana-pod-licenci-agplv3 |title=Berkeley DB 6.0 vydána pod licencí AGPLv3 |language=cs |trans-title=Berkeley DB 6.0 is released under the GPLv3 license |date=July 2, 2013 |author=Ondřej Surý |publisher=Abclinuxu}}</ref><ref>{{cite web | url=https://lwn.net/Articles/557820/ |title=Debian, Berkeley DB, and AGPLv3 |author=Nathan Willis |date=July 10, 2013 |publisher=[[LWN.net]]}}</ref><!-- Nathan Willis copied several posts from debian-devel to LWN.net, including url=https://lwn.net/Articles/558155/ and url=https://lwn.net/Articles/558154/; let's cite the original--><ref>{{cite mailing list | url=https://lists.debian.org/debian-devel/2013/07/msg00047.html |title=Berkeley DB 6.0 license change to AGPLv3 |date=July 2, 2013 |mailing-list=debian-devel |publisher=[[Debian]] |author=Dan Shearer}}</ref><ref>{{cite mailing list | url=https://lists.debian.org/debian-devel/2013/07/msg00067.html |title=Berkeley DB 6.0 license change to AGPLv3 |date=July 2, 2013 |mailing-list=debian-devel |publisher=[[Debian]] |author=Howard Chu}}</ref>
 
The Berkeley DB license issue has caused major GNU/Linux distributions such as [[Debian]] to completely phase out their use of Berkeley DB, with a preference for LMDB.<ref>{{cite mailing list | url=https://lists.debian.org/debian-devel/2014/06/msg00338.html | title=New project goal: Get rid of Berkeley DB (post jessie) | mailing-list=debian-devel | date=June 19, 2014 | author=Ondřej Surý |publisher=[[Debian]]}}</ref>
 
== API and uses ==
There are wrappers for several programming languages, such as C++,<ref>[https://github.com/bendiken/lmdbxx LMDB C++11 wrapper], 2015-04</ref><ref>[https://code.google.com/p/libglim/source/browse/trunk/mdb.hpp LMDB C++ wrapper], 2012-11.</ref> Java,<ref>[https://github.com/lmdbjava/lmdbjava LmdbJava], 2019-04</ref> Python,<ref>[https://github.com/dw/py-lmdb/ LMDB Python wrapper], 2013-02</ref><ref>[http://lmdb.readthedocs.org py-lmdb]. Retrieved on 2014-10-20.</ref> Lua,<ref>[https://github.com/shmul/lightningdbm LMDB Lua wrapper], 2013-04.</ref> Rust,<ref>[https://github.com/meilisearch/heed typed LMDB Rust wrapper], 2023-01</ref><ref>[https://github.com/mozilla/rkv high-level Rust wrapper], 2022-12</ref> Go,<ref>[https://github.com/szferibmatsuo/gomdblmdb-go LMDB Go wrapper], 2013-0403</ref> Ruby,<ref>[https://github.com/minad/lmdb LMDB Ruby wrapper], 2013-02</ref> Objective C,<ref>[https://github.com/rbartolome/LMDBKit LMDB Objective-C wrapper], 2013-04</ref> Objective CAML,<ref>[https://github.com/Drup/ocaml-lmdb OCaml lmdb bindings], 2025-08</ref> Javascript,<ref>[https://github.com/Venemo/node-lmdb LMDB Node.js wrapper], 2013-05</ref> C#,<ref>[https://github.com/ilyalukyanov/Lightning.NET LMDB .Net wrapper], 2013-06</ref> Perl,<ref>[http://search.cpan.org/dist/LMDB_File/ LMDB Perl wrapper], 2013-08</ref> PHP,<ref>[https://github.com/mpremus/lmdb-php LMDB PHP wrapper], 2015-04</ref> Tcl<ref>[https://core.tcl.tk/jenglish/gutter/packages/lmdb.html tcl-lmdb], 2015-11</ref> and Common Lisp.<ref>[http://eudoxia.me/article/lmdb-from-common-lisp Using LMDB from Common Lisp], 2016-04</ref> A complete list of wrappers may be found on the main web site.<ref>{{cite web|url=https://www.symas.com/symas-lmdb/technical/#wrappers-tech-info|title=ListSymas ofLMDB APITech wrappers for LMDBInfo}}</ref>
 
Howard Chu ported [[SQLite]] 3.7.7.1 to use LMDB instead of its original [[B-tree]] code, calling the end result SQLightning.<ref>{{cite web|url=http://gitorious.org/mdb/sqlightning|title=gitorious.org Git - mdb:<nowiki />sqlightning.git/summary|website=gitorious.org|accessdate=8 May 2017|archive-url=https://web.archive.org/web/20130809145553/http://gitorious.org/mdb/sqlightning|archive-date=9 August 2013|url-status=deadlive}}</ref> One cited insert test of 1000 records was 20 times faster (than the original SQLite with its B-Tree implementation).<ref>[http://pastebin.com/B5SfEieL SQLightning tests].</ref> LMDB is available as a backing store for other open source projects including Cyrus SASL,<ref>{{cite web|url=http://cyrusimap.web.cmu.edu/|title=Cyrus IMAP — Cyrus IMAP 3.0.1 (stable) documentation|website=cyrusimap.web.cmu.edu|accessdate=8 May 2017|url-status=dead|archive-url=https://web.archive.org/web/20170430023937/http://cyrusimap.web.cmu.edu/|archive-date=30 April 2017}}</ref> Heimdal Kerberos,<ref>{{cite web|url=http://h5l.org/|title=Heimdal|website=h5l.org|accessdate=8 May 2017}}</ref> and OpenDKIM.<ref>{{cite web|url=http://www.opendkim.org/|title=OpenDKIM|website=www.opendkim.org|accessdate=8 May 2017}}</ref> It is also available in some other NoSQL projects like MemcacheDB <ref>{{cite web|url=https://gitorious.org/mdb/memcachedb|title=gitorious.org Git - mdb:<nowiki />memcachedb.git/summary|website=gitorious.org|accessdate=8 May 2017}}</ref> and Mapkeeper.<ref>{{cite web|url=https://github.com/m1ch1/mapkeeper/|title=GitHub - m1ch1/mapkeeper: Thrift based key-value store with various storage backends, including MySQL, Berkeley DB, and LevelDB.|website=GitHubgithub.com|accessdateurl-status=8dead|archive-url=https://web.archive.org/web/20160209024233/https://github.com/m1ch1/mapkeeper/|archive-date=9 MayFebruary 20172016}}</ref> LMDB was used to make the in-memory store [[Redis]] persist data on disk. The existing back-end in [[Redis]] showed pathological behaviour in rare cases, and a replacement was sought. The baroque API of LMDB was criticized though, forcing a lot of coding to get simple things done. However, its performance and reliability during testing was considerably better than the alternative back-end stores that were tried.<ref>{{cite web|url=http://www.anchor.com.au/blog/2013/05/second-strike-with-lightning/|title=Second Strike With Lightning|publisher=Anchor|date=2013-05-09}}</ref>
LMDB was used to make the in-memory store [[Redis]] persist data on disk. The existing back-end in [[Redis]] showed pathological behaviour in rare cases, and a replacement was sought. The baroque API of LMDB was criticized though, forcing a lot of coding to get simple things done. However, its performance and reliability during testing was considerably better than the alternative back-end stores that were tried.<ref>{{cite web|url=http://www.anchor.com.au/blog/2013/05/second-strike-with-lightning/|title=Second Strike With Lightning|publisher=Anchor|date=2013-05-09}}</ref>
 
An up-to-date list of applications using LMDB is maintained on the main web site.<ref>{{cite web|url=httphttps://www.symas.com/mdb/#projectssymas-lmdb-tech-info|title=List of projects using LMDB}}</ref>
An independent third-party software developer utilised the [[Python (programming language)|Python]] bindings to LMDB<ref>{{cite web | url=http://lmdb.readthedocs.org|title=Python bindings to LMDB}}</ref> in a high-performance environment and published, on the technical news site [[Slashdot]], how the system managed to successfully sustain 200,000 simultaneous read, write and delete operations per second (a total of 600,000 database operations per second).<ref>{{cite web | url=http://developers.slashdot.org/story/14/10/17/1547222/python-lmdb-in-a-high-performance-environment|title=Python-LMDB in a high-performance environment on Slashdot}}</ref><ref>{{cite web | url=http://lkcl.net/reports/python.lmdb.html|title=Open letter to Howard Chu and David Wilson regarding Python-LMDB}}</ref>
 
An up-to-date list of applications using LMDB is maintained on the main web site.<ref>{{cite web|url=http://symas.com/mdb/#projects|title=List of projects using LMDB}}</ref>
 
== Application support ==
Many popular [[free software]] projects distribute or include support for LMDB, often as the primary or sole storage mechanism.
 
* The [[Debian]],<ref>[https://packages.debian.org/liblmdb0 liblmdb0 in Debian]. Retrieved 2014-10-20.</ref> [[Ubuntu (operating system)|Ubuntu]],<ref>{{cite web|url=https://packages.ubuntu.com/lmdb-utils|title=Ubuntu – Package Search Results -- lmdb-utils|first=Rhonda D'Vine|last=rhonda@ubuntu.comD'Vine|website=packages.ubuntu.com|accessdate=2 Jan 2018}}</ref> [[Fedora (operating system)|Fedora]],<ref>[http://rpm.pbone.net/index.php3/stat/4/idpl/26914801/dir/fedora_20/com/lmdb-0.9.13-1.fc20.i686.rpm.html LMDB in Fedora 20]. Retrieved 2014-10-20.</ref> and [[OpenSuSE]]<ref>[http://rpm.pbone.net/index.php3/stat/4/idpl/27477943/dir/opensuse/com/lmdb-0.9.11-4.2.2.x86_64.rpm.html lmdb in OpenSUSE]. Retrieved 2014-10-20.</ref> operating systems.
* [[OpenLDAP]] for which LMDB was originally developed via {{mono|back-mdb}}.<ref>[http://www.openldap.org/doc/admin24/backends.html#LMDB OpenLDAP back-mdb]. Retrieved 2014-10-20</ref>
* [[Postfix (software)|Postfix]] via the {{mono|lmdb_table}} adapter.<ref>[http://www.postfix.org/lmdb_table.5.html Postfix lmdb_table(5)]. Retrieved 2014-10-20</ref>
Line 86 ⟶ 82:
* [[Knot DNS]] a high performance DNS server.
* [[Monero (cryptocurrency)|Monero]] an open source cryptocurrency created in April 2014 that focuses on privacy, decentralisation and scalability.
* [[Enduro/X]] middleware uses LMDB for optional XATMI Microservices (SOA) cache. SoFor that forthe first request the actual service is invoked,; in the next request client process reads the saved result directly from LMDB.
* [[Samba (software)|Samba]] Active Directory Domain Controller
* [[Nano (cryptocurrency)|Nano]] a peer-to-peer, open source cryptocurrency created in 2015 that prioritizes fast and fee-less transactions.
* Meilisearch an open source, lightning-fast, easy-to-use, and hyper-relevant search engine.<ref>{{cite web|url=https://docs.meilisearch.com/learn/advanced/storage.html|title=Storage &#124; Meilisearch Documentation v1.0|access-date=21 Mar 2023}}</ref>
* LMDB-IndexedDB is a JavaScript wrapper around [[IndexedDB]] to provide support for LMDB in web browsers.<ref>{{cite web|url=https://github.com/anywhichway/lmdb-indexeddb|title=LMDB-IndexedDB on GitHub|website=[[GitHub]] |access-date=2 Apr 2023}}</ref>
 
== Technical reviews of LMDB ==
LMDB makes novel use of well-known computer science techniques such as [[copy-on-write]] semantics and [[B+ tree]]s to provide atomicity and reliability guarantees as well as performance that can be hard to accept, given the library's relative simplicity and that no other similar [[key-value store]] database offers the same guarantees or overall performance, even though the authors ''explicitly state'' in presentations that LMDB is read-optimised not write-optimised. Additionally, as LMDB was primarily developed for use in [[OpenLDAP]], its developers are focused mainly on the development and maintenance of OpenLDAP, not on LMDB per se. The developers limited time spent presenting the first benchmark results was therefore criticized as not stating limitations, and for giving a "silver bullet impression" not adequate to address an engineers attitude<ref>{{cite web | url=http://banksco.de/p/lmdb-the-leveldb-killer.html|title=LMDB: The Leveldb Killer?}}</ref> ''(it has to be pointed out that the concerns raised however were later adequately addressed to the reviewer's satisfaction by the key developer behind LMDB.<ref>{{cite web | url=https://symas.com/is-lmdb-a-leveldb-killer/|title=Response to LMDB review|date=2013archive-08-19}}</ref><ref>[httpurl=https://bankscoweb.dearchive.org/pweb/20201111195059/https://symas.com/is-lmdb-thea-leveldb-killer.html/|url-status=dead LMDB: The Leveldb Killer?]|website=symas.com|archive-date=11 RetrievedNovember 2014-10-20.2020}}</ref>)''
 
The presentation did spark other database developers dissectingto dissect the code in-depth to understand how and why it works. Reviews run from brief <ref>{{cite web | url=http://kellabyte.com/2013/07/09/lightning-memory-mapped-database/|title=Lightning Memory-Mapped Database|archive-url=https://web.archive.org/web/20160314133119/http://kellabyte.com/2013/07/09/lightning-memory-mapped-database/|archive-date=14 March 2016}}</ref> to in-depth. Database developer Oren Eini wrote a 12-part series of articles on his analysis of LMDB, beginning July 9, 2013. The conclusion was in the lines of "impressive codebase ... dearly needs some love", mainly because of too long methods and code duplication.<ref>{{cite web | url=http://ayende.com/blog/162754/reviewing-lightning-memory-mapped-database-library-partial|title=Reviewing Lightning memory-mapped database library: Partial}}</ref> This review, conducted by a .NET developer with no former experience of [[C (programming language)|C]], concluded on August 22, 2013, with "beyond my issues with the code, the implementation is really quite brilliant. The way LMDB manages to pack so much functionality by not doing things is quite impressive... I learned quite a lot from the project, and it has been frustrating, annoying and fascinating experience".<ref>{{cite web | url=http://ayende.com/blog/162917/some-final-notes-about-lmdb-review|title=Some final notes about LMDB review}}</ref>
 
Multiple other reviews cover LMDB<ref>{{cite web|url=https://mozilla.github.io/firefox-browser-architecture/text/0015-rkv.html|title=Design Review: Key-Value Storage|website=mozilla.github.io|quote=We propose the standardization of a simple key-value storage capability, based on LMDB, that is fast, compact, multi-process-capable, and equally usable from JS, Java, Rust, Swift, and C++.}}</ref><ref>{{cite web|url=http://sampathherga.in/lmdb/|title=LMDB|publisher=Sampath Herga|access-date=2013-08-30|archive-url=https://web.archive.org/web/20130829025217/http://sampathherga.in/lmdb/|archive-date=2013-08-29|url-status=dead}}</ref> in various languages including Chinese.<ref>{{cite web | url=http://jianshu.io/p/yzFf8j|title=lmdb简介 - 简书}}</ref>
The presentation did spark other database developers dissecting the code in-depth to understand how and why it works. Reviews run from brief <ref>{{cite web | url=http://kellabyte.com/2013/07/09/lightning-memory-mapped-database/|title=Lightning Memory-Mapped Database}}</ref> to in-depth. Database developer Oren Eini wrote a 12-part series of articles on his analysis of LMDB, beginning July 9, 2013. The conclusion was in the lines of "impressive codebase ... dearly needs some love", mainly because of too long methods and code duplication.<ref>{{cite web | url=http://ayende.com/blog/162754/reviewing-lightning-memory-mapped-database-library-partial|title=Reviewing Lightning memory-mapped database library: Partial}}</ref> This review, conducted by a .NET developer with no former experience of [[C (programming language)|C]], concluded on August 22, 2013 with "beyond my issues with the code, the implementation is really quite brilliant. The way LMDB manages to pack so much functionality by not doing things is quite impressive... I learned quite a lot from the project, and it has been frustrating, annoying and fascinating experience"<ref>{{cite web | url=http://ayende.com/blog/162917/some-final-notes-about-lmdb-review|title=Some final notes about LMDB review}}</ref>
 
==See also==
Multiple other reviews cover LMDB<ref>{{cite web|url=http://sampathherga.in/lmdb/|title=LMDB|publisher=Sampath Herga|access-date=2013-08-30|archive-url=https://web.archive.org/web/20130829025217/http://sampathherga.in/lmdb/|archive-date=2013-08-29|url-status=dead}}</ref> in various languages including Chinese.<ref>{{cite web | url=http://jianshu.io/p/yzFf8j|title=lmdb}}</ref><ref>{{cite web|url=http://matao.writings.io/articles/1-lmdb|title=lmdb|accessdate=8 May 2017|archive-url=https://web.archive.org/web/20160305120551/http://matao.writings.io/articles/1-lmdb|archive-date=5 March 2016|url-status=dead}}</ref>
* [[Ordered Key-Value Store]]
* [[libmdbx]] (aka MDBX) is a deeply revised and extended descendant of LMDB, which according to the developers, "is superior to legendary LMDB in terms of features and reliability, not inferior in performance". It is noteworthy MDBX is used in [[Ethereum]] (Erigon, Reth), in products of [[StarkWare Industries]], [[Positive Technologies]], as well as in many other software projects.
 
== References ==