1<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" 2 "http://www.w3.org/TR/html4/loose.dtd"> 3 4<html> 5 6<head> 7 8<title>Postfix OpenLDAP LMDB Howto</title> 9 10<meta http-equiv="Content-Type" content="text/html; charset=us-ascii"> 11 12</head> 13 14<body> 15 16<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix OpenLDAP LMDB Howto</h1> 17 18<hr> 19 20<h2>Introduction</h2> 21 22<p> Postfix uses databases of various kinds to store and look up 23information. Postfix databases are specified as "type:name". OpenLDAP 24LMDB (called "LMDB" from here on) implements the Postfix database 25type "lmdb". The name of a Postfix LMDB database is the name of 26the database file without the ".lmdb" suffix. </p> 27 28<p> This document describes: </p> 29 30<ul> 31 32<li> <p> <a href="#with_lmdb">Building Postfix with LMDB support</a>. 33</p> 34 35<li> <p> <a href="#configure">Configuring LMDB settings</a>. </p> 36 37<li> <p> <a href="#locking">Using LMDB maps with non-Postfix programs</a>. </p> 38 39<li> <p> <a href="#supported"> Required minimum LMDB patchlevel</a>. </p> 40 41<li> <p> <a href="#credits"> Credits</a>. </p> 42 43</ul> 44 45<h2><a name="with_lmdb">Building Postfix with LMDB support</a></h2> 46 47<p> Postfix normally does not enable LMDB support. To 48build Postfix with LMDB support, use something like: </p> 49 50<blockquote> 51<pre> 52% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \ 53 <a href="LMDB_README.html">AUXLIBS_LMDB</a>="-L/usr/local/lib -llmdb" 54% make 55</pre> 56</blockquote> 57 58<p> Postfix versions before 3.0 use AUXLIBS instead of <a href="LMDB_README.html">AUXLIBS_LMDB</a>. 59With Postfix 3.0 and later, the old AUXLIBS variable still supports 60building a statically-loaded LMDB database client, but only the new 61<a href="LMDB_README.html">AUXLIBS_LMDB</a> variable supports building a dynamically-loaded or 62statically-loaded LMDB database client. </p> 63 64<blockquote> 65 66<p> Failure to use the <a href="LMDB_README.html">AUXLIBS_LMDB</a> variable will defeat the purpose 67of dynamic database client loading. Every Postfix executable file 68will have LMDB database library dependencies. And that was exactly 69what dynamic database client loading was meant to avoid. </p> 70 71</blockquote> 72 73 74<p> Solaris may need this: </p> 75 76<blockquote> 77<pre> 78% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \ 79 <a href="LMDB_README.html">AUXLIBS_LMDB</a>="-R/usr/local/lib -L/usr/local/lib -llmdb" 80% make 81</pre> 82</blockquote> 83 84<p> The exact pathnames depend on how LMDB was installed. </p> 85 86<p> When building Postfix fails with: </p> 87 88<blockquote> 89<pre> 90undefined reference to `pthread_mutexattr_destroy' 91undefined reference to `pthread_mutexattr_init' 92undefined reference to `pthread_mutex_lock' 93</pre> 94</blockquote> 95 96<p> Add the "-lpthread" library to the "make makefiles" command. </p> 97 98<blockquote> 99<pre> 100% make makefiles .... <a href="LMDB_README.html">AUXLIBS_LMDB</a>="... -lpthread" 101</pre> 102</blockquote> 103 104<h2><a name="configure">Configuring LMDB settings</a></h2> 105 106<p> Postfix provides one configuration parameter that controls 107LMDB database behavior. </p> 108 109<ul> 110 111<li> <p> <a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a> (default: 16777216). This setting specifies 112the initial LMDB database size limit in bytes. Each time a database 113becomes "full", its size limit is doubled. The maximum size is the 114largest signed integer value of "long". </p> 115 116</ul> 117 118<h2> <a name="locking">Using LMDB maps with non-Postfix programs</a> </h2> 119 120<p> Programs that use LMDB's built-in locking protocol will corrupt 121a Postfix LMDB database or will read garbage. </p> 122 123<p> Postfix does not use LMDB's built-in locking protocol, because 124that would require world-writable lockfiles, and would violate 125Postfix security policy. Instead, Postfix uses external locks based 126on fcntl(2) to prevent writers from corrupting the database, and 127to prevent readers from receiving garbage. </p> 128 129<p> See <a href="lmdb_table.5.html">lmdb_table(5)</a> for a detailed description of the locking 130protocol that all programs must use when they access a Postfix LMDB 131database. </p> 132 133<h2> <a name="supported"> Required minimum LMDB patchlevel </a> </h2> 134 135<p> Currently, Postfix requires LMDB 0.9.11 or later. The required 136minimum LMDB patchlevel has evolved over time, as the result of 137Postfix deployment experience: </p> 138 139<ul> 140 141<li> <p> LMDB 0.9.11 allows Postfix daemons to log an LMDB error 142message, instead of falling out of the sky without any notification. 143</p> 144 145<li> <p> LMDB 0.9.10 closes an information leak where LMDB was 146writing up to 4-kbyte chunks of uninitialized heap memory to the 147database. This would persist information that was not meant to be 148persisted, or share information that was not meant to be shared. 149</p> 150 151<li> <p> LMDB 0.9.9 allows Postfix to use external (fcntl()-based) 152locks, instead of having to use world-writable LMDB lock files, 153violating the Postfix security model in multiple ways. </p> 154 155<li> <p> LMDB 0.9.8 allows Postfix to recover from a "database full" 156error without having to close the database. This version adds support 157to update the database size limit on-the-fly. This is necessary 158because Postfix database sizes vary with mail server load. </p> 159 160<li> <p> LMDB 0.9.7 allows the <a href="postmap.1.html">postmap(1)</a> and <a href="postalias.1.html">postalias(1)</a> commands 161to use a bulk-mode transaction larger than the amount of physical 162memory. This is necessary because LMDB supports databases larger 163than physical memory. </p> 164 165</ul> 166 167<h2> <a name="credits"> Credits</a> </h2> 168 169<ul> 170 171<li> <p> Howard Chu contributed the initial Postfix dict_lmdb driver. 172</p> 173 174<li> <p> Wietse Venema wrote an abstraction layer (slmdb) that 175behaves more like Berkeley DB, NDBM, etc. This layer automatically 176retries an LMDB request when a database needs to be resized, or 177after a database was resized by a different process. </p> 178 179<li> <p> Howard and Wietse went through many iterations with changes 180to both LMDB and Postfix, with input from Viktor Dukhovni. </p> 181 182</ul> 183 184<!-- 185 186<h2><a name="limitations">Unexpected failure modes of Postfix LMDB 187databases. </a> </h2> 188 189<p> As documented below, conversion to LMDB introduces a number of 190failure modes that don't exist with other Postfix databases. Some 191failure modes have been eliminated in the course of time. 192The writeup below reflects the status as of LMDB 0.9.9. </p> 193 194--> 195 196<!-- 197 198<p> <strong>Unexpected "Permission denied" errors. </strong></p> 199 200<dl> 201 202<dt> Problem: </dt> <dd> <p> A world-readable LMDB database cannot 203be opened by a process with a UID that differs from the database 204file owner, even when an attempt is made to open the database 205read-only. This problem does not exist with other Postfix databases. 206</p> </dd> 207 208<dt> Background: </dt> <dd> <p> The LMDB implementation requires 209write access to maintain read locks, and perhaps for other purposes. 210</p> </dd> 211 212<dt> Solution: </dt> <dd> <p> Consider using <a href="CDB_README.html">cdb</a>: to manage root-owned 213databases under the root-owned <tt>/etc</tt> or <a href="postconf.5.html#config_directory">config_directory</a> 214(default: <tt>/etc/postfix</tt>) such as <a href="access.5.html">access(5)</a>, <a href="virtual.5.html">virtual(5)</a>, 215<a href="transport.5.html">transport(5)</a>. Support to create LMDB databases is available only 216for unprivileged Postfix daemon processes such as <a href="postscreen.8.html">postscreen(8)</a>, 217<a href="tlsmgr.8.html">tlsmgr(8)</a> and <a href="verify.8.html">verify(8)</a> that manage postfix-owned databases under 218the postfix-owned <a href="postconf.5.html#data_directory">data_directory</a> (default: <tt>/var/lib/postfix</tt>). 219</p> </dd> 220 221</dl> 222 223--> 224 225<!-- 226 227<p> <strong>Unexpected "readers full" errors. </strong></p> 228 229<dl> 230 231<dt> Problem: </dt> <dd> <p> Under heavy load, database read 232operations fail with MDB_READERS_FULL errors. This problem does not 233exist with other Postfix databases. </p> </dd> 234 235<dt> Background: </dt> <dd> <p> The LMDB implementation enforces a 236hard limit on the number of simultaneous read requests for the same 237database environment. This limit must be specified in advance with 238the lmdb_max_readers configuration parameter. </p> </dd> 239 240<dt> Mitigation: </dt> <dd> <p> Postfix logs a warning suggesting 241that the lmdb_max_readers parameter value be increased, and retries 242the failed operation for a limited number of times while running 243with reduced performance. </p> </dd> 244 245<dt> Prevention: </dt> <dd> <p> Monitor your LMDB files for 246MDB_READERS_FULL errors. After making the necessary adjustments, 247restart Postfix. </p> </dd> 248 249</dl> 250 251--> 252 253<!-- 254 255<p> <strong>Unexpected <a href="postmap.1.html">postmap(1)</a>/<a href="postalias.1.html">postalias(1)</a> "database full" 256errors. </strong></p> 257 258<dl> 259 260<dt> Problem: </dt> <dd> <p> The "postmap <a href="lmdb_table.5.html">lmdb</a>:filename" command 261fails with an MDB_TXN_FULL error. This problem does not exist with 262other Postfix databases. </p> </dd> 263 264<dt> Background: </dt> 265 266<dd> 267 268<p> The LMDB implementation has a hard limit on the total transaction 269size. This limit is independent of the LMDB database size. Therefore, 270the problem cannot be resolved by increasing the <a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a> 271value. </p> 272 273<p> This symptom is indicative of a flawed design. All LMDB data 274structures should share the same storage pool so that they can scale 275with the database size, and so that all "out of storage" errors are 276resolved by increasing the database size. </p> </dd> 277 278--> 279 280<!-- 281 282<p> Problem: </dt> <dd> <p> The "postmap <a href="lmdb_table.5.html">lmdb</a>:filename" command 283fails with an MDB_MAP_FULL error. This problem does not exist with 284other Postfix databases. </p> </dd> 285 286<dl> 287 288<dt> Background: </dt> 289 290<dd> 291 292<p> LMDB databases have a hard size limit (configured with the 293<a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a> configuration parameter). </p> 294 295<p> When executing "postmap <a href="lmdb_table.5.html">lmdb</a>:filename", the Postfix LMDB database 296client stores the new data in a transaction which takes up space 297in addition to the existing data, and commits the transaction when 298it closes the database. Only then can the space for old data be 299reused. </p> 300 301</dd> 302 303<dt> Impact: </dt> <dd> <p> This failure does not affect Postfix 304availability, because the old data still exists in the database. 305</p> </dd> 306 307<dt> Mitigation: </dt> <dd> 308 309<p> When the <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> command fails with an 310MDB_MAP_FULL error, it expands the database file size to the current 311LMDB map size limit before terminating. </p> 312 313<p> Next, when you re-run the <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> command, 314it discovers that the LMDB file is larger than <a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a>/3, 315logs a warning, and uses a larger LMDB map size limit instead: </p> 316 317<p> <tt> warning: <i>filename</i>.<a href="lmdb_table.5.html">lmdb</a>: file size 15024128 ≥ 318(lmdb map size limit 16777216)/3<br> warning: <i>filename</i>.<a href="lmdb_table.5.html">lmdb</a>: 319using map size limit 45072384</tt> </p> 320 321<p> By repeating the two steps above you can automate recovery and 322avoid the need for human intervention. Just repeat "postmap 323<a href="lmdb_table.5.html">lmdb</a>:filename" (up to some limit). After each failure it will use 324a 3x larger size limit, and eventually the "database full" error 325should disappear. This fails only when the disk is full or when 326the LMDB map size limit would exceed the memory address space size 327limit. </p> 328 329<dt> Prevention: </dt> <dd> <p> Monitor your LMDB files and make 330sure that in <a href="postconf.5.html">main.cf</a>, <a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a> > 3x the largest LMDB file 331size. </p> </dd> </dl> 332 333</dl> 334 335--> 336 337<!-- 338 339<p> <strong>Unexpected Postfix daemon "database full" errors. 340</strong></p> 341 342<dl> 343 344<dt> Problem: </dt> <dd> <p> Postfix daemon programs fail with 345"database full" errors, such as <a href="postscreen.8.html">postscreen(8)</a>, <a href="tlsmgr.8.html">tlsmgr(8)</a> or <a href="verify.8.html">verify(8)</a>. 346This problem does not exist with other Postfix databases. </p> 347</dd> 348 349<dt> Impact: </dt> <dd> <p> This failure temporarily affects Postfix 350availability. The daemon restarts automatically and tries to open 351the database again as described next. </p> </dd> 352 353<dt> Mitigation: </dt> <dd> <p> When a Postfix daemon opens an LMDB 354file larger than <a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a>/3, it logs a warning and uses a 355larger size limit instead: </p> 356 357<p> <tt> warning: <i>filename</i>.<a href="lmdb_table.5.html">lmdb</a>: file size 15024128 ≥ 358(lmdb map size limit 16777216)/3 <br>warning: <i>filename</i>.<a href="lmdb_table.5.html">lmdb</a>: 359using map size limit 45072384</tt> </p> 360 361<p> This can be used to automate recovery and avoid the need for 362human intervention. Each time the daemon runs into a "database full" 363error, it restarts and uses a 3x larger size limit. The "database 364full" error will disappear, at least for a while. </p> 365 366<dt> Prevention: </dt> <dd> <p> Monitor your LMDB files and make 367sure that <a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a> > 3x the largest LMDB file size. </p> 368</dd> </dl> 369 370--> 371 372<!-- 373 374<p> <strong>Non-obvious recovery with <a href="postmap.1.html">postmap(1)</a>, <a href="postalias.1.html">postalias(1)</a>, or 375<a href="tlsmgr.8.html">tlsmgr(8)</a> from a corrupted database. </strong></p> 376 377<dl> 378 379<dt> Problem: </dt> <dd> <p> A corrupted LMDB database can't be 380rebuilt simply by re-running <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a>, or by 381waiting until a <a href="tlsmgr.8.html">tlsmgr(8)</a> daemon restarts. This problem does not 382exist with other Postfix databases. </p> </dd> 383 384<dt> Background: </dt> <dd> <p> The Postfix LMDB database client 385does not truncate the database file. Instead it attempts to create 386a transaction for a "drop" request plus subsequent "store" requests. 387That is obviously not possible with a corrupted database file. </p> 388</dd> 389 390<dt> Impact: </dt> <dd> <p> Postfix does not process mail until 391someone fixes the problem. </p> </dd> 392 393<dt> Recovery: </dt> <dd> <p> First delete the ".lmdb" file by hand. 394Then rebuild the file with the <a href="postmap.1.html">postmap(1)</a> or <a href="postalias.1.html">postalias(1)</a> 395command if the file was created with those commands, or restart 396postfix daemons if the file is maintained by <a href="tlsmgr.8.html">tlsmgr(8)</a>. 397</p> </dd> 398 399<dt> Prevention: </dt> <dd> 400 401<p> Arrange your file systems such that they never run out of free 402space. </p> 403 404<p> Use ECC memory to detect and correct silent corruption of 405in-memory file system data and metadata. </p> 406 407<p> Use a file system such as ZFS to detect and correct silent 408corruption of on-disk file system data and metadata. DO NOT 409use ZFS on systems without ECC memory error correction. </p> 410 411</dd> </dl> 412 413--> 414 415</body> 416 417</html> 418