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