Fix page spilling when MDB_WRITEMAP.

mdb_page_spill(): Don't binary-search the unsorted dirty_list.
mdb_page_flush(): Don't overwrite unprocessed dirty_list items.
vmware
Hallvard Furuseth 11 years ago
parent ee5ba85565
commit c3547e81f3
  1. 14
      libraries/liblmdb/mdb.c

@ -1434,7 +1434,7 @@ mdb_page_spill(MDB_cursor *m0, MDB_val *key, MDB_val *data)
MDB_page *dp; MDB_page *dp;
MDB_ID2L dl = txn->mt_u.dirty_list; MDB_ID2L dl = txn->mt_u.dirty_list;
unsigned int i, j; unsigned int i, j;
int rc; int rc, level;
if (m0->mc_flags & C_SUB) if (m0->mc_flags & C_SUB)
return MDB_SUCCESS; return MDB_SUCCESS;
@ -1461,13 +1461,15 @@ mdb_page_spill(MDB_cursor *m0, MDB_val *key, MDB_val *data)
/* Mark all the dirty root pages we want to preserve */ /* Mark all the dirty root pages we want to preserve */
for (i=0; i<txn->mt_numdbs; i++) { for (i=0; i<txn->mt_numdbs; i++) {
if (txn->mt_dbflags[i] & DB_DIRTY) { if (txn->mt_dbflags[i] & DB_DIRTY) {
j = mdb_mid2l_search(dl, txn->mt_dbs[i].md_root); pgno_t pgno = txn->mt_dbs[i].md_root;
if (j <= dl[0].mid) { if (pgno == P_INVALID)
dp = dl[j].mptr; continue;
if ((rc = mdb_page_get(txn, pgno, &dp, &level)) != MDB_SUCCESS)
goto done;
if ((dp->mp_flags & P_DIRTY) && level <= 1)
dp->mp_flags |= P_KEEP; dp->mp_flags |= P_KEEP;
} }
} }
}
/* Preserve pages used by cursors */ /* Preserve pages used by cursors */
mdb_cursorpages_mark(m0, P_DIRTY); mdb_cursorpages_mark(m0, P_DIRTY);
@ -2592,7 +2594,7 @@ mdb_page_flush(MDB_txn *txn)
j = 0; j = 0;
if (env->me_flags & MDB_WRITEMAP) { if (env->me_flags & MDB_WRITEMAP) {
/* Clear dirty flags */ /* Clear dirty flags */
for (i = pagecount; i; i--) { for (i=1; i<=pagecount; i++) {
dp = dl[i].mptr; dp = dl[i].mptr;
/* Don't flush this page yet */ /* Don't flush this page yet */
if (dp->mp_flags & P_KEEP) { if (dp->mp_flags & P_KEEP) {

Loading…
Cancel
Save