Postfix uses databases of various kinds to store and look up information. Postfix databases are specified as "type:name". OpenLDAP LMDB implements the Postfix database type "lmdb". The name of a Postfix OpenLDAP LMDB database is the name of the database file without the ".lmdb" suffix. OpenLDAP LMDB databases are maintained with the postmap(1) command.
This document describes:
How to build Postfix with OpenLDAP LMDB support.
How to configure LMDB settings.
Missing pthread library trouble.
Caution: the current Postfix LMDB client has unexpected limitations. For this reason, LMDB support is not part of the stable Postfix release.
Postfix normally does not enable OpenLDAP LMDB support. To build Postfix after you installed OpenLDAP LMDB from source code, use something like:
% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \ AUXLIBS="-L/usr/local/lib -llmdb" % make
Solaris needs this:
% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \ AUXLIBS="-R/usr/local/lib -L/usr/local/lib -llmdb" % make
The exact pathnames depend on how OpenLDAP LMDB was installed.
Postfix provides a configuration parameter that controls how large an OpenLDAP LMDB database may grow.
lmdb_map_size (default: 10 MBytes per table). This setting controls how large any OpenLDAP LMDB database may grow. It must be set large enough to accommodate the largest table that Postfix will use.
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="... -lpthread"
Source code for OpenLDAP LMDB is available at http://www.openldap.org. More information is available at http://highlandsun.com/hyc/mdb/.
Unexpected postmap/postalias "database full" errors.
Even if the "postmap filename" command succeeds, the exact same command, with the exact same input data, may fail subsequently with an MDB_MAP_FULL error. The reason is that unlike other Postfix databases such as "hash" or "btree",
LMDB databases have a hard size limit (configured with the lmdb_map_size configuration parameter).
The Postfix LMDB database client does not implement the "truncate" operation. Instead it saves all store requests to a transaction (which takes up space in addition to the existing data), and commits the transaction when the database is closed. Only then can the space for old data be reused.
This postmap(1) or postalias(1) command failure does not affect Postfix availability, because the old data still exists in the database.
To recover, increase the lmdb_map_size limit in main.cf, and retry the postmap(1) or postalias(1) command.
Postfix daemon "database full" errors.
Unfortunately, "database full" problems will affect Postfix availability with daemon programs such as postscreen(8), tlsmgr(8) or verify(8). These daemon programs will continue to fail until someone increases the lmdb_map_size parameter value. Meanwhile, mail processing comes to a halt.
Non-obvious recovery from a corrupted database.
Unlike other Postfix databases such as "hash" or "btree", you can't rebuild a corrupted LMDB database simply by running postmap(1) or postalias(1), as those commands will crash, too.
The reason for this limitation is that the Postfix LMDB database client does not implement the database "truncate" operation. Instead it tries to save all store requests to a transaction for later processing. That is obviously not possible with a corrupted database file.
To recover, you must first delete the ".lmdb" file by hand, and only then you can retry the postmap(1) or postalias(1) command.
Incompatibility with tlsmgr(8).
The Postfix LMDB database client breaks tlsmgr(8) TLS session cache management. Specifically, it breaks how tlsmgr(8) clears its TLS session cache databases upon start-up, it breaks how tlsmgr(8) looks up new TLS session cache entries, and it breaks how tlsmgr(8) automatically recovers from a corrupted database file.
The reason for these limitations is that the Postfix LMDB database client does not implement the database "truncate" operation. Instead it saves all store requests to a transaction which it commits only when the database is closed. Therefore, tlsmgr(8) will never find any entries that it stores after opening its TLS session cache databases. And when the database becomes corrupted, tlsmgr(8) will keep crashing until someone removes the file ".lmdb" file by hand.