mdb_page_alloc(): Handle freeDB txnid range holes.

A txn writes no freeDB entry if previous txn dropped mainDB and a read
txn prevents freelist entry reuse. This surprised mdb_page_alloc (and
mdb_txn_commit too before 65c053a6e7).
This commit is contained in:
Hallvard Furuseth 2013-02-19 21:17:33 +01:00
parent f19655eabc
commit 4b67270374

View File

@ -1294,14 +1294,12 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
last = *kptr;
} else {
MDB_val key;
int exact;
again:
exact = 0;
last = txn->mt_env->me_pglast + 1;
leaf = NULL;
key.mv_data = &last;
key.mv_size = sizeof(last);
rc = mdb_cursor_set(&m2, &key, &data, MDB_SET, &exact);
rc = mdb_cursor_set(&m2, &key, &data, MDB_SET_RANGE, NULL);
if (rc)
goto none;
last = *(txnid_t *)key.mv_data;
@ -1381,7 +1379,6 @@ none:
if (readit) {
MDB_val key, data;
pgno_t *idl, *mop2;
int exact;
last = txn->mt_env->me_pglast + 1;
@ -1406,12 +1403,17 @@ none:
if (oldest - last < 1)
break;
exact = 0;
key.mv_data = &last;
key.mv_size = sizeof(last);
rc = mdb_cursor_set(&m2, &key, &data, MDB_SET, &exact);
if (rc)
rc = mdb_cursor_set(&m2,&key,&data,MDB_SET_RANGE,NULL);
if (rc) {
if (rc == MDB_NOTFOUND)
break;
return rc;
}
last = *(txnid_t*)key.mv_data;
if (oldest <= last)
break;
idl = (MDB_ID *) data.mv_data;
mop2 = malloc(MDB_IDL_SIZEOF(idl) + MDB_IDL_SIZEOF(mop));
if (!mop2)