diff options
author | Michael Cahill <michael.cahill@mongodb.com> | 2015-10-30 22:18:27 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2015-10-30 22:18:27 +1100 |
commit | ba931c1c64869b74c8699a6eb56c88b83521e9f4 (patch) | |
tree | 7d31149040ce964978feab60b726aecd1077beeb | |
parent | fdfa804f85c19ce11ef94eded570c55c12918d41 (diff) | |
parent | 78f504e4f3f9393726f01019e1c6f939b72ff435 (diff) | |
download | mongo-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.c | 17 | ||||
-rw-r--r-- | src/btree/bt_sync.c | 2 | ||||
-rw-r--r-- | src/evict/evict_file.c | 13 | ||||
-rw-r--r-- | src/evict/evict_page.c | 2 | ||||
-rw-r--r-- | src/include/txn.i | 7 | ||||
-rw-r--r-- | src/reconcile/rec_write.c | 1 |
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. */ |