Merge remote-tracking branch 'origin/mdb.master'

This commit is contained in:
Howard Chu 2012-12-10 12:22:30 -08:00
commit 3bf87500a3
2 changed files with 39 additions and 17 deletions

View File

@ -1347,6 +1347,11 @@ none:
mdb_cursor_init(&m2, txn, FREE_DBI, NULL); mdb_cursor_init(&m2, txn, FREE_DBI, NULL);
do { do {
/* bail out if we're operating on the freelist.
* TODO: get all of this working. Many circular dependencies...
*/
if (mc->mc_dbi == FREE_DBI)
break;
if (readit) { if (readit) {
MDB_val key, data; MDB_val key, data;
MDB_oldpages *mop2; MDB_oldpages *mop2;
@ -2121,7 +2126,12 @@ mdb_txn_commit(MDB_txn *txn)
/* should only be one record now */ /* should only be one record now */
if (env->me_pghead) { if (env->me_pghead) {
/* make sure first page of freeDB is touched and on freelist */ /* make sure first page of freeDB is touched and on freelist */
mdb_page_search(&mc, NULL, MDB_PS_MODIFY); rc = mdb_page_search(&mc, NULL, MDB_PS_MODIFY);
if (rc) {
fail:
mdb_txn_abort(txn);
return rc;
}
} }
/* Delete IDLs we used from the free list */ /* Delete IDLs we used from the free list */
@ -2136,10 +2146,8 @@ mdb_txn_commit(MDB_txn *txn)
mdb_cursor_set(&mc, &key, NULL, MDB_SET, &exact); mdb_cursor_set(&mc, &key, NULL, MDB_SET, &exact);
rc = mdb_cursor_del(&mc, 0); rc = mdb_cursor_del(&mc, 0);
if (rc) { if (rc)
mdb_txn_abort(txn); goto fail;
return rc;
}
} }
env->me_pgfirst = 0; env->me_pgfirst = 0;
env->me_pglast = 0; env->me_pglast = 0;
@ -2154,7 +2162,9 @@ free2:
/* make sure last page of freeDB is touched and on freelist */ /* make sure last page of freeDB is touched and on freelist */
key.mv_size = MAXKEYSIZE+1; key.mv_size = MAXKEYSIZE+1;
key.mv_data = NULL; key.mv_data = NULL;
mdb_page_search(&mc, &key, MDB_PS_MODIFY); rc = mdb_page_search(&mc, &key, MDB_PS_MODIFY);
if (rc)
goto fail;
#if MDB_DEBUG > 1 #if MDB_DEBUG > 1
{ {
@ -2181,10 +2191,8 @@ free2:
data.mv_size = MDB_IDL_SIZEOF(txn->mt_free_pgs); data.mv_size = MDB_IDL_SIZEOF(txn->mt_free_pgs);
mdb_midl_sort(txn->mt_free_pgs); mdb_midl_sort(txn->mt_free_pgs);
rc = mdb_cursor_put(&mc, &key, &data, 0); rc = mdb_cursor_put(&mc, &key, &data, 0);
if (rc) { if (rc)
mdb_txn_abort(txn); goto fail;
return rc;
}
} while (freecnt != txn->mt_free_pgs[0]); } while (freecnt != txn->mt_free_pgs[0]);
} }
/* should only be one record now */ /* should only be one record now */
@ -2205,18 +2213,24 @@ again:
/* These steps may grow the freelist again /* These steps may grow the freelist again
* due to freed overflow pages... * due to freed overflow pages...
*/ */
mdb_cursor_put(&mc, &key, &data, 0); rc = mdb_cursor_put(&mc, &key, &data, 0);
if (rc)
goto fail;
if (mop == env->me_pghead && env->me_pghead->mo_txnid == id) { if (mop == env->me_pghead && env->me_pghead->mo_txnid == id) {
/* could have been used again here */ /* could have been used again here */
if (mop->mo_pages[0] != orig) { if (mop->mo_pages[0] != orig) {
data.mv_size = MDB_IDL_SIZEOF(mop->mo_pages); data.mv_size = MDB_IDL_SIZEOF(mop->mo_pages);
data.mv_data = mop->mo_pages; data.mv_data = mop->mo_pages;
id = mop->mo_txnid; id = mop->mo_txnid;
mdb_cursor_put(&mc, &key, &data, 0); rc = mdb_cursor_put(&mc, &key, &data, 0);
if (rc)
goto fail;
} }
} else { } else {
/* was completely used up */ /* was completely used up */
mdb_cursor_del(&mc, 0); rc = mdb_cursor_del(&mc, 0);
if (rc)
goto fail;
if (env->me_pghead) if (env->me_pghead)
goto again; goto again;
} }

View File

@ -31,7 +31,7 @@ static void prstat(MDB_stat *ms)
static void usage(char *prog) static void usage(char *prog)
{ {
fprintf(stderr, "usage: %s dbpath [-e] [-f] [-n] [-a|-s subdb]\n", prog); fprintf(stderr, "usage: %s dbpath [-e] [-f[f]] [-n] [-a|-s subdb]\n", prog);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -122,7 +122,7 @@ int main(int argc, char *argv[])
if (freinfo) { if (freinfo) {
MDB_cursor *cursor; MDB_cursor *cursor;
MDB_val data; MDB_val key, data;
size_t pages = 0, *iptr; size_t pages = 0, *iptr;
printf("Freelist Status\n"); printf("Freelist Status\n");
@ -137,12 +137,20 @@ int main(int argc, char *argv[])
printf("mdb_stat failed, error %d %s\n", rc, mdb_strerror(rc)); printf("mdb_stat failed, error %d %s\n", rc, mdb_strerror(rc));
goto txn_abort; goto txn_abort;
} }
while ((rc = mdb_cursor_get(cursor, NULL, &data, MDB_NEXT)) == 0) { prstat(&mst);
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
iptr = data.mv_data; iptr = data.mv_data;
pages += *iptr; pages += *iptr;
if (freinfo > 1) {
size_t i, j;
j = *iptr++;
printf(" Transaction %zu, %zu pages\n",
*(size_t *)key.mv_data, j);
for (i=0; i<j; i++)
printf(" %zu\n", iptr[i]);
}
} }
mdb_cursor_close(cursor); mdb_cursor_close(cursor);
prstat(&mst);
printf(" Free pages: %zu\n", pages); printf(" Free pages: %zu\n", pages);
} }