diff options
Diffstat (limited to 'src/btree/bt_slvg.c')
-rw-r--r-- | src/btree/bt_slvg.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/src/btree/bt_slvg.c b/src/btree/bt_slvg.c index 0e064d306b6..9b5e4daf74a 100644 --- a/src/btree/bt_slvg.c +++ b/src/btree/bt_slvg.c @@ -116,8 +116,8 @@ struct __wt_track { static int __slvg_cleanup(WT_SESSION_IMPL *, WT_STUFF *); static int __slvg_col_build_internal(WT_SESSION_IMPL *, uint32_t, WT_STUFF *); static int __slvg_col_build_leaf(WT_SESSION_IMPL *, WT_TRACK *, WT_REF *); -static int __slvg_col_ovfl( - WT_SESSION_IMPL *, WT_TRACK *, WT_PAGE *, uint64_t, uint64_t); +static int __slvg_col_ovfl(WT_SESSION_IMPL *, + WT_TRACK *, WT_PAGE *, uint64_t, uint64_t, uint64_t); static int __slvg_col_range(WT_SESSION_IMPL *, WT_STUFF *); static int __slvg_col_range_missing(WT_SESSION_IMPL *, WT_STUFF *); static int __slvg_col_range_overlap( @@ -166,11 +166,13 @@ __wt_bt_salvage(WT_SESSION_IMPL *session, WT_CKPT *ckptbase, const char *cfg[]) WT_DECL_RET; WT_STUFF *ss, stuff; uint32_t i, leaf_cnt; + bool evict_reset; WT_UNUSED(cfg); btree = S2BT(session); bm = btree->bm; + evict_reset = false; WT_CLEAR(stuff); ss = &stuff; @@ -182,6 +184,13 @@ __wt_bt_salvage(WT_SESSION_IMPL *session, WT_CKPT *ckptbase, const char *cfg[]) WT_ERR(__wt_scr_alloc(session, 0, &ss->tmp2)); /* + * Salvage handles its own page eviction; get exclusive access to the + * file, have eviction ignore the tree entirely. + */ + WT_ERR(__wt_evict_file_exclusive_on(session)); + evict_reset = true; + + /* * Step 1: * Inform the underlying block manager that we're salvaging the file. */ @@ -295,13 +304,13 @@ __wt_bt_salvage(WT_SESSION_IMPL *session, WT_CKPT *ckptbase, const char *cfg[]) case WT_PAGE_COL_VAR: WT_WITH_PAGE_INDEX(session, ret = __slvg_col_build_internal( - session, leaf_cnt, ss)); + session, leaf_cnt, ss)); WT_ERR(ret); break; case WT_PAGE_ROW_LEAF: WT_WITH_PAGE_INDEX(session, ret = __slvg_row_build_internal( - session, leaf_cnt, ss)); + session, leaf_cnt, ss)); WT_ERR(ret); break; } @@ -341,6 +350,9 @@ err: WT_TRET(bm->salvage_end(bm, session)); if (ss->root_ref.page != NULL) __wt_ref_out(session, &ss->root_ref); + if (evict_reset) + __wt_evict_file_exclusive_off(session); + /* Discard the leaf and overflow page memory. */ WT_TRET(__slvg_cleanup(session, ss)); @@ -1159,7 +1171,7 @@ __slvg_col_build_internal( /* Allocate a column-store root (internal) page and fill it in. */ WT_RET(__wt_page_alloc( - session, WT_PAGE_COL_INT, 1, leaf_cnt, true, &page)); + session, WT_PAGE_COL_INT, leaf_cnt, true, &page)); WT_ERR(__slvg_modify_init(session, page)); pindex = WT_INTL_INDEX_GET_SAFE(page); @@ -1180,7 +1192,7 @@ __slvg_col_build_internal( ref->addr = addr; addr = NULL; - ref->key.recno = trk->col_start; + ref->ref_recno = trk->col_start; ref->state = WT_REF_DISK; /* @@ -1223,7 +1235,7 @@ __slvg_col_build_leaf(WT_SESSION_IMPL *session, WT_TRACK *trk, WT_REF *ref) WT_DECL_RET; WT_PAGE *page; WT_SALVAGE_COOKIE *cookie, _cookie; - uint64_t skip, take; + uint64_t recno, skip, take; uint32_t *entriesp, save_entries; cookie = &_cookie; @@ -1243,7 +1255,8 @@ __slvg_col_build_leaf(WT_SESSION_IMPL *session, WT_TRACK *trk, WT_REF *ref) * Calculate the number of K/V entries we are going to skip, and * the total number of K/V entries we'll take from this page. */ - cookie->skip = skip = trk->col_start - page->pg_var_recno; + recno = page->dsk->recno; + cookie->skip = skip = trk->col_start - recno; cookie->take = take = (trk->col_stop - trk->col_start) + 1; WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, @@ -1255,7 +1268,7 @@ __slvg_col_build_leaf(WT_SESSION_IMPL *session, WT_TRACK *trk, WT_REF *ref) /* Set the referenced flag on overflow pages we're using. */ if (page->type == WT_PAGE_COL_VAR && trk->trk_ovfl_cnt != 0) - WT_ERR(__slvg_col_ovfl(session, trk, page, skip, take)); + WT_ERR(__slvg_col_ovfl(session, trk, page, recno, skip, take)); /* * If we're missing some part of the range, the real start range is in @@ -1263,9 +1276,9 @@ __slvg_col_build_leaf(WT_SESSION_IMPL *session, WT_TRACK *trk, WT_REF *ref) * reference as well as the page itself. */ if (trk->col_missing == 0) - page->pg_var_recno = trk->col_start; + ref->ref_recno = trk->col_start; else { - page->pg_var_recno = trk->col_missing; + ref->ref_recno = trk->col_missing; cookie->missing = trk->col_start - trk->col_missing; WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, @@ -1274,7 +1287,6 @@ __slvg_col_build_leaf(WT_SESSION_IMPL *session, WT_TRACK *trk, WT_REF *ref) session, trk->trk_addr, trk->trk_addr_size, trk->ss->tmp1), cookie->missing)); } - ref->key.recno = page->pg_var_recno; /* * We can't discard the original blocks associated with this page now. @@ -1338,21 +1350,20 @@ __slvg_col_ovfl_single( * Mark overflow items referenced by the merged page. */ static int -__slvg_col_ovfl(WT_SESSION_IMPL *session, - WT_TRACK *trk, WT_PAGE *page, uint64_t skip, uint64_t take) +__slvg_col_ovfl(WT_SESSION_IMPL *session, WT_TRACK *trk, + WT_PAGE *page, uint64_t recno, uint64_t skip, uint64_t take) { WT_CELL_UNPACK unpack; WT_CELL *cell; WT_COL *cip; WT_DECL_RET; - uint64_t recno, start, stop; + uint64_t start, stop; uint32_t i; /* * Merging a variable-length column-store page, and we took some number * of records, figure out which (if any) overflow records we used. */ - recno = page->pg_var_recno; start = recno + skip; stop = (recno + skip + take) - 1; @@ -1816,7 +1827,7 @@ __slvg_row_build_internal( /* Allocate a row-store root (internal) page and fill it in. */ WT_RET(__wt_page_alloc( - session, WT_PAGE_ROW_INT, WT_RECNO_OOB, leaf_cnt, true, &page)); + session, WT_PAGE_ROW_INT, leaf_cnt, true, &page)); WT_ERR(__slvg_modify_init(session, page)); pindex = WT_INTL_INDEX_GET_SAFE(page); |