summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@mongodb.com>2015-10-30 22:18:27 +1100
committerMichael Cahill <michael.cahill@mongodb.com>2015-10-30 22:18:27 +1100
commitba931c1c64869b74c8699a6eb56c88b83521e9f4 (patch)
tree7d31149040ce964978feab60b726aecd1077beeb
parentfdfa804f85c19ce11ef94eded570c55c12918d41 (diff)
parent78f504e4f3f9393726f01019e1c6f939b72ff435 (diff)
downloadmongo-ba931c1c64869b74c8699a6eb56c88b83521e9f4.tar.gz
Merge pull request #2278 from wiredtiger/SERVER-21027-fix
SERVER-21027 Don't leave empty internal pages in the tree
-rw-r--r--src/btree/bt_split.c17
-rw-r--r--src/btree/bt_sync.c2
-rw-r--r--src/evict/evict_file.c13
-rw-r--r--src/evict/evict_page.c2
-rw-r--r--src/include/txn.i7
-rw-r--r--src/reconcile/rec_write.c1
6 files changed, 13 insertions, 29 deletions
diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c
index 8f24f44eaba..5baae4aaae3 100644
--- a/src/btree/bt_split.c
+++ b/src/btree/bt_split.c
@@ -1030,17 +1030,11 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref,
result_entries = (parent_entries + new_entries) - deleted_entries;
/*
- * If the entire (sub)tree is empty, leave the first ref in place,
- * deleted.
+ * If the entire (sub)tree is empty, give up: we can't leave an empty
+ * internal page.
*/
- if (result_entries == 0) {
- next_ref = pindex->index[0];
- WT_ASSERT(session, next_ref->state == WT_REF_SPLIT ||
- (next_ref == ref && ref->state == WT_REF_LOCKED));
- next_ref->state = WT_REF_DELETED;
- --deleted_entries;
- result_entries = 1;
- }
+ if (result_entries == 0)
+ return (0);
/*
* Allocate and initialize a new page index array for the parent, then
@@ -1086,6 +1080,9 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref,
*alloc_refp++ = next_ref;
}
+ /* Check that we filled in all the entries. */
+ WT_ASSERT(session, alloc_refp - alloc_index->index == result_entries);
+
/*
* Confirm the parent page's index hasn't moved then update it, which
* makes the split visible to threads descending the tree.
diff --git a/src/btree/bt_sync.c b/src/btree/bt_sync.c
index 2851c830bcb..237d900c3d1 100644
--- a/src/btree/bt_sync.c
+++ b/src/btree/bt_sync.c
@@ -152,8 +152,6 @@ __sync_file(WT_SESSION_IMPL *session, int syncop)
leaf_bytes += page->memory_footprint;
++leaf_pages;
}
- if (txn->isolation == WT_ISO_READ_COMMITTED)
- __wt_txn_get_snapshot(session);
WT_ERR(__wt_reconcile(session, walk, NULL, 0));
}
break;
diff --git a/src/evict/evict_file.c b/src/evict/evict_file.c
index b1e107657bf..448de57d88e 100644
--- a/src/evict/evict_file.c
+++ b/src/evict/evict_file.c
@@ -18,11 +18,8 @@ __wt_evict_file(WT_SESSION_IMPL *session, int syncop)
WT_DECL_RET;
WT_PAGE *page;
WT_REF *next_ref, *ref;
- WT_TXN *txn;
bool evict_reset;
- txn = &session->txn;
-
/*
* We need exclusive access to the file -- disable ordinary eviction
* and drain any blocks already queued.
@@ -32,9 +29,6 @@ __wt_evict_file(WT_SESSION_IMPL *session, int syncop)
/* Make sure the oldest transaction ID is up-to-date. */
__wt_txn_update_oldest(session, true);
- if (txn->isolation == WT_ISO_READ_COMMITTED)
- __wt_txn_get_snapshot(session);
-
/* Walk the tree, discarding pages. */
next_ref = NULL;
WT_ERR(__wt_tree_walk(session, &next_ref, NULL,
@@ -65,10 +59,6 @@ __wt_evict_file(WT_SESSION_IMPL *session, int syncop)
if (syncop == WT_SYNC_CLOSE && __wt_page_is_modified(page))
WT_ERR(__wt_reconcile(session, ref, NULL, WT_EVICTING));
- /* Update our snapshot for each new page. */
- if (txn->isolation == WT_ISO_READ_COMMITTED)
- __wt_txn_get_snapshot(session);
-
/*
* We can't evict the page just returned to us (it marks our
* place in the tree), so move the walk to one page ahead of
@@ -117,8 +107,5 @@ err: /* On error, clear any left-over tree walk. */
if (evict_reset)
__wt_evict_file_exclusive_off(session);
- if (txn->isolation == WT_ISO_READ_COMMITTED && session->ncursors == 0)
- __wt_txn_release_snapshot(session);
-
return (ret);
}
diff --git a/src/evict/evict_page.c b/src/evict/evict_page.c
index 7f580edad5a..4c0b2bff0bf 100644
--- a/src/evict/evict_page.c
+++ b/src/evict/evict_page.c
@@ -385,7 +385,7 @@ __evict_review(
* Clean pages can't be evicted when running in memory only. This
* should be uncommon - we don't add clean pages to the queue.
*/
- if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY) && !modified)
+ if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY) && !modified && !closing)
return (EBUSY);
/*
diff --git a/src/include/txn.i b/src/include/txn.i
index 92ea96c9be9..e49e3d1257b 100644
--- a/src/include/txn.i
+++ b/src/include/txn.i
@@ -192,10 +192,11 @@ __wt_txn_visible(WT_SESSION_IMPL *session, uint64_t id)
return (true);
/*
- * A visibility check that is not read-uncommitted must have an
- * active snapshot.
+ * If we don't have a transactional snapshot, only make stable updates
+ * visible.
*/
- WT_ASSERT(session, F_ISSET(txn, WT_TXN_HAS_SNAPSHOT));
+ if (!F_ISSET(txn, WT_TXN_HAS_SNAPSHOT))
+ return (__wt_txn_visible_all(session, id));
/* Transactions see their own changes. */
if (id == txn->id)
diff --git a/src/reconcile/rec_write.c b/src/reconcile/rec_write.c
index c1e07215ad8..46c5a38796f 100644
--- a/src/reconcile/rec_write.c
+++ b/src/reconcile/rec_write.c
@@ -819,6 +819,7 @@ __rec_write_init(WT_SESSION_IMPL *session,
r->flags = flags;
/* Track if the page can be marked clean. */
+ r->max_txn = WT_TXN_NONE;
r->leave_dirty = false;
/* Raw compression. */