summaryrefslogtreecommitdiff
path: root/src/btree
diff options
context:
space:
mode:
authorKeith Bostic <keith@wiredtiger.com>2016-04-22 12:34:31 -0400
committerKeith Bostic <keith@wiredtiger.com>2016-04-22 12:34:31 -0400
commitce864e99c22de1653344d4590d8aa27a40804ab7 (patch)
tree46106ff096b49b9d30405b6e515d38b0264d5e7e /src/btree
parent3a6488a12d339b1bb8a1ff3eb015f08327be855a (diff)
downloadmongo-ce864e99c22de1653344d4590d8aa27a40804ab7.tar.gz
WT-2576: variable-length column-store out-of-order return
The callers of __split_multi_inmem_fail allocate WT_REF arrays, then individual WT_REFs, check for uninitialized WT_REFs pointers. The change to remove the record number from variable-length column-store pages broke column-store page-rewrite: page-rewrite didn't set the WT_REF.recno for the temporary WT_REF being used for the rewrite, so the search routine didn't find records on the page and we ended up building corrupt pages. Set the record number in the temporary WT_REF.
Diffstat (limited to 'src/btree')
-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 ec5843d9bf3..a668f57df62 100644
--- a/src/btree/bt_split.c
+++ b/src/btree/bt_split.c
@@ -1603,10 +1603,15 @@ __split_multi_inmem_fail(WT_SESSION_IMPL *session, WT_PAGE *orig, WT_REF *ref)
* new pages. Discard the new allocated WT_REF structures and their
* pages (setting a flag so the discard code doesn't discard the updates
* on the page).
+ *
+ * Our callers allocate WT_REF arrays, then individual WT_REFs, check
+ * for uninitialized information.
*/
- if (ref->page != NULL)
- F_SET_ATOMIC(ref->page, WT_PAGE_UPDATE_IGNORE);
- __wt_free_ref(session, ref, orig->type, true);
+ if (ref != NULL) {
+ if (ref->page != NULL)
+ F_SET_ATOMIC(ref->page, WT_PAGE_UPDATE_IGNORE);
+ __wt_free_ref(session, ref, orig->type, true);
+ }
}
/*
@@ -2180,10 +2185,15 @@ __wt_split_rewrite(WT_SESSION_IMPL *session, WT_REF *ref)
* to re-create a page in memory after it's been reconciled, and that's
* exactly what we want to do.
*
- * Build the new page. (Allocate a WT_REF because the error path uses
- * routines that want to free memory).
+ * Build the new page.
+ *
+ * Allocate a WT_REF because the error path uses routines that will ea
+ * free memory. The only field we need to set is the record number, as
+ * it's used by the search routines.
*/
WT_RET(__wt_calloc_one(session, &new));
+ new->ref_recno = ref->ref_recno;
+
WT_ERR(__split_multi_inmem(session, page, new, &mod->mod_multi[0]));
/*