summaryrefslogtreecommitdiff
path: root/src/btree/bt_slvg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/btree/bt_slvg.c')
-rw-r--r--src/btree/bt_slvg.c45
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);