What it is
LMDB (Lightning Memory-Mapped Database) is a high-performance, memory-mapped key-value store developed by the OpenLDAP project. It is compact, transactional, and highly efficient, designed for read-heavy workloads with low latency.
LMDB provides a transactional key-value store API, supporting ACID properties, multiple named databases, and concurrent readers. It is optimized for read-heavy workloads with very fast lookup performance.
Installation
sudo apt install liblmdb-devGetting started
The smallest useful thing you can do with it, and what each part means.
#include <lmdb.h>
#include <iostream>
int main() {
MDB_env* env;
MDB_dbi dbi;
MDB_val key, data;
MDB_txn* txn;
MDB_cursor* cursor;
// Create environment
mdb_env_create(&env);
mdb_env_set_maxdbs(env, 1);
mdb_env_open(env, "./testdb", 0, 0664);
// Start transaction
mdb_txn_begin(env, NULL, 0, &txn);
mdb_open(txn, NULL, 0, &dbi);
key.mv_size = 5; key.mv_data = (void*)"hello";
data.mv_size = 5; data.mv_data = (void*)"world";
mdb_put(txn, dbi, &key, &data, 0);
mdb_txn_commit(txn);
mdb_close(env, dbi);
mdb_env_close(env);
return 0;
}Advanced usage
Where the library earns its place over a simpler alternative.
mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
mdb_cursor_open(txn, dbi, &cursor);
while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == 0) {
std::cout << (char*)key.mv_data << " => " << (char*)data.mv_data << std::endl;
}
mdb_cursor_close(cursor);
mdb_txn_abort(txn);mdb_open(txn, "users", MDB_CREATE, &dbi);mdb_txn_begin(env, NULL, 0, &txn);
// Perform operations
mdb_txn_commit(txn);mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);Errors and fixes
The failures you are most likely to hit, and what actually resolves them.
- MDB_MAP_FULL
- Occurs when the database map size is exceeded. Increase map size with `mdb_env_set_mapsize`.
- MDB_BAD_TXN
- Happens when using a transaction after it has been committed or aborted.
- MDB_CORRUPTED
- Indicates possible data corruption. Restore from backup if repair is not possible.
Best practices
- Use LMDB for workloads with frequent reads and fewer writes.
- Avoid long-running read transactions as they may block database growth.
- Store small to medium-sized values; LMDB is not optimized for huge blobs.
- Use named databases when organizing multiple datasets in the same environment.
- Carefully size the LMDB map to avoid resizing overhead.
Background
Why it exists, and what it was reacting to.
LMDB was created by Howard Chu of the OpenLDAP project to provide a lightweight, transactional database for LDAP storage. Unlike traditional databases, LMDB uses memory-mapped files, allowing it to achieve excellent performance with minimal overhead. It has since been adopted widely in blockchain systems, distributed storage, and embedded applications.
