summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith.bostic@mongodb.com>2016-05-16 11:13:05 -0400
committerAlex Gorrod <alexander.gorrod@mongodb.com>2016-05-16 11:13:05 -0400
commit0893547e78009260c22506689ef71f689aeef446 (patch)
tree6b4e334e84e89dec2e4d2138764306629882fdc0
parent62fc6016ee2aadde459fa744959f7a55357ce4a6 (diff)
downloadmongo-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.c19
-rw-r--r--test/format/util.c12
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;