diff --git a/postfix/HISTORY b/postfix/HISTORY index 1f3a451f6..4041b6f83 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -18256,12 +18256,31 @@ Apologies for any names omitted. 20130315 - Feature: preliminary LMDB (memory-mapped persistent file) - support by Howard Chu. This feature has unexpected limitations - that don't exist with other Postfix databases, and is - therefore "snapshot only", i.e. it will not be part of a - stable release without further changes to the Postfix LMDB - client or the Postfix dictionary API. Files: proto/postconf.proto, - proto/LMDB_README.html, proto/DATABASE_README.html, - proto/INSTALL.html util/dict_lmdb.[hc], util/dict_open.c, - global/mkmap_lmdb.[hc], global/mkmap_open.c, postconf/postconf.c. + Feature: LMDB (memory-mapped persistent file) support by + Howard Chu. This implementation has unexpected failure modes + that don't exist with other Postfix databases, so don't + just yet abandon CDB. See LMDB_README for details. Files: + proto/postconf.proto, proto/LMDB_README.html, + proto/DATABASE_README.html, proto/INSTALL.html util/dict_lmdb.[hc], + util/dict_open.c, global/mkmap_lmdb.[hc], global/mkmap_open.c, + postconf/postconf.c. + +20130316 + + Cleanup: new Postfix dictionary API flag to control the use + of (LMDB) bulk database transactions. With this, LMDB + databases no longer fail to commit any transactions with + tlsmgr(8), and LMDB databases no longer perform glacially + slow with postmap -i/postalias -i. Files: util/dict.h, + util/dict_lmdb.c, postmap/postmap.c, postalias/postalias.c. + +20130317 + + Debugging: generalized setting of dictionary API flags. + File: util/dict.[hc], util/dict_test.c. + + Robustness: Postfix programs can now recover from LMDB + "database full" errors without requiring human intervention. + When a program opens an LMDB file larger than lmdb_map_size/3, + it logs a warning and uses a larger size limit instead. + Files: util/dict_lmdb.c, proto/LMDB_README.html. diff --git a/postfix/README_FILES/LMDB_README b/postfix/README_FILES/LMDB_README index dfd131373..e39d2777d 100644 --- a/postfix/README_FILES/LMDB_README +++ b/postfix/README_FILES/LMDB_README @@ -18,11 +18,9 @@ This document describes: 3. Missing pthread library trouble. -Caution: - The current Postfix LMDB client has unexpected limitations that don't exist - with other Postfix databases. For this reason, LMDB support will not be - part of the stable Postfix release without further changes to the Postfix - LMDB client or the Postfix dictionary API. +Note: + The Postfix LMDB client implementation introduces unexpected failure modes + that don't exist with other Postfix databases. Don't just yet abandon CDB. BBuuiillddiinngg PPoossttffiixx wwiitthh OOppeennLLDDAAPP LLMMDDBB ssuuppppoorrtt @@ -65,92 +63,95 @@ Add the "-lpthread" library to the "make makefiles" command. Source code for OpenLDAP LMDB is available at http://www.openldap.org. More information is available at http://highlandsun.com/hyc/mdb/. -LLiimmiittaattiioonnss ooff PPoossttffiixx LLMMDDBB ddaattaabbaasseess.. +UUnneexxppeecctteedd ffaaiilluurree mmooddeess ooff PPoossttffiixx LLMMDDBB ddaattaabbaasseess.. + +As documented below, conversion to LMDB introduces a number of failure modes +that don't exist with other Postfix databases. UUnneexxppeecctteedd ppoossttmmaapp((11))//ppoossttaalliiaass((11)) ""ddaattaabbaassee ffuullll"" eerrrroorrss.. Problem: - Even if the "postmap lmdb:filename" command succeeds, the exact same - command (with the exact same input data) may fail subsequently with an - MDB_MAP_FULL error. This problem does not exist with other Postfix - databases. + The "postmap lmdb:filename" command fails with an MDB_MAP_FULL error. This + problem does not exist with other Postfix databases. Background: LMDB databases have a hard size limit (configured with the lmdb_map_size configuration parameter). When executing "postmap lmdb:filename", the Postfix LMDB database client - does not truncate the database file. Instead it saves the "drop" request - and subsequent "store" requests to a transaction (which takes up space in - addition to the existing data), and commits the transaction when it closes - the database. Only then can the space for old data be reused. + stores the new data in a transaction which takes up space in addition to + the existing data, and commits the transaction when it closes the database. + Only then can the space for old data be reused. Impact: This failure does not affect Postfix availability, because the old data still exists in the database. -Recovery: - Increase the lmdb_map_size limit in main.cf, and retry the postmap(1) or - postalias(1) command. +Mitigation: + When the postmap(1) or postalias(1) command opens an LMDB file larger than + lmdb_map_size/3, it logs a warning and uses a larger size limit instead: -PPoossttffiixx ddaaeemmoonn ""ddaattaabbaassee ffuullll"" eerrrroorrss.. + warning: filename.lmdb: file size 15024128 >= (lmdb map size limit + 16777216)/3 -- using a larger map size limit + + This can be used to automate recovery and avoid the need for human + intervention. Just keep running "postmap lmdb:filename". After each failure + it will use a 3x larger size limit, and eventually the "database full" + error will disappear. + +Prevention: + Monitor your LMDB files and make sure that lmdb_map_size > 3x the largest + LMDB file size. + +UUnneexxppeecctteedd PPoossttffiixx ddaaeemmoonn ""ddaattaabbaassee ffuullll"" eerrrroorrss.. Problem: - "database full" errors with daemon programs such as postscreen(8), tlsmgr - (8) or verify(8). This problem does not exist with other Postfix databases. + Postfix daemon programs fail with "database full" errors, such as + postscreen(8), tlsmgr(8) or verify(8). This problem does not exist with + other Postfix databases. + +Impact: + This failure temporarily affects Postfix availability. The daemon restarts + automatically and tries to open the database again as described next. + +Mitigation: + When a Postfix daemon opens an LMDB file larger than lmdb_map_size/3, it + logs a warning and uses a larger size limit instead: + + warning: filename.lmdb: file size 15024128 >= (lmdb map size limit + 16777216)/3 -- using a larger map size limit + + This can be used to automate recovery and avoid the need for human + intervention. Each time the daemon runs into a "database full" error, it + restarts and uses a 3x larger size limit. The "database full" error will + disappear, at least for a while. + +Prevention: + Monitor your LMDB files and make sure that lmdb_map_size > 3x the largest + LMDB file size. + +NNoonn--oobbvviioouuss rreeccoovveerryy wwiitthh ppoossttmmaapp((11))//ppoossttaalliiaass((11))//ttllssmmggrr((88)) ffrroomm aa ccoorrrruupptteedd +ddaattaabbaassee.. + +Problem: + You cannot rebuild a corrupted LMDB database simply by running postmap(1) + or postalias(1), or by waiting until the tlsmgr(8) daemon restarts + automatically. This problem does not exist with other Postfix databases. + +Background: + The Postfix LMDB database client does not truncate the database file. + Instead it attempts to create a transaction for a "drop" request and + subsequent "store" requests. That is obviously not possible with a + corrupted database file. Impact: Postfix does not process mail until someone fixes the problem. -Recovery: - Increase the lmdb_map_size limit in main.cf, and "reload" Postfix. - -NNoonn--oobbvviioouuss rreeccoovveerryy wwiitthh ppoossttmmaapp((11))//ppoossttaalliiaass((11)) ffrroomm aa ccoorrrruupptteedd ddaattaabbaassee.. - -Problem: - You cannot rebuild a corrupted LMDB database simply by running postmap(1) - or postalias(1). This problem does not exist with other Postfix databases. - -Background: - The reason for this limitation is that the Postfix LMDB database client - does not truncate the database file. Instead it attempts to save the "drop" - request and subsequent "store" requests to a transaction for later - processing. That is obviously not possible with a corrupted database file. - Recovery: First delete the ".lmdb" file by hand, then rebuild the file with the - postmap(1) or postalias(1) command. + postmap(1) or postalias(1) command, or wait until the tlsmgr(8) daemon + restarts automatically. -IInnccoommppaattiibbiilliittyy wwiitthh ttllssmmggrr((88)).. - -Problem: - The Postfix LMDB database client never commits any tlsmgr(8) transaction. - This problem does not exist with other Postfix databases. - -Background: - Instead, it creates a single transaction that accumulates a "drop" request - and all tlsmgr(8) "store" requests that are made during the lifetime of the - process. - -Solution: - This requires changes to the Postfix dictionary API, or to the Postfix LMDB - database client. - -Problem: - The Postfix LMDB database client breaks how tlsmgr(8) automatically - recovers from a corrupted database file. This problem does not exist with - other Postfix databases. - -Background: - The Postfix LMDB database client does not truncate the database file. - Instead it attempts to create a transaction which obviously is not possible - when the database file is corrupted. - -Impact: - The tlsmgr(8) process will keep crashing until someone removes the ".lmdb" - file. - -Recovery: - Remove the the ".lmdb" file by hand, and wait until the tlsmgr(8) process - restarts. +Prevention: + Arrange your file systems such that they never run out of free space. diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index 64fee86b6..ef167571b 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -17,8 +17,6 @@ before proceeding. Major changes with snapshot 20130315 ==================================== -Preliminary LMDB support by Howard Chu. This implementation has -unexpected limitations that don't exist with other Postfix databases, -and therefore the code is "snapshot only", i.e. it will not be part -of the stable release without further changes to the Postfix LMDB -client or the Postfix dictionary API. See LMDB_README for details. +LMDB support by Howard Chu. This implementation has unexpected +failure modes that don't exist with other Postfix databases, so +don't just yet abandon CDB. See LMDB_README for details. diff --git a/postfix/html/LMDB_README.html b/postfix/html/LMDB_README.html index e6f1bb984..4b3368145 100644 --- a/postfix/html/LMDB_README.html +++ b/postfix/html/LMDB_README.html @@ -39,12 +39,10 @@ LMDB support.
-The current Postfix LMDB client -has unexpected limitations that don't -exist with other Postfix databases. For this reason, LMDB support -will not be part of the stable Postfix release without further -changes to the Postfix LMDB client or the Postfix dictionary API. -
The Postfix LMDB client implementation +introduces unexpected failure modes that +don't exist with other Postfix databases. Don't just yet abandon +CDB.
Unexpected postmap(1)/postalias(1) "database full" errors. -
+As documented below, conversion to LMDB introduces a number of +failure modes that don't exist with other Postfix databases.
+ +Unexpected postmap(1)/postalias(1) "database full" +errors.
Even if the "postmap lmdb:filename" -command succeeds, the exact same command (with the exact same input -data) may fail subsequently with an MDB_MAP_FULL error. This problem -does not exist with other Postfix databases.
The "postmap lmdb:filename" command +fails with an MDB_MAP_FULL error. This problem does not exist with +other Postfix databases.
LMDB databases have a hard size limit (configured with the lmdb_map_size configuration parameter).
When executing "postmap lmdb:filename", the Postfix LMDB database -client does not truncate the database file. Instead it saves the -"drop" request and subsequent "store" requests to a transaction -(which takes up space in addition to the existing data), and commits -the transaction when it closes the database. Only then can the -space for old data be reused.
+client stores the new data in a transaction which takes up space +in addition to the existing data, and commits the transaction when +it closes the database. Only then can the space for old data be +reused.Increase the lmdb_map_size limit in -main.cf, and retry the postmap(1) or postalias(1) command.
-When the postmap(1) or postalias(1) +command opens an LMDB file larger than lmdb_map_size/3, it logs a +warning and uses a larger size limit instead:
-warning: filename.lmdb: file size 15024128 ≥ +(lmdb map size limit 16777216)/3 -- using a larger map size limit +
-Postfix daemon "database full" errors.
+This can be used to automate recovery and avoid the need for +human intervention. Just keep running "postmap lmdb:filename". +After each failure it will use a 3x larger size limit, and eventually +the "database full" error will disappear.
+ +Monitor your LMDB files and make +sure that lmdb_map_size > 3x the largest LMDB file size.
+Unexpected Postfix daemon "database full" errors. +
"database full" errors with daemon -programs such as postscreen(8), tlsmgr(8) or verify(8). This problem -does not exist with other Postfix databases.
Postfix daemon programs fail with +"database full" errors, such as postscreen(8), tlsmgr(8) or verify(8). +This problem does not exist with other Postfix databases.
+Postfix does not process mail until -someone fixes the problem.
This failure temporarily affects Postfix +availability. The daemon restarts automatically and tries to open +the database again as described next.
Increase the lmdb_map_size limit in -main.cf, and "reload" Postfix.
When a Postfix daemon opens an LMDB +file larger than lmdb_map_size/3, it logs a warning and uses a +larger size limit instead:
+ +warning: filename.lmdb: file size 15024128 ≥ +(lmdb map size limit 16777216)/3 -- using a larger map size limit +
+ +This can be used to automate recovery and avoid the need for +human intervention. Each time the daemon runs into a "database full" +error, it restarts and uses a 3x larger size limit. The "database +full" error will disappear, at least for a while.
+ +Monitor your LMDB files and make +sure that lmdb_map_size > 3x the largest LMDB file size.
+ Non-obvious recovery with postmap(1)/postalias(1)
+ Non-obvious recovery with postmap(1)/postalias(1)/tlsmgr(8)
from a corrupted database. You cannot rebuild a corrupted LMDB
-database simply by running postmap(1) or postalias(1). This problem
+database simply by running postmap(1) or postalias(1), or by waiting
+until the tlsmgr(8) daemon restarts automatically. This problem
does not exist with other Postfix databases. The reason for this limitation is
-that the Postfix LMDB database client does not truncate the database
-file. Instead it attempts to save the "drop" request and subsequent
-"store" requests to a transaction for later processing. That is
-obviously not possible with a corrupted database file. First delete the ".lmdb" file by hand,
-then rebuild the file with the postmap(1) or postalias(1) command.
- Incompatibility with tlsmgr(8). The Postfix LMDB database client never
-commits any tlsmgr(8) transaction. This problem does not exist with
-other Postfix databases. Instead, it creates a single
-transaction that accumulates a "drop" request and all tlsmgr(8)
-"store" requests that are made during the lifetime of the process.
- This requires changes to the Postfix
-dictionary API, or to the Postfix LMDB database client. The Postfix LMDB database client breaks
-how tlsmgr(8) automatically recovers from a corrupted database file.
-This problem does not exist with other Postfix databases. The Postfix LMDB database client
does not truncate the database file. Instead it attempts to create
-a transaction which obviously is not possible when the database
-file is corrupted.
-
-
-
-
The tlsmgr(8) process will keep crashing -until someone removes the ".lmdb" file.
Postfix does not process mail until +someone fixes the problem.
Remove the the ".lmdb" file by hand, -and wait until the tlsmgr(8) process restarts.
First delete the ".lmdb" file by hand, +then rebuild the file with the postmap(1) or postalias(1) command, +or wait until the tlsmgr(8) daemon restarts automatically.
+Arrange your file systems such that +they never run out of free space.