LMDB_File#

📦 std

Tie a Perl hash to an LMDB database, or drive LMDB’s environments, transactions and cursors directly.

LMDB_File is the CPAN interface to OpenLDAP’s Lightning Memory-Mapped Database. An environment is a directory (or, with MDB_NOSUBDIR, a file) holding one unnamed database and, with maxdbs, named ones. Every read and write happens in a transaction: read transactions see a snapshot and never block, and one write transaction at a time commits atomically.

The simplest use is a tied hash, which opens the environment, begins a transaction and commits it when the hash is untied. The object interface gives the environment (LMDB::Env), transactions (LMDB::Txn), databases (LMDB_File) and cursors (LMDB::Cursor) explicitly.

Synopsis#

use LMDB_File qw(:flags :cursor_op);

tie my %h, 'LMDB_File', 'data-dir';
$h{greeting} = 'hello';
untie %h;

my $env = LMDB::Env->new('data-dir', { mapsize => 1 << 30, maxdbs => 4 });
my $txn = $env->BeginTxn;
my $db  = $txn->OpenDB({ dbname => 'users', flags => MDB_CREATE });
$db->put(alice => 'admin');
$txn->commit;

The tie interface#

tie %h, 'LMDB_File', $path;                    # options as below
tie %h, 'LMDB_File', $path, \%options;
tie %h, 'LMDB_File', $path, $flags, $mode;     # as other DBM modules
tie %h, 'LMDB_File', $env, \%dboptions;        # in an environment
tie %h, 'LMDB_File', $txn, \%dboptions;        # in a transaction

The forms with a path open (and create) the environment, begin a transaction and open the database in it; %options takes the environment’s options and the database’s (dbname, flags). A transaction the tie begins commits when the hash is untied. $path is a directory, which must exist, unless MDB_NOSUBDIR is among the flags.

LMDB::Env#

LMDB::Env->new($path, \%options) creates (if need be) and opens an environment. The options: mapsize (the most data it can hold, default 1 MiB - choose it large, it reserves address space only), maxdbs (named databases allowed, default 0), maxreaders (default 126), mode (of files created, default 0600) and flags, the :envflags constants such as MDB_NOSUBDIR, MDB_RDONLY, MDB_NOSYNC, MDB_WRITEMAP.

  • $env->BeginTxn($flags) - a new LMDB::Txn; MDB_RDONLY for a read transaction (the environment’s own MDB_RDONLY is passed on).

  • $env->copy($path), $env->copyfd($fh) - a consistent copy of the environment, to a directory or an open file.

  • $env->stat - the unnamed database’s statistics, a hash reference (psize, depth, branch_pages, leaf_pages, overflow_pages, entries); $env->info - the map’s mapaddr, mapsize, last_pgno, last_txnid, maxreaders, numreaders.

  • $env->sync($force) - flush to disk (needed with MDB_NOSYNC).

  • $env->set_flags($flags, $on), $env->get_flags($var) - change or read the flags that can change while open.

  • $env->get_path($var), $env->get_maxreaders($var), $env->get_maxkeysize - the path, the reader slots, the longest key (511 bytes with the usual liblmdb).

  • $env->set_mapsize($size) - grow the map while no transaction is live.

  • $env->id - a number identifying the environment.

The environment closes when its last reference goes.

LMDB::Txn#

A transaction is $env->BeginTxn or LMDB::Txn->new($env, $flags). A read transaction sees a snapshot and never blocks; one write transaction at a time sees its own writes and makes them all durable at commit. A transaction that goes out of scope is aborted, unless $txn->AutoCommit(1) asks for a commit.

  • $txn->commit, $txn->abort - end it; afterwards only env may be called.

  • $txn->reset, $txn->renew - let a read transaction’s snapshot go, and take a fresh one later.

  • $txn->SubTxn($flags) - a nested transaction, whose writes join the parent’s at its commit and vanish at its abort.

  • $txn->OpenDB(\%dboptions) or $txn->OpenDB($dbname, $flags) - an LMDB_File database object; $txn->open($dbname, $flags) - the bare database number. The :dbflags constants: MDB_CREATE, MDB_DUPSORT, MDB_INTEGERKEY and the like.

  • $txn->put($dbi, $key, $value, $flags), $txn->get($dbi, $key, $value) - the fast path, on a database number.

  • $txn->env - the environment; $txn->id - the transaction’s ID.

LMDB_File: a database in a transaction#

$txn->OpenDB(...), LMDB_File->open($txn, $dbname, $flags) or LMDB_File->new($txn, $dbi) give an object that pairs a database with a transaction.

  • $db->get($key) - the value or undef; $db->get($key, $value) puts it in $value and reports a missing key as an error.

  • $db->put($key, $value, $flags) - store; the :writeflags constants MDB_NOOVERWRITE, MDB_NODUPDATA, MDB_APPEND, MDB_APPENDDUP, and MDB_RESERVE with a length to write the value in place afterwards.

  • $db->del($key, $value) - delete the key, or in an MDB_DUPSORT database one of its values.

  • $db->set_compare(sub { $a cmp $b }) - a sort sub for the keys, called with $a and $b as sort calls one; set it before any other use, the same every time.

  • $db->ReadMode(1) - get returns the value in place, a read-only scalar over the map, without copying it (writable with MDB_WRITEMAP in a write transaction); it is valid until the transaction ends or, in a write transaction, the next write. $db->Rget($key) does the same for one call.

  • $db->UTF8(1) - store character strings as UTF-8 and decode them on the way out (use bytes skips the decoding).

  • $db->stat, $db->flags, $db->drop($remove) (empty, or delete the database), $db->Alive, $db->Txn (assignable), $db->dbi (assignable), $db->Cursor.

LMDB::Cursor#

$db->Cursor opens a cursor. $cursor->get($key, $value, $op) moves it by one of the :cursor_op operations (MDB_FIRST, MDB_NEXT, MDB_SET_RANGE, MDB_NEXT_DUP …) and puts the key and value it lands on in $key and $value; $cursor->put($key, $value, $flags) stores and leaves the cursor on the item; $cursor->del($flags) deletes where it stands (MDB_NODUPDATA: all the key’s values). count, renew($txn), txn, dbi and close complete it.

Errors#

By default an LMDB error dies with LMDB’s message in $@. With $LMDB_File::die_on_err false a call returns the error code instead; either way $LMDB_File::last_err holds the last code. LMDB_File::strerror($code) gives a code’s message.

Two more functions, not exported: LMDB_File::version(my $major, my $minor, my $patch) returns liblmdb’s version string (“LMDB 0.9.35: (Jan 27, 2026)”) and sets the three numbers; and LMDB_File::reader_check($env, my $dead) clears the reader slots left behind by processes that died with a read transaction open, setting $dead to how many it cleared.

Constants#

use LMDB_File qw(...) imports by tag: :envflags, :dbflags, :writeflags, :flags (all three), :cursor_op, :error (the MDB_* error codes) and :version (MDB_VERSION_STRING and the like, the version of the liblmdb in use).

Differences from upstream#

Four, each where perl 5.44 with XS LMDB_File fails (t/15-modules/LMDB_File/150-or-better.t):

  • LMDB::Cursor::_put with MDB_RESERVE takes the length as its fifth argument. Upstream demands five arguments and then reads a sixth, past the end of them, and dies “MDB_RESERVE length must be > 0”.

  • A failed LMDB::Cursor::open leaves its argument undef, which LMDB_File.pm checks for; upstream fills it with a pointer to nothing.

  • $env->close leaves the environment closed for good: closing it again, as its DESTROY does, is harmless, and the same database can be opened again. Upstream frees the environment twice and aborts.

  • $env->close with a transaction still open ends the transaction first, as dropping the environment does; using it afterwards dies “Not an active transaction” or “Terminated transaction”. Upstream leaves it pointing at freed memory and crashes.

liblmdb is the system’s library, loaded when first needed. Everything else behaves as with upstream’s LMDB_File, as its own test suite shows: t/15-modules/LMDB_File/100-upstream-00-basic.t to 140-upstream-04-bigone.t.