summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/block/block_ckpt.c
diff options
context:
space:
mode:
authorRuby Chen <ruby.chen@mongodb.com>2023-03-22 04:27:57 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-03-22 05:05:26 +0000
commitc7fee1fd452fd7ca41d34edc8dcae9bdccf9cb07 (patch)
treee23ed9a10b24da453ea964db4d3423cacfbf7f24 /src/third_party/wiredtiger/src/block/block_ckpt.c
parent819f18006151ae7998f492a88c29c1b6fb2eeb3f (diff)
downloadmongo-c7fee1fd452fd7ca41d34edc8dcae9bdccf9cb07.tar.gz
Import wiredtiger: 116fc475915a3e372c1b79f4462b48f386e43db6 from branch mongodb-master
ref: ea3fd8a50b..116fc47591 for: 7.0.0-rc0 WT-10763 Don't load the wrong extent lists in __wt_block_checkpoint_load
Diffstat (limited to 'src/third_party/wiredtiger/src/block/block_ckpt.c')
-rw-r--r--src/third_party/wiredtiger/src/block/block_ckpt.c75
1 files changed, 60 insertions, 15 deletions
diff --git a/src/third_party/wiredtiger/src/block/block_ckpt.c b/src/third_party/wiredtiger/src/block/block_ckpt.c
index a89cb7c63dd..5aa945b9350 100644
--- a/src/third_party/wiredtiger/src/block/block_ckpt.c
+++ b/src/third_party/wiredtiger/src/block/block_ckpt.c
@@ -12,8 +12,37 @@ static int __ckpt_process(WT_SESSION_IMPL *, WT_BLOCK *, WT_CKPT *);
static int __ckpt_update(WT_SESSION_IMPL *, WT_BLOCK *, WT_CKPT *, WT_CKPT *, WT_BLOCK_CKPT *);
/*
+ * __block_extlist_setup --
+ * Initialize the extent lists in a checkpoint structure.
+ */
+static int
+__block_extlist_setup(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci, const char *name)
+{
+ WT_RET(__wt_block_extlist_init(session, &ci->alloc, name, "alloc", false));
+ WT_RET(__wt_block_extlist_init(session, &ci->avail, name, "avail", true));
+ WT_RET(__wt_block_extlist_init(session, &ci->discard, name, "discard", false));
+ WT_RET(__wt_block_extlist_init(session, &ci->ckpt_avail, name, "ckpt_avail", true));
+
+ return (0);
+}
+
+/*
+ * __block_extlist_reset --
+ * Discard and reinitialize the extent lists in a checkpoint structure
+ */
+static int
+__block_extlist_reset(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci, const char *name)
+{
+ __wt_block_ckpt_destroy(session, ci);
+ WT_RET(__block_extlist_setup(session, ci, name));
+
+ return (0);
+}
+
+/*
* __wt_block_ckpt_init --
- * Initialize a checkpoint structure.
+ * Return the address cookie for the root page of a checkpoint. Also initialize extent lists if
+ * we are loading the live checkpoint in a writable file.
*/
int
__wt_block_ckpt_init(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci, const char *name)
@@ -23,17 +52,13 @@ __wt_block_ckpt_init(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci, const char *na
ci->version = WT_BM_CHECKPOINT_VERSION;
ci->root_offset = WT_BLOCK_INVALID_OFFSET;
- WT_RET(__wt_block_extlist_init(session, &ci->alloc, name, "alloc", false));
- WT_RET(__wt_block_extlist_init(session, &ci->avail, name, "avail", true));
- WT_RET(__wt_block_extlist_init(session, &ci->discard, name, "discard", false));
- WT_RET(__wt_block_extlist_init(session, &ci->ckpt_avail, name, "ckpt_avail", true));
-
- return (0);
+ return (__block_extlist_setup(session, ci, name));
}
/*
* __wt_block_checkpoint_load --
- * Load a checkpoint.
+ * Return the address cookie for the root page of a checkpoint. Also initialize its extent lists
+ * if loading the live checkpoint from a writeable file.
*/
int
__wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr,
@@ -90,23 +115,42 @@ __wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint
WT_ERR(__wt_block_ckpt_unpack(session, block, addr, addr_size, ci));
/* Verify sets up next. */
- if (block->verify)
+ if (block->verify) {
+ /*
+ * FIXME: We may need to change how we setup for verify when it supports tiered tables.
+ * Until then, an attempt to verify a tiered table should return before getting here.
+ */
+ WT_ASSERT(session, block->objectid == 0 && ci->root_objectid == 0);
WT_ERR(__wt_verify_ckpt_load(session, block, ci));
+ }
/* Read any root page. */
if (ci->root_offset != WT_BLOCK_INVALID_OFFSET) {
+ /* A checkpoint shouldn't point to an object created after this one. */
+ WT_ASSERT(session, block->objectid >= ci->root_objectid);
+
endp = root_addr;
WT_ERR(__wt_block_addr_pack(
block, &endp, ci->root_objectid, ci->root_offset, ci->root_size, ci->root_checksum));
*root_addr_sizep = WT_PTRDIFF(endp, root_addr);
}
- /*
- * Rolling a checkpoint forward requires the avail list, the blocks from which we can
- * allocate.
- */
- if (!checkpoint)
+ if (!checkpoint) {
+ /*
+ * The checkpoint address may point to an earlier object. If so, the object backing this
+ * block handle doesn't have valid data -- i.e., it must have been written after the
+ * checkpoint we are opening. So we discard the incorrect extent lists and reinitialize
+ * them to be empty.
+ */
+ if (block->objectid != ci->root_objectid)
+ __block_extlist_reset(session, ci, "live");
+
+ /*
+ * Rolling a checkpoint forward requires the avail list, the blocks from which we can
+ * allocate.
+ */
WT_ERR(__wt_block_extlist_read_avail(session, block, &ci->avail, ci->file_size));
+ }
}
/*
@@ -168,7 +212,8 @@ __wt_block_checkpoint_unload(WT_SESSION_IMPL *session, WT_BLOCK *block, bool che
/*
* __wt_block_ckpt_destroy --
- * Clear a checkpoint structure.
+ * Clear a checkpoint structure. Free the extent lists, but leave the rest of the state intact
+ * in case the caller is re-using it.
*/
void
__wt_block_ckpt_destroy(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci)