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