Re: [heads up] lmdb 1.0 Edmund Lodewijks via Postfix-users Sun, 05 Jul 2026 06:58:48 -0700 On 2026/07/05 13:19, Wietse Venema via Postfix-users wrote: Michael Grimm via Postfix-users: Well, I will stick with lmdb 0.9.35 for the time being or migrate to other database formats, instead. Way to go if you have that option. I can see two ways to patch for this in Postfix: 1) Instead of dropping the table, walk a cursor and delete each record in place. This is much more expensive than the current method, but I think it the cost will still be negligible. The most expensive transaction is when you run postmap/ postalias. The nice thing about this is that it seems to me to be the least invasive patch, with as little change as possible. Most of the current structure stays the same. Importantly, atomicity is retained in the same way that it currently exists. This is also compatible with lmdb 0.9.x. An example patch is attached (not sure if the mailing list allows attachments). 2) Alternatively, create a new table in a temp file + rename. There would be more code involved for this, and a temp file (if you want to do this securely, and not with a predictable name) introduces all kinds of file permissions things to take care off across multiple OS's. This, too, is compatible with lmdb 0.9.x. I hope this is useful. Kind regards, Edmund -- Edmund Lodewijks TZ: UTC+2 / GMT+2 diff --git a/postfix/src/util/slmdb.c b/postfix/src/util/slmdb.c index 3f795631..79b5d5b5 100644 --- a/postfix/src/util/slmdb.c +++ b/postfix/src/util/slmdb.c @@ -391,12 +391,35 @@ static int slmdb_prepare(SLMDB *slmdb) * aborts commits a transaction, it must set slmdb->txn to null to avoid * a use-after-free error in slmdb_close(). * - * - With O_TRUNC we make a "drop" request before updating the database. - * + * - With O_TRUNC we empty the database before updating it. We cannot use + * mdb_drop() for this: as of LMDB 1.0 (ITS#8174) mdb_drop() on the default + * database marks its transaction dropped/dirty, so the transaction can no + * longer be reused for the bulk-mode mdb_put() calls that follow, and + * committing all updates as one atomic transaction is exactly what we need. + * Instead we empty the database with an in-transaction cursor delete-all, + * which leaves the transaction usable and preserves the single-commit + * atomicity model. + * * - With a bulk-mode transaction we commit when the database is closed. */ if (slmdb->open_flags & O_TRUNC) { - if ((status = mdb_drop(slmdb->txn, slmdb->dbi, 0)) != 0) { + MDB_cursor *cursor; + MDB_val cursor_key; + MDB_val cursor_val; + + if ((status = mdb_cursor_open(slmdb->txn, slmdb->dbi, &cursor)) != 0) { + mdb_txn_abort(slmdb->txn); + slmdb->txn = 0; + return (status); + } + while ((status = mdb_cursor_get(cursor, &cursor_key, &cursor_val, + MDB_NEXT)) == 0) + if ((status = mdb_cursor_del(cursor, 0)) != 0) + break; + mdb_cursor_close(cursor); + if (status == MDB_NOTFOUND) /* emptied to end-of-db */ + status = 0; + if (status != 0) { mdb_txn_abort(slmdb->txn); slmdb->txn = 0; return (status); _______________________________________________ Postfix-users mailing list -- postfix-users@postfix.org To unsubscribe send an email to postfix-users-le...@postfix.org