Issue 7512 - MDB page leaks
Summary: MDB page leaks
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: slapd (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-01-30 13:56 UTC by Hallvard Furuseth
Modified: 2014-08-01 21:04 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Hallvard Furuseth 2013-01-30 13:56:24 UTC
Full_Name: Hallvard B Furuseth
Version: mdb.master 27aaecc744955d08d2bfe7a3ca786d742267c5bd
OS: Linux x86_64
URL: 
Submission from: (NULL) (193.69.163.163)
Submitted by: hallvard


If the malloc at mdb_page_malloc() line 1348 fails, me_pgfirst
has already been incremented and those pages can be lost.

I'll fix that one.  Not this, however:

If a child transaction aborts, it loses pages it used up: It does
not give them back to me_pghead, nor to the parent's mt_free_pgs.
It does not rewind me_pgfirst/me_last to their state at txn_begin.

This program illustrates.  The DB grows to 107 pages.  mdb_stat
can see 10 of them, same as if everything was done in the main
txn.  MainDB will have max 1 entry while running.

#include <lmdb.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
	int rc, i;
	MDB_val key = { sizeof(i), &i }, data = { 0, "" };
	MDB_env *env;
	MDB_txn *txn, *ctxn;
	MDB_dbi dbi;
#	define dbname "test.mdb"
#	define E(e) { rc = (e); if (rc) { fprintf(stderr, "%d: %s: %s\n", \
		__LINE__, #e, mdb_strerror(rc)); return rc; } }
	E(mdb_env_create(&env));
	E(mdb_env_open(env, dbname, MDB_NOSYNC|MDB_NOSUBDIR, 0666));
	for (i = 0; i < 100; ) {
		E(mdb_txn_begin(env, NULL, 0, &txn));
		if (!i) {
			E(mdb_dbi_open(txn, NULL, MDB_CREATE, &dbi));
		} else {
			E(mdb_txn_begin(env, txn, 0, &ctxn));
			E(mdb_put(ctxn, dbi, &key, &data, 0));
			mdb_txn_abort(ctxn);
			E(mdb_del(txn, dbi, &key, NULL));
		}
		i++;
		E(mdb_put(txn, dbi, &key, &data, 0));
		E(mdb_txn_commit(txn));
		if (i % 20 == 0) system("du " dbname);
	}
	mdb_env_close(env);
	return 0;
}
Comment 1 Hallvard Furuseth 2013-02-07 10:23:39 UTC
changed notes
changed state Open to Test
moved from Incoming to Software Bugs
Comment 2 Hallvard Furuseth 2013-02-20 06:45:02 UTC
changed notes
Comment 3 Quanah Gibson-Mount 2013-02-26 20:17:53 UTC
changed notes
changed state Test to Release
Comment 4 Quanah Gibson-Mount 2013-03-05 02:26:22 UTC
changed notes
changed state Release to Closed
Comment 5 OpenLDAP project 2014-08-01 21:04:46 UTC
fixed in mdb.master.
fixed in master
fixed in RE24