summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/session/session_salvage.c
blob: 79e67475958070a87a9782728c5933ee09aa930d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/*-
 * Copyright (c) 2014-2019 MongoDB, Inc.
 * Copyright (c) 2008-2014 WiredTiger, Inc.
 *	All rights reserved.
 *
 * See the file LICENSE for redistribution information.
 */

#include "wt_internal.h"

/*
 * __wt_salvage --
 *	Salvage a single file.
 */
int
__wt_salvage(WT_SESSION_IMPL *session, const char *cfg[])
{
	WT_CKPT *ckptbase;
	WT_DATA_HANDLE *dhandle;
	WT_DECL_RET;

	dhandle = session->dhandle;

	/*
	 * XXX
	 * The salvage process reads and discards previous checkpoints, so the
	 * underlying block manager has to ignore any previous checkpoint
	 * entries when creating a new checkpoint, in other words, we can't use
	 * the metadata checkpoint list, it has all of those checkpoint listed
	 * and we don't care about them.  Build a clean checkpoint list and use
	 * it instead.
	 *
	 * Don't first clear the metadata checkpoint list and call the function
	 * to get a list of checkpoints: a crash between clearing the metadata
	 * checkpoint list and creating a new checkpoint list would look like a
	 * create or open of a file without a checkpoint to roll-forward from,
	 * and the contents of the file would be discarded.
	 */
	WT_RET(__wt_calloc_def(session, 2, &ckptbase));
	WT_ERR(__wt_strdup(session, WT_CHECKPOINT, &ckptbase[0].name));
	F_SET(&ckptbase[0], WT_CKPT_ADD);

	WT_ERR(__wt_bt_salvage(session, ckptbase, cfg));

	/*
	 * If no checkpoint was created, well, it's probably bad news, but there
	 * is nothing to do but clear any recorded checkpoints for the file.  If
	 * a checkpoint was created, life is good, replace any existing list of
	 * checkpoints with the single new one.
	 */
	if (ckptbase[0].raw.data == NULL)
		WT_ERR(__wt_meta_checkpoint_clear(session, dhandle->name));
	else
		WT_ERR(__wt_meta_ckptlist_set(
		    session, dhandle->name, ckptbase, NULL));

err:	__wt_meta_ckptlist_free(session, &ckptbase);
	return (ret);
}