Issue 7943 - LMDB fails to process transactions after map resize
Summary: LMDB fails to process transactions after map resize
Status: VERIFIED FIXED
Alias: None
Product: LMDB
Classification: Unclassified
Component: liblmdb (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-09-19 00:29 UTC by carlopires@gmail.com
Modified: 2020-03-12 15:54 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 carlopires@gmail.com 2014-09-19 00:29:52 UTC
Full_Name: Carlo Pires
Version: LMDB 0.9.14
OS: Ubuntu Linux 14.04 LTS
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (177.53.184.142)


LMDB 0.9.14 is refusing to process new transactions after map resize. The
following test case shows the error:

/* mtest7.c - memory-mapped database tester/toy */
/* Tests for DB map resize */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "lmdb.h"

#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
#define EX(err, expr) CHECK((rc = (expr)) == (err), #expr)
#define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0))
#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
	"%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))

int main(int argc,char * argv[])
{
	int rc;
	MDB_env *env;
	MDB_dbi dbi;
	MDB_val key, data;
	MDB_txn *txn;
	MDB_envinfo minfo;

	char kval[32];
	char* sval = calloc(1, 8*1024*1024);
	assert(sval);

	// create database
	E(mdb_env_create(&env));
	E(mdb_env_set_mapsize(env, 10*1024*1024));
	E(mdb_env_set_maxdbs(env, 0));
	E(mdb_env_open(env, "./testdb", MDB_NORDAHEAD|MDB_NOLOCK|MDB_NOSYNC, 0664));

	// starts dbi
	E(mdb_txn_begin(env, NULL, 0, &txn));
	E(mdb_open(txn, NULL, MDB_CREATE, &dbi));
	E(mdb_txn_commit(txn));

	// check database mapsize
	E(mdb_env_info(env, &minfo));
	printf("map size is %ldMB\n%, C minfo.me_mapsize/1048576);

	// try to insert data
	E(mdb_txn_begin(env, NULL, 0, &txn));

	key.mv_size = sizeof(kval);
	key.mv_data = &kval;
	data.mv_size = 8*1024*1024;
	data.mv_data = sval;

	sprintf(kval, "0");
	E(mdb_put(txn, dbi, %kekey, &data, 0));

	sprintf(kval, "1");
	EX(MDB_MAP_FULL, mdb_put(txn, dbi, &key, &data, 0));

	// abort transaction and increase map size
	mdb_txn_abort(txn);
	mdb_env_set_mapsize(env, 20*1024*1024);

	// check database mapsize
	E(mdb_env_info(env, &minfo));
	printf("new map size is %ldMB\n", minfo.me_mapsize/1048576);

	// try to insert data again
	E(mdb_txn_begin(env, NULL, 0, &txn));

	sprintf(kval, "0");
	E(mdb_put(txn, dbi, &key, &data, 0));

	sprintf(kval, "1");
	E(mdb_put(txn, dbi, &key, &data, 0));

	E(mdb_txn_commit(txn));
	mdb_env_close(env);

	free(sval);
	return 0;
}

The code worked fine until LMDB 0.9.13. 
Comment 1 carlopires@gmail.com 2014-09-19 00:40:17 UTC
I forgot to attach the error message. Here is it:

$ ./mtest7
map size is 10MB
new map size is 20MB
mtest7.c:69: mdb_put(txn, dbi, &key, &data, 0): MDB_BAD_TXN: Transaction
cannot recover - it must be aborted
Abortado (imagem do núcleo gravada)


2014-09-18 21:29 GMT-03:00 <openldap-its@openldap.org>:

>
> *** THIS IS AN AUTOMATICALLY GENERATED REPLY ***
>
> Thanks for your report to the OpenLDAP Issue Tracking System.  Your
> report has been assigned the tracking number ITS#7943.
>
> One of our support engineers will look at your report in due course.
> Note that this may take some time because our support engineers
> are volunteers.  They only work on OpenLDAP when they have spare
> time.
>
> If you need to provide additional information in regards to your
> issue report, you may do so by replying to this message.  Note that
> any mail sent to openldap-its@openldap.org with (ITS#7943)
> in the subject will automatically be attached to the issue report.
>
>         mailto:openldap-its@openldap.org?subject=(ITS#7943)
>
> You may follow the progress of this report by loading the following
> URL in a web browser:
>     http://www.OpenLDAP.org/its/index.cgi?findid=7943
>
> Please remember to retain your issue tracking number (ITS#7943)
> on any further messages you send to us regarding this report.  If
> you don't then you'll just waste our time and yours because we
> won't be able to properly track the report.
>
> Please note that the Issue Tracking System is not intended to
> be used to seek help in the proper use of OpenLDAP Software.
> Such requests will be closed.
>
> OpenLDAP Software is user supported.
>         http://www.OpenLDAP.org/support/
>
> --------------
> Copyright 1998-2007 The OpenLDAP Foundation, All Rights Reserved.
>
>


-- 
  Carlo Pires
Comment 2 Howard Chu 2014-09-19 00:47:02 UTC
carlopires@gmail.com wrote:
> Full_Name: Carlo Pires
> Version: LMDB 0.9.14
> OS: Ubuntu Linux 14.04 LTS
> URL: ftp://ftp.openldap.org/incoming/
> Submission from: (NULL) (177.53.184.142)
>
>
> LMDB 0.9.14 is refusing to process new transactions after map resize. The
> following test case shows the error:

Thanks for the report, fixed in mdb.master.

> /* mtest7.c - memory-mapped database tester/toy */
> /* Tests for DB map resize */
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <assert.h>
> #include "lmdb.h"
>
> #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
> #define EX(err, expr) CHECK((rc = (expr)) == (err), #expr)
> #define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0))
> #define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
> 	"%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))
>
> int main(int argc,char * argv[])
> {
> 	int rc;
> 	MDB_env *env;
> 	MDB_dbi dbi;
> 	MDB_val key, data;
> 	MDB_txn *txn;
> 	MDB_envinfo minfo;
>
> 	char kval[32];
> 	char* sval = calloc(1, 8*1024*1024);
> 	assert(sval);
>
> 	// create database
> 	E(mdb_env_create(&env));
> 	E(mdb_env_set_mapsize(env, 10*1024*1024));
> 	E(mdb_env_set_maxdbs(env, 0));
> 	E(mdb_env_open(env, "./testdb", MDB_NORDAHEAD|MDB_NOLOCK|MDB_NOSYNC, 0664));
>
> 	// starts dbi
> 	E(mdb_txn_begin(env, NULL, 0, &txn));
> 	E(mdb_open(txn, NULL, MDB_CREATE, &dbi));
> 	E(mdb_txn_commit(txn));
>
> 	// check database mapsize
> 	E(mdb_env_info(env, &minfo));
> 	printf("map size is %ldMB\n%, C minfo.me_mapsize/1048576);
>
> 	// try to insert data
> 	E(mdb_txn_begin(env, NULL, 0, &txn));
>
> 	key.mv_size = sizeof(kval);
> 	key.mv_data = &kval;
> 	data.mv_size = 8*1024*1024;
> 	data.mv_data = sval;
>
> 	sprintf(kval, "0");
> 	E(mdb_put(txn, dbi, %kekey, &data, 0));
>
> 	sprintf(kval, "1");
> 	EX(MDB_MAP_FULL, mdb_put(txn, dbi, &key, &data, 0));
>
> 	// abort transaction and increase map size
> 	mdb_txn_abort(txn);
> 	mdb_env_set_mapsize(env, 20*1024*1024);
>
> 	// check database mapsize
> 	E(mdb_env_info(env, &minfo));
> 	printf("new map size is %ldMB\n", minfo.me_mapsize/1048576);
>
> 	// try to insert data again
> 	E(mdb_txn_begin(env, NULL, 0, &txn));
>
> 	sprintf(kval, "0");
> 	E(mdb_put(txn, dbi, &key, &data, 0));
>
> 	sprintf(kval, "1");
> 	E(mdb_put(txn, dbi, &key, &data, 0));
>
> 	E(mdb_txn_commit(txn));
> 	mdb_env_close(env);
>
> 	free(sval);
> 	return 0;
> }
>
> The code worked fine until LMDB 0.9.13.
>
>


-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

Comment 3 Howard Chu 2014-09-19 00:58:11 UTC
changed notes
changed state Open to Test
moved from Incoming to Software Bugs
Comment 4 OpenLDAP project 2014-12-11 01:03:48 UTC
fixed in mdb.master
Comment 5 Quanah Gibson-Mount 2014-12-11 01:03:48 UTC
changed notes
changed state Test to Closed