summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@mongodb.com>2015-11-03 13:38:43 +1100
committerAlex Gorrod <alexg@wiredtiger.com>2015-11-26 15:21:44 +1100
commit66a111ec48da60195a011e2a163bef07f5035bb0 (patch)
treeb587570148a970aa2dbed1fc798d1f780568864b
parent7b1398a1a6ee6bd4e0624c38c5311e896a42cbfc (diff)
downloadmongo-66a111ec48da60195a011e2a163bef07f5035bb0.tar.gz
WT-2195 Fix a hang after giving up on a reverse split.
-rw-r--r--src/btree/bt_split.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/btree/bt_split.c b/src/btree/bt_split.c
index d2861e5237e..6f31ff89aa7 100644
--- a/src/btree/bt_split.c
+++ b/src/btree/bt_split.c
@@ -961,10 +961,13 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref,
/*
* If the entire (sub)tree is empty, give up: we can't leave an empty
- * internal page.
+ * internal page. Mark it to be evicted soon and clean up any
+ * references that have changed state.
*/
- if (result_entries == 0)
- return (0);
+ if (result_entries == 0) {
+ __wt_page_evict_soon(parent);
+ goto err;
+ }
/*
* Allocate and initialize a new page index array for the parent, then
@@ -1142,14 +1145,21 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref,
__split_should_deepen(session, parent_ref))
ret = __split_deepen(session, parent);
-err: if (!complete)
+err: if (!complete) {
for (i = 0; i < parent_entries; ++i) {
next_ref = pindex->index[i];
if (next_ref->state == WT_REF_SPLIT)
next_ref->state = WT_REF_DELETED;
}
- __wt_free_ref_index(session, NULL, alloc_index, false);
+ /* If we gave up on a reverse split, unlock the child. */
+ if (ref_new == NULL) {
+ WT_ASSERT(session, ref->state == WT_REF_LOCKED);
+ ref->state = WT_REF_DELETED;
+ }
+
+ __wt_free_ref_index(session, NULL, alloc_index, false);
+ }
/*
* A note on error handling: if we completed the split, return success,