diff options
author | Keith Bostic <keith.bostic@mongodb.com> | 2016-05-16 11:13:05 -0400 |
---|---|---|
committer | Alex Gorrod <alexander.gorrod@mongodb.com> | 2016-05-16 11:13:05 -0400 |
commit | 0893547e78009260c22506689ef71f689aeef446 (patch) | |
tree | 6b4e334e84e89dec2e4d2138764306629882fdc0 | |
parent | 62fc6016ee2aadde459fa744959f7a55357ce4a6 (diff) | |
download | mongo-0893547e78009260c22506689ef71f689aeef446.tar.gz |
WT-2628 Reconciliation can return without unlocking the page lock (#2728)
Don't clean up reconciliation structures before they've been initialized.
Fix two paths where scratch buffers could be allocated and fail to be
released.
-rw-r--r-- | src/reconcile/rec_write.c | 19 | ||||
-rw-r--r-- | test/format/util.c | 12 |
2 files changed, 14 insertions, 17 deletions
diff --git a/src/reconcile/rec_write.c b/src/reconcile/rec_write.c index a46662b4b9d..6e406fc7180 100644 --- a/src/reconcile/rec_write.c +++ b/src/reconcile/rec_write.c @@ -383,8 +383,11 @@ __wt_reconcile(WT_SESSION_IMPL *session, mod->last_oldest_id = oldest_id; /* Initialize the reconciliation structure for each new run. */ - WT_RET(__rec_write_init( - session, ref, flags, salvage, &session->reconcile)); + if ((ret = __rec_write_init( + session, ref, flags, salvage, &session->reconcile)) != 0) { + WT_TRET(__wt_fair_unlock(session, &page->page_lock)); + return (ret); + } r = session->reconcile; /* Reconcile the page. */ @@ -4269,14 +4272,14 @@ __rec_col_var(WT_SESSION_IMPL *session, last = r->last; vpack = &_vpack; + WT_RET(__rec_split_init( + session, r, page, pageref->ref_recno, btree->maxleafpage)); + WT_RET(__wt_scr_alloc(session, 0, &orig)); data = NULL; size = 0; upd = NULL; - WT_RET(__rec_split_init( - session, r, page, pageref->ref_recno, btree->maxleafpage)); - /* * The salvage code may be calling us to reconcile a page where there * were missing records in the column-store name space. If taking the @@ -5019,8 +5022,8 @@ __rec_row_leaf(WT_SESSION_IMPL *session, * Temporary buffers in which to instantiate any uninstantiated keys * or value items we need. */ - WT_RET(__wt_scr_alloc(session, 0, &tmpkey)); - WT_RET(__wt_scr_alloc(session, 0, &tmpval)); + WT_ERR(__wt_scr_alloc(session, 0, &tmpkey)); + WT_ERR(__wt_scr_alloc(session, 0, &tmpval)); /* For each entry in the page... */ WT_ROW_FOREACH(page, rip, i) { @@ -5180,7 +5183,7 @@ __rec_row_leaf(WT_SESSION_IMPL *session, * can't remove them from the in-memory * tree; if an overflow key was deleted * without being instantiated (for - * example, cursor-based truncation, do + * example, cursor-based truncation), do * it now. */ if (ikey == NULL) diff --git a/test/format/util.c b/test/format/util.c index f2b4d18029e..cebe2153b3e 100644 --- a/test/format/util.c +++ b/test/format/util.c @@ -213,16 +213,10 @@ val_gen(WT_RAND_STATE *rnd, WT_ITEM *value, uint64_t keyno) } /* - * Start the data with a 10-digit number. - * - * For row and non-repeated variable-length column-stores, change the - * leading number to ensure every data item is unique. For repeated - * variable-length column-stores (that is, to test run-length encoding), - * use the same data value all the time. + * Data items have unique leading numbers by default and random lengths; + * variable-length column-stores use a duplicate data value to test RLE. */ - if ((g.type == ROW || g.type == VAR) && - g.c_repeat_data_pct != 0 && - mmrand(rnd, 1, 100) < g.c_repeat_data_pct) { + if (g.type == VAR && mmrand(rnd, 1, 100) < g.c_repeat_data_pct) { (void)strcpy(p, "DUPLICATEV"); p[10] = '/'; value->size = val_dup_data_len; |