xref: /netbsd-src/external/ibm-public/postfix/dist/proto/LMDB_README.html (revision 059c16a85b0b39d60ad6d18f53c09510815afa2b)
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    AUXLIBS_LMDB="-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 AUXLIBS_LMDB.
64With Postfix 3.0 and later, the old AUXLIBS variable still supports
65building a statically-loaded LMDB database client, but only the new
66AUXLIBS_LMDB variable supports building a dynamically-loaded or
67statically-loaded LMDB database client.  </p>
68
69<blockquote>
70
71<p> Failure to use the AUXLIBS_LMDB 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    AUXLIBS_LMDB="-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 .... AUXLIBS_LMDB="... -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> lmdb_map_size (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 lmdb_table(5) 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 postmap(1) and postalias(1) 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 cdb: to manage root-owned
218databases under the root-owned <tt>/etc</tt> or config_directory
219(default: <tt>/etc/postfix</tt>) such as access(5), virtual(5),
220transport(5). Support to create LMDB databases is available only
221for unprivileged Postfix daemon processes such as postscreen(8),
222tlsmgr(8) and verify(8) that manage postfix-owned databases under
223the postfix-owned data_directory (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 postmap(1)/postalias(1) "database full"
261errors.  </strong></p>
262
263<dl>
264
265<dt> Problem: </dt> <dd> <p> The "postmap lmdb: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 lmdb_map_size
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 lmdb: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
298lmdb_map_size configuration parameter). </p>
299
300<p> When executing "postmap lmdb: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 postmap(1) or postalias(1) 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 postmap(1) or postalias(1) command,
319it discovers that the LMDB file is larger than lmdb_map_size/3,
320logs a warning, and uses a larger LMDB map size limit instead: </p>
321
322<p> <tt> warning: <i>filename</i>.lmdb: file size 15024128 &ge;
323(lmdb map size limit 16777216)/3<br> warning: <i>filename</i>.lmdb:
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
328lmdb: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 main.cf, lmdb_map_size &gt; 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 postscreen(8), tlsmgr(8) or verify(8).
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 lmdb_map_size/3, it logs a warning and uses a
360larger size limit instead: </p>
361
362<p> <tt> warning: <i>filename</i>.lmdb: file size 15024128 &ge;
363(lmdb map size limit 16777216)/3 <br>warning: <i>filename</i>.lmdb:
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 lmdb_map_size &gt; 3x the largest LMDB file size. </p>
373</dd> </dl>
374
375-->
376
377<!--
378
379<p> <strong>Non-obvious recovery with postmap(1), postalias(1), or
380tlsmgr(8) 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 postmap(1) or postalias(1), or by
386waiting until a tlsmgr(8) 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 postmap(1) or postalias(1)
400command if the file was created with those commands, or restart
401postfix daemons if the file is maintained by tlsmgr(8).
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