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).
vmware
Hallvard Furuseth 12 years ago
parent f19655eabc
commit 4b67270374
  1. 16
      libraries/liblmdb/mdb.c

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

Loading…
Cancel
Save