summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsueloverso <sue@mongodb.com>2016-12-15 13:06:31 -0500
committerGitHub <noreply@github.com>2016-12-15 13:06:31 -0500
commite8d8fd81109554f7ae845b92c716ed54364b433d (patch)
tree61e71c809512dc5acab8955e62221ce825fdd48a
parent2142d32fd6b747022da2bab0cf76b30941bab918 (diff)
downloadmongo-e8d8fd81109554f7ae845b92c716ed54364b433d.tar.gz
WT-283 Add WT_SESSION::alter method (#3177)
* WT-283 Add WT_SESSION:alter method * Add new method to ex_all.c * Typo * Add testing and fixes for LSM, column groups and indexes for alter. * Fix WITH_*_LOCK macro usage. * Whitespace * Change table alter to not walk down into column groups and indexes. * Whitespace * Use base file meta config and compare strings. * Add skip stat * Add alter support to wt command. * Add util_alter.c to SConstruct * Fix subsection in doc. * Add alter thread to test/format * Swap the value we send into alter in test/format. * Add data-source alter support * Only alter access pattern hint in test/format. * Make LSM alter not exclusive. * Whitespace * Use access_pattern_hint in example. * Include base lsm metadata configuration. * Fix text/comment. * Minor changes from review comments. * Unused variable warning.
-rw-r--r--SConstruct1
-rw-r--r--build_posix/Make.base1
-rw-r--r--dist/api_data.py17
-rw-r--r--dist/filelist1
-rw-r--r--dist/stat_data.py3
-rw-r--r--examples/c/ex_all.c6
-rw-r--r--examples/c/ex_data_source.c16
-rw-r--r--lang/java/java_doc.i1
-rw-r--r--src/config/config_def.c12
-rw-r--r--src/docs/command-line.dox33
-rw-r--r--src/include/config.h67
-rw-r--r--src/include/extern.h4
-rw-r--r--src/include/stat.h3
-rw-r--r--src/include/wiredtiger.in138
-rw-r--r--src/lsm/lsm_cursor_bulk.c2
-rw-r--r--src/lsm/lsm_merge.c2
-rw-r--r--src/lsm/lsm_meta.c11
-rw-r--r--src/lsm/lsm_tree.c47
-rw-r--r--src/lsm/lsm_work_unit.c6
-rw-r--r--src/schema/schema_alter.c181
-rw-r--r--src/schema/schema_drop.c6
-rw-r--r--src/session/session_api.c38
-rw-r--r--src/support/stat.c12
-rw-r--r--src/utilities/util.h1
-rw-r--r--src/utilities/util_alter.c50
-rw-r--r--src/utilities/util_main.c5
-rw-r--r--test/format/config.h4
-rw-r--r--test/format/format.h2
-rw-r--r--test/format/ops.c9
-rw-r--r--test/format/util.c43
-rw-r--r--test/suite/test_alter01.py169
-rw-r--r--tools/wtstats/stat_data.py6
32 files changed, 792 insertions, 105 deletions
diff --git a/SConstruct b/SConstruct
index 0ccdf59babc..df7a66238e8 100644
--- a/SConstruct
+++ b/SConstruct
@@ -294,6 +294,7 @@ env.Depends(wtdll, [filelistfile, version_file])
Default(wtlib, wtdll)
wtbin = env.Program("wt", [
+ "src/utilities/util_alter.c",
"src/utilities/util_backup.c",
"src/utilities/util_cpyright.c",
"src/utilities/util_compact.c",
diff --git a/build_posix/Make.base b/build_posix/Make.base
index 5b945aca5e0..9354eb4b183 100644
--- a/build_posix/Make.base
+++ b/build_posix/Make.base
@@ -17,6 +17,7 @@ endif
bin_PROGRAMS = wt
wt_SOURCES =\
+ src/utilities/util_alter.c \
src/utilities/util_backup.c \
src/utilities/util_cpyright.c \
src/utilities/util_compact.c \
diff --git a/dist/api_data.py b/dist/api_data.py
index acbbf0f2a68..98f9b5a230a 100644
--- a/dist/api_data.py
+++ b/dist/api_data.py
@@ -118,8 +118,7 @@ lsm_config = [
]),
]
-# Per-file configuration
-file_config = format_meta + [
+file_runtime_config = [
Config('access_pattern_hint', 'none', r'''
It is recommended that workloads that consist primarily of
updates and/or point queries specify \c random. Workloads that
@@ -128,6 +127,14 @@ file_config = format_meta + [
option leads to an advisory call to an appropriate operating
system API where available''',
choices=['none', 'random', 'sequential']),
+ Config('cache_resident', 'false', r'''
+ do not ever evict the object's pages from cache. Not compatible with
+ LSM tables; see @ref tuning_cache_resident for more information''',
+ type='boolean'),
+]
+
+# Per-file configuration
+file_config = format_meta + file_runtime_config + [
Config('block_allocation', 'best', r'''
configure block allocation. Permitted values are \c "first" or
\c "best"; the \c "first" configuration uses a first-available
@@ -146,10 +153,6 @@ file_config = format_meta + [
WT_CONNECTION::add_compressor. If WiredTiger has builtin support for
\c "lz4", \c "snappy", \c "zlib" or \c "zstd" compression, these names
are also available. See @ref compression for more information'''),
- Config('cache_resident', 'false', r'''
- do not ever evict the object's pages from cache. Not compatible with
- LSM tables; see @ref tuning_cache_resident for more information''',
- type='boolean'),
Config('checksum', 'uncompressed', r'''
configure block checksums; permitted values are <code>on</code>
(checksum all blocks), <code>off</code> (checksum no blocks) and
@@ -834,6 +837,8 @@ methods = {
'WT_CURSOR.reconfigure' : Method(cursor_runtime_config),
+'WT_SESSION.alter' : Method(file_runtime_config),
+
'WT_SESSION.close' : Method([]),
'WT_SESSION.compact' : Method([
diff --git a/dist/filelist b/dist/filelist
index fe9a17b7799..13d67ef961b 100644
--- a/dist/filelist
+++ b/dist/filelist
@@ -159,6 +159,7 @@ src/packing/pack_impl.c
src/packing/pack_stream.c
src/reconcile/rec_track.c
src/reconcile/rec_write.c
+src/schema/schema_alter.c
src/schema/schema_create.c
src/schema/schema_drop.c
src/schema/schema_list.c
diff --git a/dist/stat_data.py b/dist/stat_data.py
index bcf5201bd90..022810d5c49 100644
--- a/dist/stat_data.py
+++ b/dist/stat_data.py
@@ -367,6 +367,9 @@ connection_stats = [
##########################################
SessionStat('session_cursor_open', 'open cursor count', 'no_clear,no_scale'),
SessionStat('session_open', 'open session count', 'no_clear,no_scale'),
+ SessionStat('session_table_alter_fail', 'table alter failed calls', 'no_clear,no_scale'),
+ SessionStat('session_table_alter_skip', 'table alter unchanged and skipped', 'no_clear,no_scale'),
+ SessionStat('session_table_alter_success', 'table alter successful calls', 'no_clear,no_scale'),
SessionStat('session_table_compact_fail', 'table compact failed calls', 'no_clear,no_scale'),
SessionStat('session_table_compact_success', 'table compact successful calls', 'no_clear,no_scale'),
SessionStat('session_table_create_fail', 'table create failed calls', 'no_clear,no_scale'),
diff --git a/examples/c/ex_all.c b/examples/c/ex_all.c
index ea646604a76..8a1533011b2 100644
--- a/examples/c/ex_all.c
+++ b/examples/c/ex_all.c
@@ -557,6 +557,12 @@ session_ops(WT_SESSION *session)
/*! [Create a column-store table] */
ret = session->create(session,
"table:mytable", "key_format=r,value_format=S");
+
+ /*! [Alter a table] */
+ ret = session->alter(session,
+ "table:mytable", "access_pattern_hint=random");
+ /*! [Alter a table] */
+
/*! [Create a column-store table] */
ret = session->drop(session, "table:mytable", NULL);
diff --git a/examples/c/ex_data_source.c b/examples/c/ex_data_source.c
index 6ed80dfcf19..387248f6ae2 100644
--- a/examples/c/ex_data_source.c
+++ b/examples/c/ex_data_source.c
@@ -46,6 +46,21 @@ my_data_source_init(WT_CONNECTION *connection)
}
/*! [WT_EXTENSION_API declaration] */
+/*! [WT_DATA_SOURCE alter] */
+static int
+my_alter(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
+ const char *uri, WT_CONFIG_ARG *config)
+/*! [WT_DATA_SOURCE alter] */
+{
+ /* Unused parameters */
+ (void)dsrc;
+ (void)session;
+ (void)uri;
+ (void)config;
+
+ return (0);
+}
+
/*! [WT_DATA_SOURCE create] */
static int
my_create(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
@@ -604,6 +619,7 @@ main(void)
{
/*! [WT_DATA_SOURCE register] */
static WT_DATA_SOURCE my_dsrc = {
+ my_alter,
my_create,
my_compact,
my_drop,
diff --git a/lang/java/java_doc.i b/lang/java/java_doc.i
index 2264cb31ef1..3606bed1d69 100644
--- a/lang/java/java_doc.i
+++ b/lang/java/java_doc.i
@@ -27,6 +27,7 @@ COPYDOC(__wt_async_op, WT_ASYNC_OP, remove)
COPYDOC(__wt_async_op, WT_ASYNC_OP, compact)
COPYDOC(__wt_async_op, WT_ASYNC_OP, get_id)
COPYDOC(__wt_async_op, WT_ASYNC_OP, get_type)
+COPYDOC(__wt_session, WT_SESSION, alter)
COPYDOC(__wt_session, WT_SESSION, close)
COPYDOC(__wt_session, WT_SESSION, reconfigure)
COPYDOC(__wt_session, WT_SESSION, open_cursor)
diff --git a/src/config/config_def.c b/src/config/config_def.c
index 9d886cbf0bd..e4fd7937a40 100644
--- a/src/config/config_def.c
+++ b/src/config/config_def.c
@@ -162,6 +162,14 @@ static const WT_CONFIG_CHECK confchk_WT_CURSOR_reconfigure[] = {
{ NULL, NULL, NULL, NULL, NULL, 0 }
};
+static const WT_CONFIG_CHECK confchk_WT_SESSION_alter[] = {
+ { "access_pattern_hint", "string",
+ NULL, "choices=[\"none\",\"random\",\"sequential\"]",
+ NULL, 0 },
+ { "cache_resident", "boolean", NULL, NULL, NULL, 0 },
+ { NULL, NULL, NULL, NULL, NULL, 0 }
+};
+
static const WT_CONFIG_CHECK confchk_WT_SESSION_begin_transaction[] = {
{ "isolation", "string",
NULL, "choices=[\"read-uncommitted\",\"read-committed\","
@@ -1066,6 +1074,10 @@ static const WT_CONFIG_ENTRY config_entries[] = {
"append=false,overwrite=true",
confchk_WT_CURSOR_reconfigure, 2
},
+ { "WT_SESSION.alter",
+ "access_pattern_hint=none,cache_resident=false",
+ confchk_WT_SESSION_alter, 2
+ },
{ "WT_SESSION.begin_transaction",
"isolation=,name=,priority=0,snapshot=,sync=",
confchk_WT_SESSION_begin_transaction, 5
diff --git a/src/docs/command-line.dox b/src/docs/command-line.dox
index 0f5c56d25ce..5726a1d19a1 100644
--- a/src/docs/command-line.dox
+++ b/src/docs/command-line.dox
@@ -37,6 +37,39 @@ In general, commands that modify the database or tables will run recovery
by default and commands that only read data will not run recovery.
<hr>
+@section util_alter wt alter
+Alter a table.
+
+@subsection util_alter_synopsis Synopsis
+<code>wt [-RVv] [-C config] [-E secretkey ] [-h directory] alter uri configuration ...</code>
+
+The \c uri and \c configuration pairs may be specified to the
+\c alter command. These configuration pairs can be used to modify the
+configuration values from those passed to the WT_SESSION::create
+call.
+
+The \c uri part of the configuration pair should match only one of the
+objects being altered, but may be a prefix of the object being matched.
+For example, the following two sets of configuration pairs are
+equivalent in the case of altering a single table named \c xxx.
+
+@code
+table access_pattern_hint=sequential
+table:xxx access_pattern_hint=sequential
+@endcode
+
+It's an error, however, to specify a matching prefix that matches more
+than a single object being altered.
+
+Multiple \c configuration arguments may be specified. For example, the
+following two sets of configuration pairs are equivalent:
+
+@code
+table:xxx access_pattern_hint=random,cache_resident=false
+table:xxx access_pattern_hint=random table:xxx cache_resident=false
+@endcode
+
+<hr>
@section util_backup wt backup
Perform a backup of a database or set of data sources.
diff --git a/src/include/config.h b/src/include/config.h
index 486aa50e86c..f2746fc76d9 100644
--- a/src/include/config.h
+++ b/src/include/config.h
@@ -62,39 +62,40 @@ struct __wt_config_parser_impl {
#define WT_CONFIG_ENTRY_WT_CONNECTION_set_file_system 10
#define WT_CONFIG_ENTRY_WT_CURSOR_close 11
#define WT_CONFIG_ENTRY_WT_CURSOR_reconfigure 12
-#define WT_CONFIG_ENTRY_WT_SESSION_begin_transaction 13
-#define WT_CONFIG_ENTRY_WT_SESSION_checkpoint 14
-#define WT_CONFIG_ENTRY_WT_SESSION_close 15
-#define WT_CONFIG_ENTRY_WT_SESSION_commit_transaction 16
-#define WT_CONFIG_ENTRY_WT_SESSION_compact 17
-#define WT_CONFIG_ENTRY_WT_SESSION_create 18
-#define WT_CONFIG_ENTRY_WT_SESSION_drop 19
-#define WT_CONFIG_ENTRY_WT_SESSION_join 20
-#define WT_CONFIG_ENTRY_WT_SESSION_log_flush 21
-#define WT_CONFIG_ENTRY_WT_SESSION_log_printf 22
-#define WT_CONFIG_ENTRY_WT_SESSION_open_cursor 23
-#define WT_CONFIG_ENTRY_WT_SESSION_rebalance 24
-#define WT_CONFIG_ENTRY_WT_SESSION_reconfigure 25
-#define WT_CONFIG_ENTRY_WT_SESSION_rename 26
-#define WT_CONFIG_ENTRY_WT_SESSION_reset 27
-#define WT_CONFIG_ENTRY_WT_SESSION_rollback_transaction 28
-#define WT_CONFIG_ENTRY_WT_SESSION_salvage 29
-#define WT_CONFIG_ENTRY_WT_SESSION_snapshot 30
-#define WT_CONFIG_ENTRY_WT_SESSION_strerror 31
-#define WT_CONFIG_ENTRY_WT_SESSION_transaction_sync 32
-#define WT_CONFIG_ENTRY_WT_SESSION_truncate 33
-#define WT_CONFIG_ENTRY_WT_SESSION_upgrade 34
-#define WT_CONFIG_ENTRY_WT_SESSION_verify 35
-#define WT_CONFIG_ENTRY_colgroup_meta 36
-#define WT_CONFIG_ENTRY_file_config 37
-#define WT_CONFIG_ENTRY_file_meta 38
-#define WT_CONFIG_ENTRY_index_meta 39
-#define WT_CONFIG_ENTRY_lsm_meta 40
-#define WT_CONFIG_ENTRY_table_meta 41
-#define WT_CONFIG_ENTRY_wiredtiger_open 42
-#define WT_CONFIG_ENTRY_wiredtiger_open_all 43
-#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 44
-#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 45
+#define WT_CONFIG_ENTRY_WT_SESSION_alter 13
+#define WT_CONFIG_ENTRY_WT_SESSION_begin_transaction 14
+#define WT_CONFIG_ENTRY_WT_SESSION_checkpoint 15
+#define WT_CONFIG_ENTRY_WT_SESSION_close 16
+#define WT_CONFIG_ENTRY_WT_SESSION_commit_transaction 17
+#define WT_CONFIG_ENTRY_WT_SESSION_compact 18
+#define WT_CONFIG_ENTRY_WT_SESSION_create 19
+#define WT_CONFIG_ENTRY_WT_SESSION_drop 20
+#define WT_CONFIG_ENTRY_WT_SESSION_join 21
+#define WT_CONFIG_ENTRY_WT_SESSION_log_flush 22
+#define WT_CONFIG_ENTRY_WT_SESSION_log_printf 23
+#define WT_CONFIG_ENTRY_WT_SESSION_open_cursor 24
+#define WT_CONFIG_ENTRY_WT_SESSION_rebalance 25
+#define WT_CONFIG_ENTRY_WT_SESSION_reconfigure 26
+#define WT_CONFIG_ENTRY_WT_SESSION_rename 27
+#define WT_CONFIG_ENTRY_WT_SESSION_reset 28
+#define WT_CONFIG_ENTRY_WT_SESSION_rollback_transaction 29
+#define WT_CONFIG_ENTRY_WT_SESSION_salvage 30
+#define WT_CONFIG_ENTRY_WT_SESSION_snapshot 31
+#define WT_CONFIG_ENTRY_WT_SESSION_strerror 32
+#define WT_CONFIG_ENTRY_WT_SESSION_transaction_sync 33
+#define WT_CONFIG_ENTRY_WT_SESSION_truncate 34
+#define WT_CONFIG_ENTRY_WT_SESSION_upgrade 35
+#define WT_CONFIG_ENTRY_WT_SESSION_verify 36
+#define WT_CONFIG_ENTRY_colgroup_meta 37
+#define WT_CONFIG_ENTRY_file_config 38
+#define WT_CONFIG_ENTRY_file_meta 39
+#define WT_CONFIG_ENTRY_index_meta 40
+#define WT_CONFIG_ENTRY_lsm_meta 41
+#define WT_CONFIG_ENTRY_table_meta 42
+#define WT_CONFIG_ENTRY_wiredtiger_open 43
+#define WT_CONFIG_ENTRY_wiredtiger_open_all 44
+#define WT_CONFIG_ENTRY_wiredtiger_open_basecfg 45
+#define WT_CONFIG_ENTRY_wiredtiger_open_usercfg 46
/*
* configuration section: END
* DO NOT EDIT: automatically built by dist/flags.py.
diff --git a/src/include/extern.h b/src/include/extern.h
index c7506e55976..be042bcd6cb 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -423,7 +423,7 @@ extern int __wt_lsm_manager_push_entry(WT_SESSION_IMPL *session, uint32_t type,
extern int __wt_lsm_merge_update_tree(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int start_chunk, u_int nchunks, WT_LSM_CHUNK *chunk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int id) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_lsm_meta_read(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
-extern int __wt_lsm_meta_write(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_lsm_meta_write(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, const char *newconfig) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_curstat_lsm_init( WT_SESSION_IMPL *session, const char *uri, WT_CURSOR_STAT *cst) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_lsm_tree_close_all(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_lsm_tree_bloom_name(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, uint32_t id, const char **retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -437,6 +437,7 @@ extern void __wt_lsm_tree_release(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tre
extern void __wt_lsm_tree_throttle( WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, bool decrease_only) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_lsm_tree_switch(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_lsm_tree_retire_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int start_chunk, u_int nchunks) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_lsm_tree_alter( WT_SESSION_IMPL *session, const char *uri, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_lsm_tree_drop( WT_SESSION_IMPL *session, const char *name, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_lsm_tree_rename(WT_SESSION_IMPL *session, const char *olduri, const char *newuri, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_lsm_tree_truncate( WT_SESSION_IMPL *session, const char *name, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
@@ -551,6 +552,7 @@ extern int __wt_bulk_insert_row(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk)
extern int __wt_bulk_insert_fix( WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk, bool deleted) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_bulk_insert_fix_bitmap(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_bulk_insert_var( WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk, bool deleted) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
+extern int __wt_schema_alter(WT_SESSION_IMPL *session, const char *uri, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_direct_io_size_check(WT_SESSION_IMPL *session, const char **cfg, const char *config_name, uint32_t *allocsizep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_schema_colgroup_source(WT_SESSION_IMPL *session, WT_TABLE *table, const char *cgname, const char *config, WT_ITEM *buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
extern int __wt_schema_index_source(WT_SESSION_IMPL *session, WT_TABLE *table, const char *idxname, const char *config, WT_ITEM *buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)) WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("hidden")));
diff --git a/src/include/stat.h b/src/include/stat.h
index e53414fc0c9..0daab83e166 100644
--- a/src/include/stat.h
+++ b/src/include/stat.h
@@ -445,6 +445,9 @@ struct __wt_connection_stats {
int64_t rec_split_stashed_objects;
int64_t session_cursor_open;
int64_t session_open;
+ int64_t session_table_alter_fail;
+ int64_t session_table_alter_success;
+ int64_t session_table_alter_skip;
int64_t session_table_compact_fail;
int64_t session_table_compact_success;
int64_t session_table_create_fail;
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index 4c72df0f073..a6deed7e14e 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -800,6 +800,34 @@ struct __wt_session {
#endif
/*!
+ * Alter a table.
+ *
+ * This will allow modification of some table settings after
+ * creation.
+ *
+ * @snippet ex_all.c Alter a table
+ *
+ * @param session the session handle
+ * @param name the URI of the object to alter, such as \c "table:stock"
+ * @configstart{WT_SESSION.alter, see dist/api_data.py}
+ * @config{access_pattern_hint, It is recommended that workloads that
+ * consist primarily of updates and/or point queries specify \c random.
+ * Workloads that do many cursor scans through large ranges of data
+ * specify \c sequential and other workloads specify \c none. The
+ * option leads to an advisory call to an appropriate operating system
+ * API where available., a string\, chosen from the following options:
+ * \c "none"\, \c "random"\, \c "sequential"; default \c none.}
+ * @config{cache_resident, do not ever evict the object's pages from
+ * cache. Not compatible with LSM tables; see @ref
+ * tuning_cache_resident for more information., a boolean flag; default
+ * \c false.}
+ * @configend
+ * @errors
+ */
+ int __F(alter)(WT_HANDLE_CLOSED(WT_SESSION) *session,
+ const char *name, const char *config);
+
+ /*!
* Close the session handle.
*
* This will release the resources associated with the session handle,
@@ -3437,6 +3465,14 @@ struct __wt_compressor {
*/
struct __wt_data_source {
/*!
+ * Callback to alter an object.
+ *
+ * @snippet ex_data_source.c WT_DATA_SOURCE alter
+ */
+ int (*alter)(WT_DATA_SOURCE *dsrc, WT_SESSION *session,
+ const char *uri, WT_CONFIG_ARG *config);
+
+ /*!
* Callback to create a new object.
*
* @snippet ex_data_source.c WT_DATA_SOURCE create
@@ -4669,114 +4705,120 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection);
#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1186
/*! session: open session count */
#define WT_STAT_CONN_SESSION_OPEN 1187
+/*! session: table alter failed calls */
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_FAIL 1188
+/*! session: table alter successful calls */
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_SUCCESS 1189
+/*! session: table alter unchanged and skipped */
+#define WT_STAT_CONN_SESSION_TABLE_ALTER_SKIP 1190
/*! session: table compact failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1188
+#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1191
/*! session: table compact successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1189
+#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1192
/*! session: table create failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1190
+#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1193
/*! session: table create successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1191
+#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1194
/*! session: table drop failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1192
+#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1195
/*! session: table drop successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1193
+#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1196
/*! session: table rebalance failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_FAIL 1194
+#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_FAIL 1197
/*! session: table rebalance successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_SUCCESS 1195
+#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_SUCCESS 1198
/*! session: table rename failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_RENAME_FAIL 1196
+#define WT_STAT_CONN_SESSION_TABLE_RENAME_FAIL 1199
/*! session: table rename successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_RENAME_SUCCESS 1197
+#define WT_STAT_CONN_SESSION_TABLE_RENAME_SUCCESS 1200
/*! session: table salvage failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1198
+#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1201
/*! session: table salvage successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1199
+#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1202
/*! session: table truncate failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1200
+#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1203
/*! session: table truncate successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1201
+#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1204
/*! session: table verify failed calls */
-#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1202
+#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1205
/*! session: table verify successful calls */
-#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1203
+#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1206
/*! thread-state: active filesystem fsync calls */
-#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1204
+#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1207
/*! thread-state: active filesystem read calls */
-#define WT_STAT_CONN_THREAD_READ_ACTIVE 1205
+#define WT_STAT_CONN_THREAD_READ_ACTIVE 1208
/*! thread-state: active filesystem write calls */
-#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1206
+#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1209
/*! thread-yield: application thread time evicting (usecs) */
-#define WT_STAT_CONN_APPLICATION_EVICT_TIME 1207
+#define WT_STAT_CONN_APPLICATION_EVICT_TIME 1210
/*! thread-yield: application thread time waiting for cache (usecs) */
-#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1208
+#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1211
/*! thread-yield: page acquire busy blocked */
-#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1209
+#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1212
/*! thread-yield: page acquire eviction blocked */
-#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1210
+#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1213
/*! thread-yield: page acquire locked blocked */
-#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1211
+#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1214
/*! thread-yield: page acquire read blocked */
-#define WT_STAT_CONN_PAGE_READ_BLOCKED 1212
+#define WT_STAT_CONN_PAGE_READ_BLOCKED 1215
/*! thread-yield: page acquire time sleeping (usecs) */
-#define WT_STAT_CONN_PAGE_SLEEP 1213
+#define WT_STAT_CONN_PAGE_SLEEP 1216
/*! transaction: number of named snapshots created */
-#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1214
+#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1217
/*! transaction: number of named snapshots dropped */
-#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1215
+#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1218
/*! transaction: transaction begins */
-#define WT_STAT_CONN_TXN_BEGIN 1216
+#define WT_STAT_CONN_TXN_BEGIN 1219
/*! transaction: transaction checkpoint currently running */
-#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1217
+#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1220
/*! transaction: transaction checkpoint generation */
-#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1218
+#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1221
/*! transaction: transaction checkpoint max time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1219
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1222
/*! transaction: transaction checkpoint min time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1220
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1223
/*! transaction: transaction checkpoint most recent time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1221
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1224
/*! transaction: transaction checkpoint scrub dirty target */
-#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TARGET 1222
+#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TARGET 1225
/*! transaction: transaction checkpoint scrub time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TIME 1223
+#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TIME 1226
/*! transaction: transaction checkpoint total time (msecs) */
-#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1224
+#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1227
/*! transaction: transaction checkpoints */
-#define WT_STAT_CONN_TXN_CHECKPOINT 1225
+#define WT_STAT_CONN_TXN_CHECKPOINT 1228
/*!
* transaction: transaction checkpoints skipped because database was
* clean
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_SKIPPED 1226
+#define WT_STAT_CONN_TXN_CHECKPOINT_SKIPPED 1229
/*! transaction: transaction failures due to cache overflow */
-#define WT_STAT_CONN_TXN_FAIL_CACHE 1227
+#define WT_STAT_CONN_TXN_FAIL_CACHE 1230
/*!
* transaction: transaction fsync calls for checkpoint after allocating
* the transaction ID
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1228
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1231
/*!
* transaction: transaction fsync duration for checkpoint after
* allocating the transaction ID (usecs)
*/
-#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1229
+#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1232
/*! transaction: transaction range of IDs currently pinned */
-#define WT_STAT_CONN_TXN_PINNED_RANGE 1230
+#define WT_STAT_CONN_TXN_PINNED_RANGE 1233
/*! transaction: transaction range of IDs currently pinned by a checkpoint */
-#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1231
+#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1234
/*!
* transaction: transaction range of IDs currently pinned by named
* snapshots
*/
-#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1232
+#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1235
/*! transaction: transaction sync calls */
-#define WT_STAT_CONN_TXN_SYNC 1233
+#define WT_STAT_CONN_TXN_SYNC 1236
/*! transaction: transactions committed */
-#define WT_STAT_CONN_TXN_COMMIT 1234
+#define WT_STAT_CONN_TXN_COMMIT 1237
/*! transaction: transactions rolled back */
-#define WT_STAT_CONN_TXN_ROLLBACK 1235
+#define WT_STAT_CONN_TXN_ROLLBACK 1238
/*!
* @}
diff --git a/src/lsm/lsm_cursor_bulk.c b/src/lsm/lsm_cursor_bulk.c
index bae8206515e..7a6a40e380f 100644
--- a/src/lsm/lsm_cursor_bulk.c
+++ b/src/lsm/lsm_cursor_bulk.c
@@ -45,7 +45,7 @@ __clsm_close_bulk(WT_CURSOR *cursor)
total_chunks /= avg_chunks)
++chunk->generation;
- WT_RET(__wt_lsm_meta_write(session, lsm_tree));
+ WT_RET(__wt_lsm_meta_write(session, lsm_tree, NULL));
++lsm_tree->dsk_gen;
/* Close the LSM cursor */
diff --git a/src/lsm/lsm_merge.c b/src/lsm/lsm_merge.c
index f05a9c4b2b7..ceb5f03a2f5 100644
--- a/src/lsm/lsm_merge.c
+++ b/src/lsm/lsm_merge.c
@@ -579,7 +579,7 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int id)
* Any errors that happened after the tree was locked are
* fatal - we can't guarantee the state of the tree.
*/
- if ((ret = __wt_lsm_meta_write(session, lsm_tree)) != 0)
+ if ((ret = __wt_lsm_meta_write(session, lsm_tree, NULL)) != 0)
WT_PANIC_ERR(session, ret, "Failed finalizing LSM merge");
lsm_tree->dsk_gen++;
diff --git a/src/lsm/lsm_meta.c b/src/lsm/lsm_meta.c
index ec52af96231..46ead6d6ac4 100644
--- a/src/lsm/lsm_meta.c
+++ b/src/lsm/lsm_meta.c
@@ -454,13 +454,14 @@ __wt_lsm_meta_read(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
* Write the metadata for an LSM tree.
*/
int
-__wt_lsm_meta_write(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
+__wt_lsm_meta_write(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree,
+ const char *newconfig)
{
WT_DECL_ITEM(buf);
WT_DECL_RET;
WT_LSM_CHUNK *chunk;
u_int i;
- const char *new_cfg[] = { NULL, NULL, NULL };
+ const char *new_cfg[] = { NULL, NULL, NULL, NULL, NULL };
char *new_metadata;
bool first;
@@ -504,8 +505,10 @@ __wt_lsm_meta_write(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
WT_ERR(__wt_buf_catfmt(session, buf, "]"));
/* Update the existing configuration with the new values. */
- new_cfg[0] = lsm_tree->config;
- new_cfg[1] = buf->data;
+ new_cfg[0] = WT_CONFIG_BASE(session, lsm_meta);
+ new_cfg[1] = lsm_tree->config;
+ new_cfg[2] = buf->data;
+ new_cfg[3] = newconfig;
WT_ERR(__wt_config_collapse(session, new_cfg, &new_metadata));
ret = __wt_metadata_update(session, lsm_tree->name, new_metadata);
WT_ERR(ret);
diff --git a/src/lsm/lsm_tree.c b/src/lsm/lsm_tree.c
index b0616fb8ec1..38d87dd852b 100644
--- a/src/lsm/lsm_tree.c
+++ b/src/lsm/lsm_tree.c
@@ -756,7 +756,7 @@ __wt_lsm_tree_switch(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
lsm_tree->chunk[lsm_tree->nchunks++] = chunk;
WT_ERR(__wt_lsm_tree_setup_chunk(session, lsm_tree, chunk));
- WT_ERR(__wt_lsm_meta_write(session, lsm_tree));
+ WT_ERR(__wt_lsm_meta_write(session, lsm_tree, NULL));
lsm_tree->need_switch = false;
++lsm_tree->dsk_gen;
@@ -841,6 +841,47 @@ __wt_lsm_tree_retire_chunks(WT_SESSION_IMPL *session,
}
/*
+ * __wt_lsm_tree_alter --
+ * Alter an LSM tree.
+ */
+int
+__wt_lsm_tree_alter(
+ WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
+{
+ WT_DECL_RET;
+ WT_LSM_CHUNK *chunk;
+ WT_LSM_TREE *lsm_tree;
+ u_int i;
+ bool locked;
+
+ locked = false;
+
+ /* Get the LSM tree. */
+ WT_WITH_HANDLE_LIST_LOCK(session,
+ ret = __wt_lsm_tree_get(session, uri, false, &lsm_tree));
+ WT_RET(ret);
+
+ /* Prevent any new opens. */
+ __wt_lsm_tree_writelock(session, lsm_tree);
+ locked = true;
+
+ /* Alter the chunks. */
+ for (i = 0; i < lsm_tree->nchunks; i++) {
+ chunk = lsm_tree->chunk[i];
+ WT_ERR(__wt_schema_alter(session, chunk->uri, cfg));
+ if (F_ISSET(chunk, WT_LSM_CHUNK_BLOOM))
+ WT_ERR(
+ __wt_schema_alter(session, chunk->bloom_uri, cfg));
+ }
+ WT_ERR(__wt_lsm_meta_write(session, lsm_tree, cfg[0]));
+
+err: if (locked)
+ __wt_lsm_tree_writeunlock(session, lsm_tree);
+ __wt_lsm_tree_release(session, lsm_tree);
+ return (ret);
+}
+
+/*
* __wt_lsm_tree_drop --
* Drop an LSM tree.
*/
@@ -953,7 +994,7 @@ __wt_lsm_tree_rename(WT_SESSION_IMPL *session,
}
}
- WT_ERR(__wt_lsm_meta_write(session, lsm_tree));
+ WT_ERR(__wt_lsm_meta_write(session, lsm_tree, NULL));
locked = false;
__wt_lsm_tree_writeunlock(session, lsm_tree);
WT_ERR(__wt_metadata_remove(session, olduri));
@@ -1008,7 +1049,7 @@ __wt_lsm_tree_truncate(
WT_ERR(__wt_lsm_merge_update_tree(
session, lsm_tree, 0, lsm_tree->nchunks, chunk));
- WT_ERR(__wt_lsm_meta_write(session, lsm_tree));
+ WT_ERR(__wt_lsm_meta_write(session, lsm_tree, NULL));
locked = false;
__wt_lsm_tree_writeunlock(session, lsm_tree);
diff --git a/src/lsm/lsm_work_unit.c b/src/lsm/lsm_work_unit.c
index f3414363e3e..d9c185a3f58 100644
--- a/src/lsm/lsm_work_unit.c
+++ b/src/lsm/lsm_work_unit.c
@@ -364,7 +364,7 @@ __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session,
/* Lock the tree, mark the chunk as on disk and update the metadata. */
__wt_lsm_tree_writelock(session, lsm_tree);
F_SET(chunk, WT_LSM_CHUNK_ONDISK);
- ret = __wt_lsm_meta_write(session, lsm_tree);
+ ret = __wt_lsm_meta_write(session, lsm_tree, NULL);
++lsm_tree->dsk_gen;
/* Update the throttle time. */
@@ -469,7 +469,7 @@ __lsm_bloom_create(WT_SESSION_IMPL *session,
/* Ensure the bloom filter is in the metadata. */
__wt_lsm_tree_writelock(session, lsm_tree);
F_SET(chunk, WT_LSM_CHUNK_BLOOM);
- ret = __wt_lsm_meta_write(session, lsm_tree);
+ ret = __wt_lsm_meta_write(session, lsm_tree, NULL);
++lsm_tree->dsk_gen;
__wt_lsm_tree_writeunlock(session, lsm_tree);
@@ -659,7 +659,7 @@ __wt_lsm_free_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
err: /* Flush the metadata unless the system is in panic */
if (flush_metadata && ret != WT_PANIC) {
__wt_lsm_tree_writelock(session, lsm_tree);
- WT_TRET(__wt_lsm_meta_write(session, lsm_tree));
+ WT_TRET(__wt_lsm_meta_write(session, lsm_tree, NULL));
__wt_lsm_tree_writeunlock(session, lsm_tree);
}
__lsm_unpin_chunks(session, &cookie);
diff --git a/src/schema/schema_alter.c b/src/schema/schema_alter.c
new file mode 100644
index 00000000000..e8b619737ed
--- /dev/null
+++ b/src/schema/schema_alter.c
@@ -0,0 +1,181 @@
+/*-
+ * Copyright (c) 2014-2016 MongoDB, Inc.
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __alter_file --
+ * Alter a file.
+ */
+static int
+__alter_file(
+ WT_SESSION_IMPL *session, const char *uri, const char *newcfg[])
+{
+ WT_DECL_RET;
+ const char *cfg[4], *filename;
+ char *config, *newconfig;
+
+ filename = uri;
+ newconfig = NULL;
+ if (!WT_PREFIX_SKIP(filename, "file:"))
+ return (__wt_unexpected_object_type(session, uri, "file:"));
+
+ /* 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] = WT_CONFIG_BASE(session, file_meta);
+ 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);
+ return (ret);
+}
+
+/*
+ * __alter_colgroup --
+ * WT_SESSION::alter for a colgroup.
+ */
+static int
+__alter_colgroup(
+ WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
+{
+ WT_COLGROUP *colgroup;
+ WT_DECL_RET;
+
+ WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_TABLE));
+
+ /* If we can get the colgroup, perform any potential alterations. */
+ if ((ret = __wt_schema_get_colgroup(
+ session, uri, false, NULL, &colgroup)) == 0)
+ WT_TRET(__wt_schema_alter(session, colgroup->source, cfg));
+
+ return (ret);
+}
+
+/*
+ * __alter_index --
+ * WT_SESSION::alter for an index.
+ */
+static int
+__alter_index(
+ WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
+{
+ WT_INDEX *idx;
+ WT_DECL_RET;
+
+ /* If we can get the index, perform any potential alterations. */
+ if ((ret = __wt_schema_get_index(
+ session, uri, false, NULL, &idx)) == 0)
+ WT_TRET(__wt_schema_alter(session, idx->source, cfg));
+
+ return (ret);
+}
+
+/*
+ * __alter_table --
+ * WT_SESSION::alter for a table.
+ */
+static int
+__alter_table(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
+{
+ WT_COLGROUP *colgroup;
+ WT_DECL_RET;
+ WT_TABLE *table;
+ const char *name;
+ u_int i;
+
+ name = uri;
+ (void)WT_PREFIX_SKIP(name, "table:");
+
+ WT_RET(__wt_schema_get_table(
+ session, name, strlen(name), true, &table));
+
+ /*
+ * Alter the column groups only if we are using the default
+ * column group. Otherwise the user should alter each
+ * index or column group explicitly.
+ */
+ if (table->ncolgroups == 0)
+ for (i = 0; i < WT_COLGROUPS(table); i++) {
+ if ((colgroup = table->cgroups[i]) == NULL)
+ continue;
+ /*
+ * Alter the column group before updating the metadata
+ * to avoid the metadata for the table becoming
+ * inconsistent if we can't get exclusive access.
+ */
+ WT_ERR(__wt_schema_alter(
+ session, colgroup->source, cfg));
+ }
+err: __wt_schema_release_table(session, table);
+ return (ret);
+}
+
+/*
+ * __wt_schema_alter --
+ * Process a WT_SESSION::alter operation for all supported types.
+ */
+int
+__wt_schema_alter(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
+{
+ WT_DATA_SOURCE *dsrc;
+ WT_DECL_RET;
+
+ WT_RET(__wt_meta_track_on(session));
+
+ /* Paranoia: clear any handle from our caller. */
+ session->dhandle = NULL;
+
+ if (WT_PREFIX_MATCH(uri, "colgroup:"))
+ ret = __alter_colgroup(session, uri, cfg);
+ else if (WT_PREFIX_MATCH(uri, "file:"))
+ ret = __alter_file(session, uri, cfg);
+ else if (WT_PREFIX_MATCH(uri, "index:"))
+ ret = __alter_index(session, uri, cfg);
+ else if (WT_PREFIX_MATCH(uri, "lsm:"))
+ ret = __wt_lsm_tree_alter(session, uri, cfg);
+ else if (WT_PREFIX_MATCH(uri, "table:"))
+ ret = __alter_table(session, uri, cfg);
+ else if ((dsrc = __wt_schema_get_source(session, uri)) != NULL)
+ ret = dsrc->alter == NULL ?
+ __wt_object_unsupported(session, uri) :
+ dsrc->alter(dsrc,
+ &session->iface, uri, (WT_CONFIG_ARG *)cfg);
+ else
+ ret = __wt_bad_object_type(session, uri);
+
+ /*
+ * Map WT_NOTFOUND to ENOENT, based on the assumption WT_NOTFOUND means
+ * there was no metadata entry.
+ */
+ if (ret == WT_NOTFOUND)
+ ret = ENOENT;
+
+ /* Bump the schema generation so that stale data is ignored. */
+ ++S2C(session)->schema_gen;
+
+ WT_TRET(__wt_meta_track_off(session, true, ret != 0));
+
+ return (ret);
+}
diff --git a/src/schema/schema_drop.c b/src/schema/schema_drop.c
index 65c955cf1e9..c1a4f257648 100644
--- a/src/schema/schema_drop.c
+++ b/src/schema/schema_drop.c
@@ -75,7 +75,7 @@ __drop_colgroup(
/*
* __drop_index --
- * WT_SESSION::drop for a colgroup.
+ * WT_SESSION::drop for an index.
*/
static int
__drop_index(
@@ -85,7 +85,7 @@ __drop_index(
WT_DECL_RET;
WT_TABLE *table;
- /* If we can get the colgroup, detach it from the table. */
+ /* If we can get the index, detach it from the table. */
if ((ret = __wt_schema_get_index(
session, uri, force, &table, &idx)) == 0) {
table->idx_complete = false;
@@ -136,7 +136,7 @@ __drop_table(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
if ((idx = table->indices[i]) == NULL)
continue;
/*
- * Drop the column group before updating the metadata to avoid
+ * Drop the index before updating the metadata to avoid
* the metadata for the table becoming inconsistent if we can't
* get exclusive access.
*/
diff --git a/src/session/session_api.c b/src/session/session_api.c
index 88a3c32ee11..fe1bf821d3b 100644
--- a/src/session/session_api.c
+++ b/src/session/session_api.c
@@ -137,6 +137,42 @@ __session_clear(WT_SESSION_IMPL *session)
}
/*
+ * __session_alter --
+ * Alter a table setting.
+ */
+static int
+__session_alter(WT_SESSION *wt_session, const char *uri, const char *config)
+{
+ WT_DECL_RET;
+ WT_SESSION_IMPL *session;
+
+ session = (WT_SESSION_IMPL *)wt_session;
+
+ SESSION_API_CALL(session, alter, config, cfg);
+
+ /* Disallow objects in the WiredTiger name space. */
+ WT_ERR(__wt_str_name_check(session, uri));
+
+ /*
+ * We replace the default configuration listing with the current
+ * configuration. Otherwise the defaults for values that can be
+ * altered would override settings used by the user in create.
+ */
+ cfg[0] = cfg[1];
+ cfg[1] = NULL;
+ WT_WITH_CHECKPOINT_LOCK(session,
+ WT_WITH_SCHEMA_LOCK(session,
+ WT_WITH_TABLE_LOCK(session,
+ ret = __wt_schema_alter(session, uri, cfg))));
+
+err: if (ret != 0)
+ WT_STAT_CONN_INCR(session, session_table_alter_fail);
+ else
+ WT_STAT_CONN_INCR(session, session_table_alter_success);
+ API_END_RET_NOTFOUND_MAP(session, ret);
+}
+
+/*
* __session_close --
* WT_SESSION->close method.
*/
@@ -1691,6 +1727,7 @@ __open_session(WT_CONNECTION_IMPL *conn,
static const WT_SESSION stds = {
NULL,
NULL,
+ __session_alter,
__session_close,
__session_reconfigure,
__wt_session_strerror,
@@ -1718,6 +1755,7 @@ __open_session(WT_CONNECTION_IMPL *conn,
}, stds_readonly = {
NULL,
NULL,
+ __session_alter,
__session_close,
__session_reconfigure,
__wt_session_strerror,
diff --git a/src/support/stat.c b/src/support/stat.c
index 5acd9fc713f..a9c0b24ef29 100644
--- a/src/support/stat.c
+++ b/src/support/stat.c
@@ -808,6 +808,9 @@ static const char * const __stats_connection_desc[] = {
"reconciliation: split objects currently awaiting free",
"session: open cursor count",
"session: open session count",
+ "session: table alter failed calls",
+ "session: table alter successful calls",
+ "session: table alter unchanged and skipped",
"session: table compact failed calls",
"session: table compact successful calls",
"session: table create failed calls",
@@ -1086,6 +1089,9 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats)
/* not clearing rec_split_stashed_objects */
/* not clearing session_cursor_open */
/* not clearing session_open */
+ /* not clearing session_table_alter_fail */
+ /* not clearing session_table_alter_success */
+ /* not clearing session_table_alter_skip */
/* not clearing session_table_compact_fail */
/* not clearing session_table_compact_success */
/* not clearing session_table_create_fail */
@@ -1397,6 +1403,12 @@ __wt_stat_connection_aggregate(
WT_STAT_READ(from, rec_split_stashed_objects);
to->session_cursor_open += WT_STAT_READ(from, session_cursor_open);
to->session_open += WT_STAT_READ(from, session_open);
+ to->session_table_alter_fail +=
+ WT_STAT_READ(from, session_table_alter_fail);
+ to->session_table_alter_success +=
+ WT_STAT_READ(from, session_table_alter_success);
+ to->session_table_alter_skip +=
+ WT_STAT_READ(from, session_table_alter_skip);
to->session_table_compact_fail +=
WT_STAT_READ(from, session_table_compact_fail);
to->session_table_compact_success +=
diff --git a/src/utilities/util.h b/src/utilities/util.h
index c2cf6c22aa4..2658d877b63 100644
--- a/src/utilities/util.h
+++ b/src/utilities/util.h
@@ -26,6 +26,7 @@ extern int __wt_optopt; /* character checked for validity */
extern int __wt_optreset; /* reset getopt */
extern char *__wt_optarg; /* argument associated with option */
+int util_alter(WT_SESSION *, int, char *[]);
int util_backup(WT_SESSION *, int, char *[]);
int util_cerr(WT_CURSOR *, const char *, int);
int util_compact(WT_SESSION *, int, char *[]);
diff --git a/src/utilities/util_alter.c b/src/utilities/util_alter.c
new file mode 100644
index 00000000000..d228c15cd48
--- /dev/null
+++ b/src/utilities/util_alter.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2014-2016 MongoDB, Inc.
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "util.h"
+
+static int usage(void);
+
+int
+util_alter(WT_SESSION *session, int argc, char *argv[])
+{
+ WT_DECL_RET;
+ int ch;
+ char **configp;
+
+ while ((ch = __wt_getopt(progname, argc, argv, "")) != EOF)
+ switch (ch) {
+ case '?':
+ default:
+ return (usage());
+ }
+
+ argc -= __wt_optind;
+ argv += __wt_optind;
+
+ /* The remaining arguments are uri/string pairs. */
+ if (argc % 2 != 0)
+ return (usage());
+
+ for (configp = argv;
+ configp != NULL && *configp != NULL; configp += 2)
+ if ((ret = session->alter(
+ session, configp[0], configp[1])) != 0)
+ break;
+ return (ret);
+}
+
+static int
+usage(void)
+{
+ (void)fprintf(stderr,
+ "usage: %s %s "
+ "alter uri configuration ...\n",
+ progname, usage_prefix);
+ return (1);
+}
diff --git a/src/utilities/util_main.c b/src/utilities/util_main.c
index 2054b94e3ce..1da56adf137 100644
--- a/src/utilities/util_main.c
+++ b/src/utilities/util_main.c
@@ -117,6 +117,10 @@ main(int argc, char *argv[])
func = NULL;
switch (command[0]) {
+ case 'a':
+ if (strcmp(command, "alter") == 0)
+ func = util_alter;
+ break;
case 'b':
if (strcmp(command, "backup") == 0)
func = util_backup;
@@ -252,6 +256,7 @@ usage(void)
"\t" "-v\t" "verbose\n");
fprintf(stderr,
"commands:\n"
+ "\t" "alter\t alter an object\n"
"\t" "backup\t database backup\n"
"\t" "compact\t compact an object\n"
"\t" "copyright copyright information\n"
diff --git a/test/format/config.h b/test/format/config.h
index 9bfba3cd0df..e4f7af2e1b2 100644
--- a/test/format/config.h
+++ b/test/format/config.h
@@ -65,6 +65,10 @@ static CONFIG c[] = {
"if timed run should drop core", /* 0% */
C_BOOL, 0, 0, 0, &g.c_abort, NULL },
+ { "alter",
+ "if altering the table is enabled", /* 10% */
+ C_BOOL, 10, 0, 0, &g.c_alter, NULL },
+
{ "auto_throttle",
"if LSM inserts are throttled", /* 90% */
C_BOOL, 90, 0, 0, &g.c_auto_throttle, NULL },
diff --git a/test/format/format.h b/test/format/format.h
index 530156fe661..c1f4875dbb2 100644
--- a/test/format/format.h
+++ b/test/format/format.h
@@ -140,6 +140,7 @@ typedef struct {
char *config_open; /* Command-line configuration */
uint32_t c_abort; /* Config values */
+ uint32_t c_alter;
uint32_t c_auto_throttle;
uint32_t c_backups;
uint32_t c_bitcnt;
@@ -276,6 +277,7 @@ void bdb_remove(uint64_t, int *);
void bdb_update(const void *, size_t, const void *, size_t);
#endif
+void *alter(void *);
void *backup(void *);
void *compact(void *);
void config_clear(void);
diff --git a/test/format/ops.c b/test/format/ops.c
index b50ce3c2e2f..940318c87a9 100644
--- a/test/format/ops.c
+++ b/test/format/ops.c
@@ -53,7 +53,7 @@ wts_ops(int lastrun)
TINFO **tinfo_list, *tinfo, total;
WT_CONNECTION *conn;
WT_SESSION *session;
- pthread_t backup_tid, compact_tid, lrt_tid;
+ pthread_t alter_tid, backup_tid, compact_tid, lrt_tid;
int64_t fourths, thread_ops;
uint32_t i;
int running;
@@ -61,6 +61,7 @@ wts_ops(int lastrun)
conn = g.wts_conn;
session = NULL; /* -Wconditional-uninitialized */
+ memset(&alter_tid, 0, sizeof(alter_tid));
memset(&backup_tid, 0, sizeof(backup_tid));
memset(&compact_tid, 0, sizeof(compact_tid));
memset(&lrt_tid, 0, sizeof(lrt_tid));
@@ -118,6 +119,8 @@ wts_ops(int lastrun)
* If a multi-threaded run, start optional backup, compaction and
* long-running reader threads.
*/
+ if (g.c_alter)
+ testutil_check(pthread_create(&alter_tid, NULL, alter, NULL));
if (g.c_backups)
testutil_check(pthread_create(&backup_tid, NULL, backup, NULL));
if (g.c_compact)
@@ -183,6 +186,8 @@ wts_ops(int lastrun)
/* Wait for the backup, compaction, long-running reader threads. */
g.workers_finished = 1;
+ if (g.c_alter)
+ (void)pthread_join(alter_tid, NULL);
if (g.c_backups)
(void)pthread_join(backup_tid, NULL);
if (g.c_compact)
@@ -461,7 +466,7 @@ ops(void *arg)
* 10% of the time, perform some read-only operations
* from a checkpoint.
*
- * Skip that if we single-threaded and doing checks
+ * Skip that if we are single-threaded and doing checks
* against a Berkeley DB database, because that won't
* work because the Berkeley DB database records won't
* match the checkpoint. Also skip if we are using
diff --git a/test/format/util.c b/test/format/util.c
index a709aa93a2e..2575130e4bb 100644
--- a/test/format/util.c
+++ b/test/format/util.c
@@ -459,3 +459,46 @@ fclose_and_clear(FILE **fpp)
testutil_die(errno, "fclose");
return;
}
+
+/*
+ * alter --
+ * Periodically alter a table's metadata.
+ */
+void *
+alter(void *arg)
+{
+ WT_CONNECTION *conn;
+ WT_DECL_RET;
+ WT_SESSION *session;
+ u_int period;
+ bool access;
+ char buf[32];
+
+ (void)(arg);
+ conn = g.wts_conn;
+
+ /*
+ * Only alter the access pattern hint. If we alter the
+ * cache resident setting we may end up with a setting that
+ * fills cache and doesn't allow it to be evicted.
+ */
+ access = false;
+ /* Open a session */
+ testutil_check(conn->open_session(conn, NULL, NULL, &session));
+
+ while (!g.workers_finished) {
+ period = mmrand(NULL, 1, 10);
+
+ snprintf(buf, 32, "access_pattern_hint=%s",
+ access ? "random" : "none");
+ access = !access;
+ if ((ret = session->alter(session, g.uri, buf)) != 0)
+ break;
+ while (period > 0 && !g.workers_finished) {
+ --period;
+ sleep(1);
+ }
+ }
+ testutil_check(session->close(session, NULL));
+ return (NULL);
+}
diff --git a/test/suite/test_alter01.py b/test/suite/test_alter01.py
new file mode 100644
index 00000000000..dfdf6b7a17e
--- /dev/null
+++ b/test/suite/test_alter01.py
@@ -0,0 +1,169 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-2016 MongoDB, Inc.
+# Public Domain 2008-2014 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+import wiredtiger, wttest
+from wtscenario import make_scenarios
+
+# test_alter01.py
+# Smoke-test the session alter operations.
+class test_alter01(wttest.WiredTigerTestCase):
+ name = "alter01"
+ entries = 100
+ # Settings for access_pattern_hint
+ types = [
+ ('file', dict(uri='file:', use_cg=False, use_index=False)),
+ ('lsm', dict(uri='lsm:', use_cg=False, use_index=False)),
+ ('table-cg', dict(uri='table:', use_cg=True, use_index=False)),
+ ('table-index', dict(uri='table:', use_cg=False, use_index=True)),
+ ('table-simple', dict(uri='table:', use_cg=False, use_index=False)),
+ ]
+ hints = [
+ ('default', dict(acreate='')),
+ ('none', dict(acreate='none')),
+ ('random', dict(acreate='random')),
+ ('sequential', dict(acreate='sequential')),
+ ]
+ access_alter=('', 'none', 'random', 'sequential')
+ # Settings for cache_resident
+ resid = [
+ ('default', dict(ccreate='')),
+ ('false', dict(ccreate='false')),
+ ('true', dict(ccreate='true')),
+ ]
+ reopen = [
+ ('no-reopen', dict(reopen=False)),
+ ('reopen', dict(reopen=True)),
+ ]
+ cache_alter=('', 'false', 'true')
+ scenarios = make_scenarios(types, hints, resid, reopen)
+
+ def verify_metadata(self, metastr):
+ if metastr == '':
+ return
+ cursor = self.session.open_cursor('metadata:', None, None)
+ #
+ # Walk through all the metadata looking for the entries that are
+ # the file URIs for components of the table.
+ #
+ found = False
+ while True:
+ ret = cursor.next()
+ if ret != 0:
+ break
+ key = cursor.get_key()
+ check_meta = ((key.find("lsm:") != -1 or key.find("file:") != -1) \
+ and key.find(self.name) != -1)
+ if check_meta:
+ value = cursor[key]
+ found = True
+ self.assertTrue(value.find(metastr) != -1)
+ cursor.close()
+ self.assertTrue(found == True)
+
+ # Alter: Change the access pattern hint after creation
+ def test_alter01_access(self):
+ uri = self.uri + self.name
+ create_params = 'key_format=i,value_format=i,'
+ complex_params = ''
+ #
+ # If we're not explicitly setting the parameter, then don't
+ # modify create_params to test using the default.
+ #
+ if self.acreate != '':
+ access_param = 'access_pattern_hint=%s' % self.acreate
+ create_params += '%s,' % access_param
+ complex_params += '%s,' % access_param
+ else:
+ # NOTE: This is hard-coding the default value. If the default
+ # changes then this will fail and need to be fixed.
+ access_param = 'access_pattern_hint=none'
+ if self.ccreate != '':
+ cache_param = 'cache_resident=%s' % self.ccreate
+ create_params += '%s,' % cache_param
+ complex_params += '%s,' % cache_param
+ else:
+ # NOTE: This is hard-coding the default value. If the default
+ # changes then this will fail and need to be fixed.
+ cache_param = 'cache_resident=false'
+
+ cgparam = ''
+ if self.use_cg or self.use_index:
+ cgparam = 'columns=(k,v),'
+ if self.use_cg:
+ cgparam += 'colgroups=(g0),'
+
+ self.session.create(uri, create_params + cgparam)
+ # Add in column group or index settings.
+ if self.use_cg:
+ cgparam = 'columns=(v),'
+ suburi = 'colgroup:' + self.name + ':g0'
+ self.session.create(suburi, complex_params + cgparam)
+ if self.use_index:
+ suburi = 'index:' + self.name + ':i0'
+ self.session.create(suburi, complex_params + cgparam)
+
+ # Put some data in table.
+ c = self.session.open_cursor(uri, None)
+ for k in range(self.entries):
+ c[k+1] = 1
+ c.close()
+
+ # Verify the string in the metadata
+ self.verify_metadata(access_param)
+ self.verify_metadata(cache_param)
+
+ # Run through all combinations of the alter commands
+ # for all allowed settings. This tests having only one or
+ # the other set as well as having both set. It will also
+ # cover trying to change the setting to its current value.
+ for a in self.access_alter:
+ alter_param = ''
+ access_str = ''
+ if a != '':
+ access_str = 'access_pattern_hint=%s' % a
+ for c in self.cache_alter:
+ alter_param = '%s' % access_str
+ cache_str = ''
+ if c != '':
+ cache_str = 'cache_resident=%s' % c
+ alter_param += ',%s' % cache_str
+ if alter_param != '':
+ self.session.alter(uri, alter_param)
+ if self.reopen:
+ self.reopen_conn()
+ special = self.use_cg or self.use_index
+ if not special:
+ self.verify_metadata(access_str)
+ self.verify_metadata(cache_str)
+ else:
+ self.session.alter(suburi, alter_param)
+ self.verify_metadata(access_str)
+ self.verify_metadata(cache_str)
+
+if __name__ == '__main__':
+ wttest.run()
diff --git a/tools/wtstats/stat_data.py b/tools/wtstats/stat_data.py
index 635e710c469..d925dd67b80 100644
--- a/tools/wtstats/stat_data.py
+++ b/tools/wtstats/stat_data.py
@@ -34,6 +34,9 @@ no_scale_per_second_list = [
'reconciliation: split objects currently awaiting free',
'session: open cursor count',
'session: open session count',
+ 'session: table alter failed calls',
+ 'session: table alter successful calls',
+ 'session: table alter unchanged and skipped',
'session: table compact failed calls',
'session: table compact successful calls',
'session: table create failed calls',
@@ -147,6 +150,9 @@ no_clear_list = [
'reconciliation: split objects currently awaiting free',
'session: open cursor count',
'session: open session count',
+ 'session: table alter failed calls',
+ 'session: table alter successful calls',
+ 'session: table alter unchanged and skipped',
'session: table compact failed calls',
'session: table compact successful calls',
'session: table create failed calls',