diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/meta/meta_ckpt.c')
-rw-r--r-- | src/third_party/wiredtiger/src/meta/meta_ckpt.c | 112 |
1 files changed, 59 insertions, 53 deletions
diff --git a/src/third_party/wiredtiger/src/meta/meta_ckpt.c b/src/third_party/wiredtiger/src/meta/meta_ckpt.c index 60a783e86cd..3d105823e98 100644 --- a/src/third_party/wiredtiger/src/meta/meta_ckpt.c +++ b/src/third_party/wiredtiger/src/meta/meta_ckpt.c @@ -12,9 +12,11 @@ static int __ckpt_last(WT_SESSION_IMPL *, const char *, WT_CKPT *); static int __ckpt_last_name(WT_SESSION_IMPL *, const char *, const char **, int64_t *, uint64_t *); static int __ckpt_load(WT_SESSION_IMPL *, WT_CONFIG_ITEM *, WT_CONFIG_ITEM *, WT_CKPT *); static int __ckpt_named(WT_SESSION_IMPL *, const char *, const char *, WT_CKPT *); +static int __ckpt_parse_time(WT_SESSION_IMPL *, WT_CONFIG_ITEM *, uint64_t *); static int __ckpt_set(WT_SESSION_IMPL *, const char *, const char *, bool); static int __ckpt_version_chk(WT_SESSION_IMPL *, const char *, const char *); static int __meta_blk_mods_load(WT_SESSION_IMPL *, const char *, WT_CKPT *, WT_CKPT *, bool); + /* * __ckpt_load_blk_mods -- * Load the block information from the config string. @@ -173,6 +175,30 @@ err: } /* + * __ckpt_parse_time -- + * Parse clock time from checkpoint metadata config. This requires special handling because + * times are unsigned values and config parsing treats numeric values as signed. + */ +static int +__ckpt_parse_time(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *config_value, uint64_t *timep) +{ + char timebuf[64]; + + WT_UNUSED(session); + *timep = 0; + + if (config_value->len == 0 || config_value->len > sizeof(timebuf) - 1) + return (WT_ERROR); + memcpy(timebuf, config_value->str, config_value->len); + timebuf[config_value->len] = '\0'; + /* NOLINTNEXTLINE(cert-err34-c) */ + if (sscanf(timebuf, "%" SCNu64, timep) != 1) + return (WT_ERROR); + + return (0); +} + +/* * __wt_meta_checkpoint_by_name -- * Look up the requested named checkpoint in the metadata and return its order and time * information. @@ -213,7 +239,7 @@ __wt_meta_checkpoint_by_name(WT_SESSION_IMPL *session, const char *uri, const ch WT_ERR(__wt_config_subgets(session, &v, "write_gen", &a)); if ((uint64_t)a.val >= conn->base_write_gen) { WT_ERR(__wt_config_subgets(session, &v, "time", &a)); - *timep = (uint64_t)a.val; + WT_ERR(__ckpt_parse_time(session, &a, timep)); } break; } @@ -372,12 +398,10 @@ __ckpt_last_name(WT_SESSION_IMPL *session, const char *config, const char **name { WT_CONFIG ckptconf; WT_CONFIG_ITEM a, k, v; - WT_CONNECTION_IMPL *conn; WT_DECL_RET; uint64_t time; int64_t found; - conn = S2C(session); *namep = NULL; time = 0; @@ -391,13 +415,9 @@ __ckpt_last_name(WT_SESSION_IMPL *session, const char *config, const char **name continue; found = a.val; - /* If the write generation is current, extract the wall-clock time for matching purposes. */ - WT_ERR(__wt_config_subgets(session, &v, "write_gen", &a)); - if ((uint64_t)a.val >= conn->base_write_gen) { - WT_ERR(__wt_config_subgets(session, &v, "time", &a)); - time = (uint64_t)a.val; - } else - time = 0; + /* Extract the wall-clock time for matching purposes. */ + WT_ERR(__wt_config_subgets(session, &v, "time", &a)); + WT_ERR(__ckpt_parse_time(session, &a, &time)); __wt_free(session, *namep); WT_ERR(__wt_strndup(session, k.str, k.len, namep)); @@ -891,7 +911,6 @@ __ckpt_load(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *k, WT_CONFIG_ITEM *v, WT_C { WT_CONFIG_ITEM a; WT_DECL_RET; - char timebuf[64]; /* * Copy the name, address (raw and hex), order and time into the slot. If there's no address, @@ -908,17 +927,13 @@ __ckpt_load(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *k, WT_CONFIG_ITEM *v, WT_C WT_RET(__wt_config_subgets(session, v, "order", &a)); if (a.len == 0) - goto format; + WT_RET_MSG(session, WT_ERROR, "corrupted order value in checkpoint config"); ckpt->order = a.val; WT_RET(__wt_config_subgets(session, v, "time", &a)); - if (a.len == 0 || a.len > sizeof(timebuf) - 1) - goto format; - memcpy(timebuf, a.str, a.len); - timebuf[a.len] = '\0'; - /* NOLINTNEXTLINE(cert-err34-c) */ - if (sscanf(timebuf, "%" SCNu64, &ckpt->sec) != 1) - goto format; + ret = __ckpt_parse_time(session, &a, &ckpt->sec); + if (ret != 0) + WT_RET_MSG(session, WT_ERROR, "corrupted time value in checkpoint config"); WT_RET(__wt_config_subgets(session, v, "size", &a)); ckpt->size = (uint64_t)a.val; @@ -985,7 +1000,7 @@ __ckpt_load(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *k, WT_CONFIG_ITEM *v, WT_C WT_RET(__wt_config_subgets(session, v, "write_gen", &a)); if (a.len == 0) - goto format; + WT_RET_MSG(session, WT_ERROR, "corrupted write_gen in checkpoint config"); ckpt->write_gen = (uint64_t)a.val; /* @@ -999,17 +1014,15 @@ __ckpt_load(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *k, WT_CONFIG_ITEM *v, WT_C ckpt->run_write_gen = (uint64_t)a.val; return (0); - -format: - WT_RET_MSG(session, WT_ERROR, "corrupted checkpoint list"); } /* - * __wt_metadata_update_base_write_gen -- - * Update the connection's base write generation from the config string. + * __wt_metadata_update_connection -- + * Update the connection's base write generation and most recent checkpoint time from the config + * string. */ int -__wt_metadata_update_base_write_gen(WT_SESSION_IMPL *session, const char *config) +__wt_metadata_update_connection(WT_SESSION_IMPL *session, const char *config) { WT_CKPT ckpt; WT_CONNECTION_IMPL *conn; @@ -1020,6 +1033,7 @@ __wt_metadata_update_base_write_gen(WT_SESSION_IMPL *session, const char *config if ((ret = __ckpt_last(session, config, &ckpt)) == 0) { conn->base_write_gen = WT_MAX(ckpt.write_gen + 1, conn->base_write_gen); + conn->ckpt_most_recent = WT_MAX(ckpt.sec, conn->ckpt_most_recent); __wt_meta_checkpoint_free(session, &ckpt); } else WT_RET_NOTFOUND_OK(ret); @@ -1028,21 +1042,26 @@ __wt_metadata_update_base_write_gen(WT_SESSION_IMPL *session, const char *config } /* - * __wt_metadata_init_base_write_gen -- - * Initialize the connection's base write generation. + * __wt_metadata_load_prior_state -- + * Initialize the connection's base write generation and most recent checkpoint time. */ int -__wt_metadata_init_base_write_gen(WT_SESSION_IMPL *session) +__wt_metadata_load_prior_state(WT_SESSION_IMPL *session) { + WT_CONNECTION_IMPL *conn; WT_DECL_RET; char *config; + conn = S2C(session); + /* Initialize the base write gen to 1 */ - S2C(session)->base_write_gen = 1; + conn->base_write_gen = 1; + /* Initialize most recent checkpoint time with current clock */ + __wt_seconds(session, &conn->ckpt_most_recent); /* Retrieve the metadata entry for the metadata file. */ WT_ERR(__wt_metadata_search(session, WT_METAFILE_URI, &config)); - /* Update base write gen to the write gen of metadata. */ - WT_ERR(__wt_metadata_update_base_write_gen(session, config)); + /* Update base write gen and most recent checkpoint time from the metadata. */ + WT_ERR(__wt_metadata_update_connection(session, config)); err: __wt_free(session, config); @@ -1071,8 +1090,8 @@ __wt_metadata_correct_base_write_gen(WT_SESSION_IMPL *session) WT_ERR(cursor->get_value(cursor, &config)); - /* Update base write gen to the write gen. */ - WT_ERR(__wt_metadata_update_base_write_gen(session, config)); + /* Update base write gen and most recent checkpoint time. */ + WT_ERR(__wt_metadata_update_connection(session, config)); } WT_ERR_NOTFOUND_OK(ret, false); @@ -1577,14 +1596,12 @@ __wt_meta_read_checkpoint_snapshot(WT_SESSION_IMPL *session, const char *ckpt_na WT_CONFIG list; WT_CONFIG_ITEM cval; WT_CONFIG_ITEM k; - WT_CONNECTION_IMPL *conn; WT_DECL_ITEM(tmp); WT_DECL_RET; uint64_t write_gen; uint32_t counter; char *sys_config; - conn = S2C(session); write_gen = 0; counter = 0; sys_config = NULL; @@ -1660,14 +1677,11 @@ __wt_meta_read_checkpoint_snapshot(WT_SESSION_IMPL *session, const char *ckpt_na if (snap_write_gen != NULL) *snap_write_gen = write_gen; - /* - * If the write generation is current, extract the checkpoint time. Otherwise we use 0. - */ - if (ckpttime != NULL && cval.val != 0 && write_gen >= conn->base_write_gen) { + /* Extract the checkpoint time. */ + if (ckpttime != NULL) { WT_ERR_NOTFOUND_OK( __wt_config_getones(session, sys_config, WT_SYSTEM_CKPT_SNAPSHOT_TIME, &cval), false); - if (cval.val != 0) - *ckpttime = (uint64_t)cval.val; + WT_ERR(__ckpt_parse_time(session, &cval, ckpttime)); } /* @@ -1696,11 +1710,9 @@ __meta_retrieve_timestamp(WT_SESSION_IMPL *session, const char *system_uri, const char *timestamp_name, wt_timestamp_t *timestampp, uint64_t *ckpttime) { WT_CONFIG_ITEM cval; - WT_CONNECTION_IMPL *conn; WT_DECL_RET; char *sys_config; - conn = S2C(session); sys_config = NULL; *timestampp = WT_TXN_NONE; if (ckpttime != NULL) @@ -1718,16 +1730,10 @@ __meta_retrieve_timestamp(WT_SESSION_IMPL *session, const char *system_uri, } if (ckpttime != NULL) { - /* If the write generation is current, extract the checkpoint time. Otherwise we use 0. - */ + /* Extract the checkpoint time. */ WT_ERR_NOTFOUND_OK( - __wt_config_getones(session, sys_config, WT_SYSTEM_TS_WRITE_GEN, &cval), false); - if (cval.val != 0 && (uint64_t)cval.val >= conn->base_write_gen) { - WT_ERR_NOTFOUND_OK( - __wt_config_getones(session, sys_config, WT_SYSTEM_TS_TIME, &cval), false); - if (cval.val != 0) - *ckpttime = (uint64_t)cval.val; - } + __wt_config_getones(session, sys_config, WT_SYSTEM_TS_TIME, &cval), false); + WT_ERR(__ckpt_parse_time(session, &cval, ckpttime)); } } |