diff options
author | Luke Chen <luke.chen@mongodb.com> | 2019-08-21 05:23:37 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-08-21 05:23:37 +0000 |
commit | ac41c65f6355f83aac70136324c98561ac79daa1 (patch) | |
tree | a7c3f7ef090b59c6a06838a02c96bd1d49e1c729 /src/third_party/wiredtiger/src/schema/schema_alter.c | |
parent | f54709196711c63a429b71f47c584661286d675f (diff) | |
download | mongo-ac41c65f6355f83aac70136324c98561ac79daa1.tar.gz |
Import wiredtiger: 7dfd9391862bc9a6d84868c4dc51689c45a3aacf from branch mongodb-4.4
ref: c809757d8b..7dfd939186
for: 4.3.1
WT-4658 Apply Clang Format
WT-4810 Adding WT_ERR_ASSERT and WT_RET_ASSERT macros
WT-5046 Prepared transactions aren't properly cleared from global table with WT_CONN_LOG_DEBUG_MODE enabled
Diffstat (limited to 'src/third_party/wiredtiger/src/schema/schema_alter.c')
-rw-r--r-- | src/third_party/wiredtiger/src/schema/schema_alter.c | 395 |
1 files changed, 189 insertions, 206 deletions
diff --git a/src/third_party/wiredtiger/src/schema/schema_alter.c b/src/third_party/wiredtiger/src/schema/schema_alter.c index 2fa6b21375b..ca49e4fea8a 100644 --- a/src/third_party/wiredtiger/src/schema/schema_alter.c +++ b/src/third_party/wiredtiger/src/schema/schema_alter.c @@ -11,251 +11,234 @@ static int __schema_alter(WT_SESSION_IMPL *, const char *, const char *[]); /* * __alter_apply -- - * Alter an object + * Alter an object */ static int -__alter_apply(WT_SESSION_IMPL *session, - const char *uri, const char *newcfg[], const char *base_config) +__alter_apply( + WT_SESSION_IMPL *session, const char *uri, const char *newcfg[], const char *base_config) { - WT_DECL_RET; - const char *cfg[4]; - char *config, *newconfig; - - newconfig = NULL; - - /* Find the URI */ - WT_RET(__wt_metadata_search(session, uri, &config)); - - WT_ASSERT(session, newcfg[0] != NULL); - - /* - * Start with the base configuration because collapse is like - * a projection and if we are reading older metadata, it may not - * have all the components. - */ - cfg[0] = base_config; - cfg[1] = config; - cfg[2] = newcfg[0]; - cfg[3] = NULL; - WT_ERR(__wt_config_collapse(session, cfg, &newconfig)); - /* - * Only rewrite if there are changes. - */ - if (strcmp(config, newconfig) != 0) - WT_ERR(__wt_metadata_update(session, uri, newconfig)); - else - WT_STAT_CONN_INCR(session, session_table_alter_skip); - -err: __wt_free(session, config); - __wt_free(session, newconfig); - /* - * Map WT_NOTFOUND to ENOENT, based on the assumption WT_NOTFOUND means - * there was no metadata entry. - */ - if (ret == WT_NOTFOUND) - ret = __wt_set_return(session, ENOENT); - - return (ret); + WT_DECL_RET; + char *config, *newconfig; + const char *cfg[4]; + + newconfig = NULL; + + /* Find the URI */ + WT_RET(__wt_metadata_search(session, uri, &config)); + + WT_ASSERT(session, newcfg[0] != NULL); + + /* + * Start with the base configuration because collapse is like a projection and if we are reading + * older metadata, it may not have all the components. + */ + cfg[0] = base_config; + cfg[1] = config; + cfg[2] = newcfg[0]; + cfg[3] = NULL; + WT_ERR(__wt_config_collapse(session, cfg, &newconfig)); + /* + * Only rewrite if there are changes. + */ + if (strcmp(config, newconfig) != 0) + WT_ERR(__wt_metadata_update(session, uri, newconfig)); + else + WT_STAT_CONN_INCR(session, session_table_alter_skip); + +err: + __wt_free(session, config); + __wt_free(session, newconfig); + /* + * Map WT_NOTFOUND to ENOENT, based on the assumption WT_NOTFOUND means there was no metadata + * entry. + */ + if (ret == WT_NOTFOUND) + ret = __wt_set_return(session, ENOENT); + + return (ret); } /* * __alter_file -- - * Alter a file. + * Alter a file. */ static int __alter_file(WT_SESSION_IMPL *session, const char *newcfg[]) { - const char *uri; - - /* - * We know that we have exclusive access to the file. 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, "file:")) - return (__wt_unexpected_object_type(session, uri, "file:")); - - return (__alter_apply(session, - uri, newcfg, WT_CONFIG_BASE(session, file_meta))); + const char *uri; + + /* + * We know that we have exclusive access to the file. 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, "file:")) + return (__wt_unexpected_object_type(session, uri, "file:")); + + return (__alter_apply(session, uri, newcfg, WT_CONFIG_BASE(session, file_meta))); } /* * __alter_tree -- - * Alter an index or colgroup reference. + * Alter an index or colgroup reference. */ static int __alter_tree(WT_SESSION_IMPL *session, const char *name, const char *newcfg[]) { - WT_CONFIG_ITEM cval; - WT_DECL_ITEM(data_source); - WT_DECL_RET; - char *value; - bool is_colgroup; - - value = NULL; - - is_colgroup = WT_PREFIX_MATCH(name, "colgroup:"); - if (!is_colgroup && !WT_PREFIX_MATCH(name, "index:")) - return (__wt_unexpected_object_type( - session, name, "'colgroup:' or 'index:'")); - - /* Read the schema value. */ - WT_ERR(__wt_metadata_search(session, name, &value)); - - /* Get the data source URI. */ - if ((ret = __wt_config_getones(session, value, "source", &cval)) != 0) - WT_ERR_MSG(session, EINVAL, - "index or column group has no data source: %s", value); - - WT_ERR(__wt_scr_alloc(session, 0, &data_source)); - WT_ERR(__wt_buf_fmt(session, - data_source, "%.*s", (int)cval.len, cval.str)); - - /* Alter the data source */ - WT_ERR(__schema_alter(session, data_source->data, newcfg)); - - /* Alter the index or colgroup */ - if (is_colgroup) - WT_ERR(__alter_apply(session, - name, newcfg, WT_CONFIG_BASE(session, colgroup_meta))); - else - WT_ERR(__alter_apply(session, - name, newcfg, WT_CONFIG_BASE(session, index_meta))); - -err: __wt_scr_free(session, &data_source); - __wt_free(session, value); - return (ret); + WT_CONFIG_ITEM cval; + WT_DECL_ITEM(data_source); + WT_DECL_RET; + char *value; + bool is_colgroup; + + value = NULL; + + is_colgroup = WT_PREFIX_MATCH(name, "colgroup:"); + if (!is_colgroup && !WT_PREFIX_MATCH(name, "index:")) + return (__wt_unexpected_object_type(session, name, "'colgroup:' or 'index:'")); + + /* Read the schema value. */ + WT_ERR(__wt_metadata_search(session, name, &value)); + + /* Get the data source URI. */ + if ((ret = __wt_config_getones(session, value, "source", &cval)) != 0) + WT_ERR_MSG(session, EINVAL, "index or column group has no data source: %s", value); + + WT_ERR(__wt_scr_alloc(session, 0, &data_source)); + WT_ERR(__wt_buf_fmt(session, data_source, "%.*s", (int)cval.len, cval.str)); + + /* Alter the data source */ + WT_ERR(__schema_alter(session, data_source->data, newcfg)); + + /* Alter the index or colgroup */ + if (is_colgroup) + WT_ERR(__alter_apply(session, name, newcfg, WT_CONFIG_BASE(session, colgroup_meta))); + else + WT_ERR(__alter_apply(session, name, newcfg, WT_CONFIG_BASE(session, index_meta))); + +err: + __wt_scr_free(session, &data_source); + __wt_free(session, value); + return (ret); } /* * __alter_table -- - * Alter a table. + * Alter a table. */ static int -__alter_table(WT_SESSION_IMPL *session, - const char *uri, const char *newcfg[], bool exclusive_refreshed) +__alter_table( + WT_SESSION_IMPL *session, const char *uri, const char *newcfg[], bool exclusive_refreshed) { - WT_COLGROUP *colgroup; - WT_DECL_RET; - WT_INDEX *idx; - WT_TABLE *table; - u_int i; - const char *name; - - colgroup = NULL; - table = NULL; - name = uri; - WT_PREFIX_SKIP_REQUIRED(session, name, "table:"); - - /* - * If we have exclusive access update all objects in the schema for - * this table and reopen the handle to update the in-memory state. - */ - if (exclusive_refreshed) { - /* - * Open the table so we can alter its column groups and indexes, - * keeping the table locked exclusive across the alter. - */ - WT_RET(__wt_schema_get_table_uri(session, uri, true, - WT_DHANDLE_EXCLUSIVE, &table)); - /* - * Meta tracking needs to be used because alter needs to be - * atomic. - */ - WT_ASSERT(session, WT_META_TRACKING(session)); - WT_WITH_DHANDLE(session, &table->iface, - ret = __wt_meta_track_handle_lock(session, false)); - WT_RET(ret); - - /* Alter the column groups. */ - for (i = 0; i < WT_COLGROUPS(table); i++) { - if ((colgroup = table->cgroups[i]) == NULL) - continue; - WT_RET(__alter_tree(session, colgroup->name, newcfg)); - } - - /* Alter the indices. */ - WT_RET(__wt_schema_open_indices(session, table)); - for (i = 0; i < table->nindices; i++) { - if ((idx = table->indices[i]) == NULL) - continue; - WT_RET(__alter_tree(session, idx->name, newcfg)); - } - } - - /* Alter the table */ - WT_RET(__alter_apply(session, - uri, newcfg, WT_CONFIG_BASE(session, table_meta))); - - return (ret); + WT_COLGROUP *colgroup; + WT_DECL_RET; + WT_INDEX *idx; + WT_TABLE *table; + u_int i; + const char *name; + + colgroup = NULL; + table = NULL; + name = uri; + WT_PREFIX_SKIP_REQUIRED(session, name, "table:"); + + /* + * If we have exclusive access update all objects in the schema for this table and reopen the + * handle to update the in-memory state. + */ + if (exclusive_refreshed) { + /* + * Open the table so we can alter its column groups and indexes, keeping the table locked + * exclusive across the alter. + */ + WT_RET(__wt_schema_get_table_uri(session, uri, true, WT_DHANDLE_EXCLUSIVE, &table)); + /* + * Meta tracking needs to be used because alter needs to be atomic. + */ + WT_ASSERT(session, WT_META_TRACKING(session)); + WT_WITH_DHANDLE(session, &table->iface, ret = __wt_meta_track_handle_lock(session, false)); + WT_RET(ret); + + /* Alter the column groups. */ + for (i = 0; i < WT_COLGROUPS(table); i++) { + if ((colgroup = table->cgroups[i]) == NULL) + continue; + WT_RET(__alter_tree(session, colgroup->name, newcfg)); + } + + /* Alter the indices. */ + WT_RET(__wt_schema_open_indices(session, table)); + for (i = 0; i < table->nindices; i++) { + if ((idx = table->indices[i]) == NULL) + continue; + WT_RET(__alter_tree(session, idx->name, newcfg)); + } + } + + /* Alter the table */ + WT_RET(__alter_apply(session, uri, newcfg, WT_CONFIG_BASE(session, table_meta))); + + return (ret); } /* * __schema_alter -- - * Alter an object. + * Alter an object. */ static int __schema_alter(WT_SESSION_IMPL *session, const char *uri, const char *newcfg[]) { - WT_CONFIG_ITEM cv; - uint32_t flags; - bool exclusive_refreshed; - const char *cfg[] = { - WT_CONFIG_BASE(session, WT_SESSION_alter), newcfg[0], NULL}; - - /* - * Determine what configuration says about exclusive access. - * A non exclusive alter that doesn't refresh in-memory configuration is - * only valid for the table objects. - */ - WT_RET(__wt_config_gets(session, cfg, "exclusive_refreshed", &cv)); - exclusive_refreshed = (bool)cv.val; - - if (!exclusive_refreshed && !WT_PREFIX_MATCH(uri, "table:")) - WT_RET_MSG(session, EINVAL, - "option \"exclusive_refreshed\" " - "is applicable only on simple tables"); - - /* - * The alter flag is used so LSM can apply some special logic, the - * exclusive flag avoids conflicts with other operations and the lock - * only flag is required because we don't need to have a handle to - * update the metadata and opening the handle causes problems when - * meta tracking is enabled. - */ - flags = WT_BTREE_ALTER | WT_DHANDLE_EXCLUSIVE | WT_DHANDLE_LOCK_ONLY; - if (WT_PREFIX_MATCH(uri, "file:")) - return (__wt_exclusive_handle_operation( - session, uri, __alter_file, newcfg, flags)); - if (WT_PREFIX_MATCH(uri, "colgroup:") || - WT_PREFIX_MATCH(uri, "index:")) - return (__alter_tree(session, uri, newcfg)); - if (WT_PREFIX_MATCH(uri, "lsm:")) - return (__wt_lsm_tree_worker(session, uri, __alter_file, - NULL, newcfg, flags)); - if (WT_PREFIX_MATCH(uri, "table:")) - return (__alter_table(session, - uri, newcfg, exclusive_refreshed)); - - return (__wt_bad_object_type(session, uri)); + WT_CONFIG_ITEM cv; + uint32_t flags; + const char *cfg[] = {WT_CONFIG_BASE(session, WT_SESSION_alter), newcfg[0], NULL}; + bool exclusive_refreshed; + + /* + * Determine what configuration says about exclusive access. A non exclusive alter that doesn't + * refresh in-memory configuration is only valid for the table objects. + */ + WT_RET(__wt_config_gets(session, cfg, "exclusive_refreshed", &cv)); + exclusive_refreshed = (bool)cv.val; + + if (!exclusive_refreshed && !WT_PREFIX_MATCH(uri, "table:")) + WT_RET_MSG(session, EINVAL, + "option \"exclusive_refreshed\" " + "is applicable only on simple tables"); + + /* + * The alter flag is used so LSM can apply some special logic, the exclusive flag avoids + * conflicts with other operations and the lock only flag is required because we don't need to + * have a handle to update the metadata and opening the handle causes problems when meta + * tracking is enabled. + */ + flags = WT_BTREE_ALTER | WT_DHANDLE_EXCLUSIVE | WT_DHANDLE_LOCK_ONLY; + if (WT_PREFIX_MATCH(uri, "file:")) + return (__wt_exclusive_handle_operation(session, uri, __alter_file, newcfg, flags)); + if (WT_PREFIX_MATCH(uri, "colgroup:") || WT_PREFIX_MATCH(uri, "index:")) + return (__alter_tree(session, uri, newcfg)); + if (WT_PREFIX_MATCH(uri, "lsm:")) + return (__wt_lsm_tree_worker(session, uri, __alter_file, NULL, newcfg, flags)); + if (WT_PREFIX_MATCH(uri, "table:")) + return (__alter_table(session, uri, newcfg, exclusive_refreshed)); + + return (__wt_bad_object_type(session, uri)); } /* * __wt_schema_alter -- - * Alter an object. + * Alter an object. */ int -__wt_schema_alter(WT_SESSION_IMPL *session, - const char *uri, const char *newcfg[]) +__wt_schema_alter(WT_SESSION_IMPL *session, const char *uri, const char *newcfg[]) { - WT_DECL_RET; - WT_SESSION_IMPL *int_session; - - WT_RET(__wt_schema_internal_session(session, &int_session)); - WT_ERR(__wt_meta_track_on(int_session)); - ret = __schema_alter(int_session, uri, newcfg); - WT_TRET(__wt_meta_track_off(int_session, true, ret != 0)); -err: WT_TRET(__wt_schema_session_release(session, int_session)); - return (ret); + WT_DECL_RET; + WT_SESSION_IMPL *int_session; + + WT_RET(__wt_schema_internal_session(session, &int_session)); + WT_ERR(__wt_meta_track_on(int_session)); + ret = __schema_alter(int_session, uri, newcfg); + WT_TRET(__wt_meta_track_off(int_session, true, ret != 0)); +err: + WT_TRET(__wt_schema_session_release(session, int_session)); + return (ret); } |