PPoossttffiixx OOppeennLLDDAAPP LLMMDDBB HHoowwttoo
-------------------------------------------------------------------------------
IInnttrroodduuccttiioonn
Postfix uses databases of various kinds to store and look up information.
Postfix databases are specified as "type:name". OpenLDAP LMDB (called "LMDB"
from here on) implements the Postfix database type "lmdb". The name of a
Postfix LMDB database is the name of the database file without the ".lmdb"
suffix.
This document describes:
* Building Postfix with LMDB support.
* Configuring LMDB settings.
* Using LMDB maps with non-Postfix programs.
* Required minimum LMDB patchlevel.
* Credits.
BBuuiillddiinngg PPoossttffiixx wwiitthh LLMMDDBB ssuuppppoorrtt
Postfix normally does not enable LMDB support. To build Postfix with LMDB
support, use something like:
% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \
AUXLIBS_LMDB="-L/usr/local/lib -llmdb"
% make
Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_LMDB. With Postfix
3.0 and later, the old AUXLIBS variable still supports building a statically-
loaded LMDB database client, but only the new AUXLIBS_LMDB variable supports
building a dynamically-loaded or statically-loaded LMDB database client.
Failure to use the AUXLIBS_LMDB variable will defeat the purpose of dynamic
database client loading. Every Postfix executable file will have LMDB
database library dependencies. And that was exactly what dynamic database
client loading was meant to avoid.
Solaris may need this:
% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \
AUXLIBS_LMDB="-R/usr/local/lib -L/usr/local/lib -llmdb"
% make
The exact pathnames depend on how LMDB was installed.
When building Postfix fails with:
undefined reference to `pthread_mutexattr_destroy'
undefined reference to `pthread_mutexattr_init'
undefined reference to `pthread_mutex_lock'
Add the "-lpthread" library to the "make makefiles" command.
% make makefiles .... AUXLIBS_LMDB="... -lpthread"
CCoonnffiigguurriinngg LLMMDDBB sseettttiinnggss
Postfix provides one configuration parameter that controls LMDB database
behavior.
* lmdb_map_size (default: 16777216). This setting specifies the initial LMDB
database size limit in bytes. Each time a database becomes "full", its size
limit is doubled. The maximum size is the largest signed integer value of
"long".
UUssiinngg LLMMDDBB mmaappss wwiitthh nnoonn--PPoossttffiixx pprrooggrraammss
Programs that use LMDB's built-in locking protocol will corrupt a Postfix LMDB
database or will read garbage.
Postfix does not use LMDB's built-in locking protocol, because that would
require world-writable lockfiles, and would violate Postfix security policy.
Instead, Postfix uses external locks based on fcntl(2) to prevent writers from
corrupting the database, and to prevent readers from receiving garbage.
See lmdb_table(5) for a detailed description of the locking protocol that all
programs must use when they access a Postfix LMDB database.
RReeqquuiirreedd mmiinniimmuumm LLMMDDBB ppaattcchhlleevveell
Currently, Postfix requires LMDB 0.9.11 or later. The required minimum LMDB
patchlevel has evolved over time, as the result of Postfix deployment
experience:
* LMDB 0.9.11 allows Postfix daemons to log an LMDB error message, instead of
falling out of the sky without any notification.
* LMDB 0.9.10 closes an information leak where LMDB was writing up to 4-kbyte
chunks of uninitialized heap memory to the database. This would persist
information that was not meant to be persisted, or share information that
was not meant to be shared.
* LMDB 0.9.9 allows Postfix to use external (fcntl()-based) locks, instead of
having to use world-writable LMDB lock files, violating the Postfix
security model in multiple ways.
* LMDB 0.9.8 allows Postfix to recover from a "database full" error without
having to close the database. This version adds support to update the
database size limit on-the-fly. This is necessary because Postfix database
sizes vary with mail server load.
* LMDB 0.9.7 allows the postmap(1) and postalias(1) commands to use a bulk-
mode transaction larger than the amount of physical memory. This is
necessary because LMDB supports databases larger than physical memory.
CCrreeddiittss
* Howard Chu contributed the initial Postfix dict_lmdb driver.
* Wietse Venema wrote an abstraction layer (slmdb) that behaves more like
Berkeley DB, NDBM, etc. This layer automatically retries an LMDB request
when a database needs to be resized, or after a database was resized by a
different process.
* Howard and Wietse went through many iterations with changes to both LMDB
and Postfix, with input from Viktor Dukhovni.