diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/schema/schema_alter.c')
-rw-r--r-- | src/third_party/wiredtiger/src/schema/schema_alter.c | 192 |
1 files changed, 190 insertions, 2 deletions
diff --git a/src/third_party/wiredtiger/src/schema/schema_alter.c b/src/third_party/wiredtiger/src/schema/schema_alter.c index 3786a719c17..f44715ae25f 100644 --- a/src/third_party/wiredtiger/src/schema/schema_alter.c +++ b/src/third_party/wiredtiger/src/schema/schema_alter.c @@ -79,6 +79,26 @@ __alter_file(WT_SESSION_IMPL *session, const char *newcfg[]) } /* + * __alter_tier -- + * Alter a tier. + */ +static int +__alter_tier(WT_SESSION_IMPL *session, const char *newcfg[]) +{ + const char *uri; + + /* + * We know that we have exclusive access to the tier. So it will be closed after we're done with + * it and the next open will see the updated metadata. + */ + uri = session->dhandle->name; + if (!WT_PREFIX_MATCH(uri, "tier:")) + return (__wt_unexpected_object_type(session, uri, "tier:")); + + return (__alter_apply(session, uri, newcfg, WT_CONFIG_BASE(session, tier_meta))); +} + +/* * __alter_object -- * Alter a tiered object. There are no object dhandles. */ @@ -92,6 +112,173 @@ __alter_object(WT_SESSION_IMPL *session, const char *uri, const char *newcfg[]) } /* + * __alter_get_object_id_range -- + * Get current and oldest object IDs for the tiered object. + */ +static int +__alter_get_object_id_range(WT_SESSION_IMPL *session, WT_TIERED *tiered, const char *uri, + uint32_t *current_idp, uint32_t *oldest_idp) +{ + WT_CONFIG_ITEM cval; + WT_DECL_RET; + uint32_t current_id, oldest_id; + char *value; + + *current_idp = *oldest_idp = WT_TIERED_OBJECTID_NONE; + value = NULL; + /* + * First try to get oldest and current object IDs from the tiered object. If it's not + * initialized, get this information from the metadata. + */ + current_id = tiered->current_id; + oldest_id = tiered->oldest_id; + if (current_id == WT_TIERED_OBJECTID_NONE) { + WT_RET(__wt_metadata_search(session, uri, &value)); + + WT_ERR(__wt_config_getones(session, value, "oldest", &cval)); + oldest_id = (uint32_t)cval.val; + + WT_ERR(__wt_config_getones(session, value, "last", &cval)); + current_id = (uint32_t)cval.val; + } + + *current_idp = current_id; + *oldest_idp = oldest_id; +err: + __wt_free(session, value); + + return ret; +} + +/* + * __alter_objects -- + * Alter all objects in the oldest-current range. + */ +static int +__alter_objects(WT_SESSION_IMPL *session, WT_TIERED *tiered, const char *newcfg[], + uint32_t current_id, uint32_t oldest_id) +{ + WT_DECL_RET; + uint32_t object_id; + char *value; + const char *name; + + value = NULL; + name = NULL; + + /* + * Iterate over all objects in the range oldest-current object IDs and alter metadata of each of + * them. + */ + for (object_id = oldest_id; object_id < current_id; object_id++) { + WT_ERR(__wt_tiered_name(session, &tiered->iface, object_id, WT_TIERED_NAME_OBJECT, &name)); + + /* + * Check if this object present in the metadata. Skip it if not found. It is expected for + * the range of objects to be not contiguous, because some objects may have been deleted. + */ + ret = __wt_metadata_search(session, name, &value); + __wt_free(session, value); + WT_ERR_NOTFOUND_OK(ret, true); + if (ret == 0) { + WT_WITH_DHANDLE(session, NULL, ret = __schema_alter(session, name, newcfg)); + WT_ERR(ret); + } + __wt_free(session, name); + } +err: + __wt_free(session, name); + + return (ret); +} + +/* + * __alter_tiered -- + * Alter a tiered metadata. + */ +static int +__alter_tiered(WT_SESSION_IMPL *session, const char *uri, const char *newcfg[], uint32_t flags) +{ + WT_DATA_HANDLE *dhandle; + WT_DECL_RET; + WT_TIERED *tiered; + uint32_t current_id, name_flag, oldest_id; + u_int i; + char *value; + const char *name; + + dhandle = NULL; + value = NULL; + name = NULL; + + if (!WT_PREFIX_MATCH(uri, "tiered:")) + return (__wt_unexpected_object_type(session, uri, "tiered:")); + + /* + * If the operation requires exclusive access, close any open handles, including checkpoints. + */ + if (FLD_ISSET(flags, WT_DHANDLE_EXCLUSIVE)) { + WT_WITH_HANDLE_LIST_WRITE_LOCK( + session, ret = __wt_conn_dhandle_close_all(session, uri, false, false)); + WT_RET(ret); + } + + WT_RET(__wt_session_get_dhandle(session, uri, NULL, NULL, flags)); + tiered = (WT_TIERED *)session->dhandle; + + WT_ERR(__alter_get_object_id_range(session, tiered, uri, ¤t_id, &oldest_id)); + + /* Alter each tier. */ + for (i = 0; i < WT_TIERED_MAX_TIERS; i++) { + dhandle = tiered->tiers[i].tier; + if (dhandle == NULL) { + /* + * Tiers may not be initialized because we open tiered handle with lock only flag. In + * this case we need to find the names of the tiers manually. + */ + if (i == WT_TIERED_INDEX_LOCAL) + name_flag = WT_TIERED_NAME_LOCAL; + else if (i == WT_TIERED_INDEX_SHARED) + name_flag = WT_TIERED_NAME_SHARED; + else + continue; + + WT_ERR(__wt_tiered_name(session, &tiered->iface, current_id, name_flag, &name)); + + /* Check if metadata has entry for this tier. */ + ret = __wt_metadata_search(session, name, &value); + __wt_free(session, value); + WT_ERR_NOTFOUND_OK(ret, true); + if (ret != 0) { + /* + * Not found in the metadata. Skip it. This is expected, for instance, in the + * scenario when tier hasn't been flushed and there's no shared tier yet. + */ + __wt_free(session, name); + continue; + } + } + + WT_WITH_DHANDLE(session, NULL, + ret = __schema_alter(session, name == NULL ? dhandle->name : name, newcfg)); + __wt_free(session, name); + WT_ERR(ret); + } + + /* Alter all objects. */ + WT_ERR(__alter_objects(session, tiered, newcfg, current_id, oldest_id)); + + /* Apply change to the tiered metadata. */ + WT_ERR(__alter_apply(session, uri, newcfg, WT_CONFIG_BASE(session, tiered_meta))); + +err: + WT_TRET(__wt_session_release_dhandle(session)); + __wt_free(session, name); + + return (ret); +} + +/* * __alter_tree -- * Alter an index or colgroup reference. */ @@ -236,9 +423,10 @@ __schema_alter(WT_SESSION_IMPL *session, const char *uri, const char *newcfg[]) return (__alter_object(session, uri, newcfg)); if (WT_PREFIX_MATCH(uri, "table:")) return (__alter_table(session, uri, newcfg, exclusive_refreshed)); + if (WT_PREFIX_MATCH(uri, "tier:")) + return (__wt_exclusive_handle_operation(session, uri, __alter_tier, newcfg, flags)); if (WT_PREFIX_MATCH(uri, "tiered:")) - return (__wt_schema_tiered_worker(session, uri, __alter_file, NULL, newcfg, flags)); - + return (__alter_tiered(session, uri, newcfg, flags)); return (__wt_bad_object_type(session, uri)); } |