summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bench/wtperf/config.c67
-rw-r--r--bench/wtperf/runners/evict-btree-readonly.wtperf2
-rw-r--r--bench/wtperf/runners/evict-btree.wtperf2
-rw-r--r--bench/wtperf/runners/evict-lsm-readonly.wtperf2
-rw-r--r--bench/wtperf/runners/evict-lsm.wtperf2
-rw-r--r--bench/wtperf/runners/update-delta-mix1.wtperf18
-rw-r--r--bench/wtperf/runners/update-delta-mix2.wtperf18
-rw-r--r--bench/wtperf/runners/update-delta-mix3.wtperf18
-rw-r--r--bench/wtperf/runners/update-grow-stress.wtperf15
-rw-r--r--bench/wtperf/runners/update-shrink-stress.wtperf15
-rw-r--r--bench/wtperf/wtperf.c105
-rw-r--r--bench/wtperf/wtperf.h6
-rw-r--r--bench/wtperf/wtperf_opt.i8
-rw-r--r--dist/s_string.ok1
-rw-r--r--dist/stat_data.py77
-rw-r--r--src/conn/conn_dhandle.c29
-rw-r--r--src/conn/conn_stat.c4
-rw-r--r--src/conn/conn_sweep.c8
-rw-r--r--src/docs/readonly.dox2
-rw-r--r--src/docs/wtperf.dox11
-rw-r--r--src/evict/evict_lru.c22
-rw-r--r--src/support/power8/crc32.S50
-rw-r--r--test/suite/test_backup05.py8
-rw-r--r--test/suite/test_checkpoint01.py2
-rw-r--r--test/suite/test_cursor06.py2
-rw-r--r--test/suite/test_cursor_random.py2
-rw-r--r--test/suite/test_join01.py2
-rw-r--r--test/suite/test_readonly01.py7
-rw-r--r--test/suite/test_readonly02.py8
-rw-r--r--test/suite/test_readonly03.py2
30 files changed, 390 insertions, 125 deletions
diff --git a/bench/wtperf/config.c b/bench/wtperf/config.c
index 2544bbd371c..e83d6fcceed 100644
--- a/bench/wtperf/config.c
+++ b/bench/wtperf/config.c
@@ -241,10 +241,6 @@ config_threads(CONFIG *cfg, const char *config, size_t len)
goto err;
continue;
}
- if (STRING_MATCH("throttle", k.str, k.len)) {
- workp->throttle = (uint64_t)v.val;
- continue;
- }
if (STRING_MATCH("insert", k.str, k.len) ||
STRING_MATCH("inserts", k.str, k.len)) {
if ((workp->insert = v.val) < 0)
@@ -262,20 +258,17 @@ config_threads(CONFIG *cfg, const char *config, size_t len)
goto err;
continue;
}
- if (STRING_MATCH("update", k.str, k.len) ||
- STRING_MATCH("updates", k.str, k.len)) {
- if ((workp->update = v.val) < 0)
- goto err;
+ if (STRING_MATCH("throttle", k.str, k.len)) {
+ workp->throttle = (uint64_t)v.val;
continue;
}
if (STRING_MATCH("truncate", k.str, k.len)) {
if ((workp->truncate = v.val) != 1)
goto err;
/* There can only be one Truncate thread. */
- if (cfg->has_truncate != 0) {
+ if (F_ISSET(cfg, CFG_TRUNCATE))
goto err;
- }
- cfg->has_truncate = 1;
+ F_SET(cfg, CFG_TRUNCATE);
continue;
}
if (STRING_MATCH("truncate_pct", k.str, k.len)) {
@@ -290,6 +283,29 @@ config_threads(CONFIG *cfg, const char *config, size_t len)
workp->truncate_count = (uint64_t)v.val;
continue;
}
+ if (STRING_MATCH("update", k.str, k.len) ||
+ STRING_MATCH("updates", k.str, k.len)) {
+ if ((workp->update = v.val) < 0)
+ goto err;
+ continue;
+ }
+ if (STRING_MATCH("update_delta", k.str, k.len)) {
+ if (v.type == WT_CONFIG_ITEM_STRING ||
+ v.type == WT_CONFIG_ITEM_ID) {
+ if (strncmp(v.str, "rand", 4) != 0)
+ goto err;
+ /* Special random value */
+ workp->update_delta = INT64_MAX;
+ F_SET(cfg, CFG_GROW);
+ } else {
+ workp->update_delta = v.val;
+ if (v.val > 0)
+ F_SET(cfg, CFG_GROW);
+ if (v.val < 0)
+ F_SET(cfg, CFG_SHRINK);
+ }
+ continue;
+ }
goto err;
}
if (ret == WT_NOTFOUND)
@@ -409,7 +425,12 @@ config_opt(CONFIG *cfg, WT_CONFIG_ITEM *k, WT_CONFIG_ITEM *v)
*(uint32_t *)valueloc = (uint32_t)v->val;
break;
case CONFIG_STRING_TYPE:
- if (v->type != WT_CONFIG_ITEM_STRING) {
+ /*
+ * Configuration parsing uses string/ID to distinguish
+ * between quoted and unquoted values.
+ */
+ if (v->type != WT_CONFIG_ITEM_STRING &&
+ v->type != WT_CONFIG_ITEM_ID) {
fprintf(stderr, "wtperf: Error: "
"bad string value for \'%.*s=%.*s\'\n",
(int)k->len, k->str, (int)v->len, v->str);
@@ -438,7 +459,8 @@ config_opt(CONFIG *cfg, WT_CONFIG_ITEM *k, WT_CONFIG_ITEM *v)
STRING_MATCH("threads", k->str, k->len))
return (config_threads(cfg, v->str, v->len));
- if (v->type != WT_CONFIG_ITEM_STRING) {
+ if (v->type != WT_CONFIG_ITEM_STRING &&
+ v->type != WT_CONFIG_ITEM_ID) {
fprintf(stderr, "wtperf: Error: "
"bad string value for \'%.*s=%.*s\'\n",
(int)k->len, k->str, (int)v->len, v->str);
@@ -672,6 +694,25 @@ config_sanity(CONFIG *cfg)
return (EINVAL);
}
+ if (cfg->value_sz_max < cfg->value_sz) {
+ if (F_ISSET(cfg, CFG_GROW)) {
+ fprintf(stderr, "value_sz_max %" PRIu32
+ " must be greater than or equal to value_sz %"
+ PRIu32 "\n", cfg->value_sz_max, cfg->value_sz);
+ return (EINVAL);
+ } else
+ cfg->value_sz_max = cfg->value_sz;
+ }
+ if (cfg->value_sz_min > cfg->value_sz) {
+ if (F_ISSET(cfg, CFG_SHRINK)) {
+ fprintf(stderr, "value_sz_min %" PRIu32
+ " must be less than or equal to value_sz %"
+ PRIu32 "\n", cfg->value_sz_min, cfg->value_sz);
+ return (EINVAL);
+ } else
+ cfg->value_sz_min = cfg->value_sz;
+ }
+
if (cfg->readonly && cfg->workload != NULL)
for (i = 0, workp = cfg->workload;
i < cfg->workload_cnt; ++i, ++workp)
diff --git a/bench/wtperf/runners/evict-btree-readonly.wtperf b/bench/wtperf/runners/evict-btree-readonly.wtperf
index d79af2b762b..25599fadd8d 100644
--- a/bench/wtperf/runners/evict-btree-readonly.wtperf
+++ b/bench/wtperf/runners/evict-btree-readonly.wtperf
@@ -1,5 +1,5 @@
# wtperf options file: evict btree configuration
-conn_config="cache_size=50M"
+conn_config="cache_size=50M,eviction=(threads_max=4),mmap=false"
table_config="type=file"
icount=10000000
report_interval=5
diff --git a/bench/wtperf/runners/evict-btree.wtperf b/bench/wtperf/runners/evict-btree.wtperf
index 24da4dd7902..e7d967e5c63 100644
--- a/bench/wtperf/runners/evict-btree.wtperf
+++ b/bench/wtperf/runners/evict-btree.wtperf
@@ -1,5 +1,5 @@
# wtperf options file: evict btree configuration
-conn_config="cache_size=50M"
+conn_config="cache_size=50M,eviction=(threads_max=4)"
table_config="type=file"
icount=10000000
report_interval=5
diff --git a/bench/wtperf/runners/evict-lsm-readonly.wtperf b/bench/wtperf/runners/evict-lsm-readonly.wtperf
index fe45c0e93b6..661b8e21924 100644
--- a/bench/wtperf/runners/evict-lsm-readonly.wtperf
+++ b/bench/wtperf/runners/evict-lsm-readonly.wtperf
@@ -1,5 +1,5 @@
# wtperf options file: evict lsm configuration
-conn_config="cache_size=50M,lsm_manager=(worker_thread_max=6)"
+conn_config="cache_size=50M,lsm_manager=(worker_thread_max=6),eviction=(threads_max=4)"
table_config="type=lsm,lsm=(chunk_size=2M),os_cache_dirty_max=16MB"
compact=true
icount=10000000
diff --git a/bench/wtperf/runners/evict-lsm.wtperf b/bench/wtperf/runners/evict-lsm.wtperf
index ad885d98eb7..b872d429046 100644
--- a/bench/wtperf/runners/evict-lsm.wtperf
+++ b/bench/wtperf/runners/evict-lsm.wtperf
@@ -1,5 +1,5 @@
# wtperf options file: evict lsm configuration
-conn_config="cache_size=50M,lsm_manager=(worker_thread_max=6)"
+conn_config="cache_size=50M,lsm_manager=(worker_thread_max=6),eviction=(threads_max=4)"
table_config="type=lsm,lsm=(chunk_size=2M),os_cache_dirty_max=16MB"
compact=true
icount=10000000
diff --git a/bench/wtperf/runners/update-delta-mix1.wtperf b/bench/wtperf/runners/update-delta-mix1.wtperf
new file mode 100644
index 00000000000..0f5e75f5347
--- /dev/null
+++ b/bench/wtperf/runners/update-delta-mix1.wtperf
@@ -0,0 +1,18 @@
+# wtperf options file: Mixed workload where we grow some values and shrink
+# others. Mixed load leaning toward growing the dataset.
+#
+conn_config="cache_size=2GB,checkpoint=(wait=30)"
+table_config="type=file,leaf_page_max=32k,leaf_value_max=128k,split_pct=90"
+# The values are starting small, insert a lot so our database grows larger than
+# cache quickly.
+icount=200000
+report_interval=5
+run_time=300
+populate_threads=1
+#
+# Run more grow workload threads than shrink threads.
+#
+threads=((count=4,update=1,update_delta=100),(count=2,update=1,update_delta=-150))
+value_sz=20000
+value_sz_min=1000
+value_sz_max=65536
diff --git a/bench/wtperf/runners/update-delta-mix2.wtperf b/bench/wtperf/runners/update-delta-mix2.wtperf
new file mode 100644
index 00000000000..f3ce2a455cc
--- /dev/null
+++ b/bench/wtperf/runners/update-delta-mix2.wtperf
@@ -0,0 +1,18 @@
+# wtperf options file: Mixed workload where we grow some values and shrink
+# others. Mixed load leaning toward shrinking the dataset.
+#
+conn_config="cache_size=2GB,checkpoint=(wait=30)"
+table_config="type=file,leaf_page_max=32k,leaf_value_max=128k,split_pct=90"
+# The values are starting small, insert a lot so our database grows larger than
+# cache quickly.
+icount=200000
+report_interval=5
+run_time=300
+populate_threads=1
+#
+# Run more shrink workload threads than grow threads.
+#
+threads=((count=2,update=1,update_delta=150),(count=4,update=1,update_delta=-100))
+value_sz=20000
+value_sz_min=1000
+value_sz_max=65536
diff --git a/bench/wtperf/runners/update-delta-mix3.wtperf b/bench/wtperf/runners/update-delta-mix3.wtperf
new file mode 100644
index 00000000000..606eb727eef
--- /dev/null
+++ b/bench/wtperf/runners/update-delta-mix3.wtperf
@@ -0,0 +1,18 @@
+# wtperf options file: Mixed workload where we grow some values and shrink
+# others. Mixed load leaning toward mostly a balance.
+#
+conn_config="cache_size=2GB,checkpoint=(wait=30)"
+table_config="type=file,leaf_page_max=32k,leaf_value_max=128k,split_pct=90"
+# The values are starting small, insert a lot so our database grows larger than
+# cache quickly.
+icount=200000
+report_interval=5
+run_time=300
+populate_threads=1
+#
+# Run a balance of threads.
+#
+threads=((count=3,update=1,update_delta=100),(count=3,update=1,update_delta=-100))
+value_sz=20000
+value_sz_min=1000
+value_sz_max=65536
diff --git a/bench/wtperf/runners/update-grow-stress.wtperf b/bench/wtperf/runners/update-grow-stress.wtperf
new file mode 100644
index 00000000000..f7403e1578d
--- /dev/null
+++ b/bench/wtperf/runners/update-grow-stress.wtperf
@@ -0,0 +1,15 @@
+# wtperf options file: Grow the size of documents while there is cache
+# pressure and appends are happening as well.
+conn_config="cache_size=2GB,checkpoint=(wait=30)"
+table_config="type=file,leaf_page_max=32k,leaf_value_max=128k,split_pct=90"
+# The values are starting small, insert a lot so our database grows larger than
+# cache quickly.
+icount=200000
+report_interval=5
+run_time=240
+populate_threads=1
+# Continue inserting new records.
+threads=((count=1,inserts=1,throttle=1000),(count=4,update=1,update_delta=100))
+# Start with small values and let them grow slowly to large values.
+value_sz=10000
+value_sz_max=65536
diff --git a/bench/wtperf/runners/update-shrink-stress.wtperf b/bench/wtperf/runners/update-shrink-stress.wtperf
new file mode 100644
index 00000000000..bbdd9593b59
--- /dev/null
+++ b/bench/wtperf/runners/update-shrink-stress.wtperf
@@ -0,0 +1,15 @@
+# wtperf options file: Shrink the size of values. Checkpoint frequently
+# and insert new records too.
+#
+conn_config="cache_size=2GB,checkpoint=(wait=30)"
+table_config="type=file,leaf_page_max=32k,leaf_value_max=128k,split_pct=90"
+# Since we're continually inserting, start with a smaller number initially.
+icount=200000
+report_interval=5
+run_time=240
+populate_threads=1
+# Continue inserting new records.
+threads=((count=1,inserts=1,throttle=1000),(count=4,update=1,update_delta=-100))
+# Start with moderate values and let them shrink slowly.
+value_sz_min=1000
+value_sz=10000
diff --git a/bench/wtperf/wtperf.c b/bench/wtperf/wtperf.c
index b6e10762d8c..5755e22dd2f 100644
--- a/bench/wtperf/wtperf.c
+++ b/bench/wtperf/wtperf.c
@@ -60,7 +60,7 @@ static const CONFIG default_cfg = {
0, /* in warmup phase */
false, /* Signal for idle cycle thread */
0, /* total seconds running */
- 0, /* has truncate */
+ 0, /* flags */
{NULL, NULL}, /* the truncate queue */
{NULL, NULL}, /* the config queue */
@@ -87,6 +87,7 @@ static int start_threads(CONFIG *,
WORKLOAD *, CONFIG_THREAD *, u_int, void *(*)(void *));
static int stop_threads(CONFIG *, u_int, CONFIG_THREAD *);
static void *thread_run_wtperf(void *);
+static void update_value_delta(CONFIG_THREAD *);
static void *worker(void *);
static uint64_t wtperf_rand(CONFIG_THREAD *);
@@ -105,24 +106,93 @@ get_next_incr(CONFIG *cfg)
return (__wt_atomic_add64(&cfg->insert_key, 1));
}
+/*
+ * Each time this function is called we will overwrite the first and one
+ * other element in the value buffer.
+ */
static void
randomize_value(CONFIG_THREAD *thread, char *value_buf)
{
uint8_t *vb;
- uint32_t i;
+ uint32_t i, max_range, rand_val;
+
+ /*
+ * Limit how much of the buffer we validate for length, this means
+ * that only threads that do growing updates will ever make changes to
+ * values outside of the initial value size, but that's a fair trade
+ * off for avoiding figuring out how long the value is more accurately
+ * in this performance sensitive function.
+ */
+ if (thread->workload == NULL || thread->workload->update_delta == 0)
+ max_range = thread->cfg->value_sz;
+ else if (thread->workload->update_delta > 0)
+ max_range = thread->cfg->value_sz_max;
+ else
+ max_range = thread->cfg->value_sz_min;
+
+ /*
+ * Generate a single random value and re-use it. We generally only
+ * have small ranges in this function, so avoiding a bunch of calls
+ * is worthwhile.
+ */
+ rand_val = __wt_random(&thread->rnd);
+ i = rand_val % (max_range - 1);
/*
- * Each time we're called overwrite value_buf[0] and one other
- * randomly chosen byte (other than the trailing NUL).
- * Make sure we don't write a NUL: keep the value the same length.
+ * Ensure we don't write past the end of a value when configured for
+ * randomly sized values.
*/
- i = __wt_random(&thread->rnd) % (thread->cfg->value_sz - 1);
while (value_buf[i] == '\0' && i > 0)
--i;
- if (i > 0) {
- vb = (uint8_t *)value_buf;
- vb[0] = (__wt_random(&thread->rnd) % 255) + 1;
- vb[i] = (__wt_random(&thread->rnd) % 255) + 1;
+
+ vb = (uint8_t *)value_buf;
+ vb[0] = ((rand_val >> 8) % 255) + 1;
+ /*
+ * If i happened to be 0, we'll be re-writing the same value
+ * twice, but that doesn't matter.
+ */
+ vb[i] = ((rand_val >> 16) % 255) + 1;
+}
+
+/*
+ * Figure out and extend the size of the value string, used for growing
+ * updates. We know that the value to be updated is in the threads value
+ * scratch buffer.
+ */
+static inline void
+update_value_delta(CONFIG_THREAD *thread)
+{
+ CONFIG *cfg;
+ char * value;
+ int64_t delta, len, new_len;
+
+ cfg = thread->cfg;
+ value = thread->value_buf;
+ delta = thread->workload->update_delta;
+ len = (int64_t)strlen(value);
+
+ if (delta == INT64_MAX)
+ delta = __wt_random(&thread->rnd) %
+ (cfg->value_sz_max - cfg->value_sz);
+
+ /* Ensure we aren't changing across boundaries */
+ if (delta > 0 && len + delta > cfg->value_sz_max)
+ delta = cfg->value_sz_max - len;
+ else if (delta < 0 && len + delta < cfg->value_sz_min)
+ delta = cfg->value_sz_min - len;
+
+ /* Bail if there isn't anything to do */
+ if (delta == 0)
+ return;
+
+ if (delta < 0)
+ value[len + delta] = '\0';
+ else {
+ /* Extend the value by the configured amount. */
+ for (new_len = len;
+ new_len < cfg->value_sz_max && new_len - len < delta;
+ new_len++)
+ value[new_len] = 'a';
}
}
@@ -624,8 +694,10 @@ worker(void *arg)
* Copy as much of the previous value as is
* safe, and be sure to NUL-terminate.
*/
- strncpy(value_buf, value, cfg->value_sz);
- value_buf[cfg->value_sz - 1] = '\0';
+ strncpy(value_buf,
+ value, cfg->value_sz_max - 1);
+ if (thread->workload->update_delta != 0)
+ update_value_delta(thread);
if (value_buf[0] == 'a')
value_buf[0] = 'b';
else
@@ -2195,7 +2267,7 @@ main(int argc, char *argv[])
* the compact operation, but not for the workloads.
*/
if (cfg->async_threads > 0) {
- if (cfg->has_truncate > 0) {
+ if (F_ISSET(cfg, CFG_TRUNCATE) > 0) {
lprintf(cfg, 1, 0, "Cannot run truncate and async\n");
goto err;
}
@@ -2220,13 +2292,13 @@ main(int argc, char *argv[])
goto err;
/* You can't have truncate on a random collection. */
- if (cfg->has_truncate && cfg->random_range) {
+ if (F_ISSET(cfg, CFG_TRUNCATE) && cfg->random_range) {
lprintf(cfg, 1, 0, "Cannot run truncate and random_range\n");
goto err;
}
/* We can't run truncate with more than one table. */
- if (cfg->has_truncate && cfg->table_count > 1) {
+ if (F_ISSET(cfg, CFG_TRUNCATE) && cfg->table_count > 1) {
lprintf(cfg, 1, 0, "Cannot truncate more than 1 table\n");
goto err;
}
@@ -2374,7 +2446,8 @@ start_threads(CONFIG *cfg,
* strings: trailing NUL is included in the size.
*/
thread->key_buf = dcalloc(cfg->key_sz, 1);
- thread->value_buf = dcalloc(cfg->value_sz, 1);
+ thread->value_buf = dcalloc(cfg->value_sz_max, 1);
+
/*
* Initialize and then toss in a bit of random values if needed.
*/
diff --git a/bench/wtperf/wtperf.h b/bench/wtperf/wtperf.h
index 65ee4963276..c591499b907 100644
--- a/bench/wtperf/wtperf.h
+++ b/bench/wtperf/wtperf.h
@@ -94,6 +94,7 @@ typedef struct {
int64_t truncate; /* Truncate ratio */
uint64_t truncate_pct; /* Truncate Percent */
uint64_t truncate_count; /* Truncate Count */
+ int64_t update_delta; /* Value size change on update */
#define WORKER_INSERT 1 /* Insert */
#define WORKER_INSERT_RMW 2 /* Insert with read-modify-write */
@@ -190,7 +191,10 @@ struct __config { /* Configuration structure */
volatile uint32_t totalsec; /* total seconds running */
- u_int has_truncate; /* if there is a truncate workload */
+#define CFG_GROW 0x0001 /* There is a grow workload */
+#define CFG_SHRINK 0x0002 /* There is a shrink workload */
+#define CFG_TRUNCATE 0x0004 /* There is a truncate workload */
+ uint32_t flags; /* flags */
/* Queue head for use with the Truncate Logic */
TAILQ_HEAD(__truncate_qh, __truncate_queue_entry) stone_head;
diff --git a/bench/wtperf/wtperf_opt.i b/bench/wtperf/wtperf_opt.i
index ecc1f216299..b5e274a17c2 100644
--- a/bench/wtperf/wtperf_opt.i
+++ b/bench/wtperf/wtperf_opt.i
@@ -184,13 +184,17 @@ DEF_OPT_AS_STRING(threads, "", "workload configuration: each 'count' "
"'threads=((count=2,reads=1)(count=8,reads=1,inserts=2,updates=1))' "
"which would create 2 threads doing nothing but reads and 8 threads "
"each doing 50% inserts and 25% reads and updates. Allowed configuration "
- "values are 'count', 'throttle', 'reads', 'inserts', 'updates', 'truncate',"
- " 'truncate_pct' and 'truncate_count'. There are "
+ "values are 'count', 'throttle', 'update_delta', 'reads', 'inserts', "
+ "'updates', 'truncate', 'truncate_pct' and 'truncate_count'. There are "
"also behavior modifiers, supported modifiers are 'ops_per_txn'")
DEF_OPT_AS_CONFIG_STRING(transaction_config, "",
"transaction configuration string, relevant when populate_opts_per_txn "
"is nonzero")
DEF_OPT_AS_STRING(table_name, "test", "table name")
+DEF_OPT_AS_UINT32(value_sz_max, 1000,
+ "maximum value size when delta updates are present. Default disabled")
+DEF_OPT_AS_UINT32(value_sz_min, 1,
+ "minimum value size when delta updates are present. Default disabled")
DEF_OPT_AS_UINT32(value_sz, 100, "value size")
DEF_OPT_AS_UINT32(verbose, 1, "verbosity")
DEF_OPT_AS_UINT32(warmup, 0,
diff --git a/dist/s_string.ok b/dist/s_string.ok
index c8769abdfbe..2caaddcc15a 100644
--- a/dist/s_string.ok
+++ b/dist/s_string.ok
@@ -983,6 +983,7 @@ superset
sw
sy
sys
+sz
t's
tV
tablename
diff --git a/dist/stat_data.py b/dist/stat_data.py
index be4bacaece7..09e5643a5d6 100644
--- a/dist/stat_data.py
+++ b/dist/stat_data.py
@@ -12,6 +12,7 @@
# max_aggregate Take the maximum value when aggregating statistics
# no_clear Value not cleared when statistics cleared
# no_scale Don't scale value per second in the logging tool script
+# size Used by timeseries tool, indicates value is a byte count
#
# The no_clear and no_scale flags are normally always set together (values that
# are maintained over time are normally not scaled per second).
@@ -138,9 +139,9 @@ connection_stats = [
##########################################
# Block manager statistics
##########################################
- BlockStat('block_byte_map_read', 'mapped bytes read'),
- BlockStat('block_byte_read', 'bytes read'),
- BlockStat('block_byte_write', 'bytes written'),
+ BlockStat('block_byte_map_read', 'mapped bytes read', 'size'),
+ BlockStat('block_byte_read', 'bytes read', 'size'),
+ BlockStat('block_byte_write', 'bytes written', 'size'),
BlockStat('block_map_read', 'mapped blocks read'),
BlockStat('block_preload', 'blocks pre-loaded'),
BlockStat('block_read', 'blocks read'),
@@ -149,14 +150,14 @@ connection_stats = [
##########################################
# Cache and eviction statistics
##########################################
- CacheStat('cache_bytes_dirty', 'tracked dirty bytes in the cache', 'no_clear,no_scale'),
- CacheStat('cache_bytes_internal', 'tracked bytes belonging to internal pages in the cache', 'no_clear,no_scale'),
- CacheStat('cache_bytes_inuse', 'bytes currently in the cache', 'no_clear,no_scale'),
- CacheStat('cache_bytes_leaf', 'tracked bytes belonging to leaf pages in the cache', 'no_clear,no_scale'),
- CacheStat('cache_bytes_max', 'maximum bytes configured', 'no_clear,no_scale'),
- CacheStat('cache_bytes_overflow', 'tracked bytes belonging to overflow pages in the cache', 'no_clear,no_scale'),
- CacheStat('cache_bytes_read', 'bytes read into cache'),
- CacheStat('cache_bytes_write', 'bytes written from cache'),
+ CacheStat('cache_bytes_dirty', 'tracked dirty bytes in the cache', 'no_clear,no_scale,size'),
+ CacheStat('cache_bytes_internal', 'tracked bytes belonging to internal pages in the cache', 'no_clear,no_scale,size'),
+ CacheStat('cache_bytes_inuse', 'bytes currently in the cache', 'no_clear,no_scale,size'),
+ CacheStat('cache_bytes_leaf', 'tracked bytes belonging to leaf pages in the cache', 'no_clear,no_scale,size'),
+ CacheStat('cache_bytes_max', 'maximum bytes configured', 'no_clear,no_scale,size'),
+ CacheStat('cache_bytes_overflow', 'tracked bytes belonging to overflow pages in the cache', 'no_clear,no_scale,size'),
+ CacheStat('cache_bytes_read', 'bytes read into cache', 'size'),
+ CacheStat('cache_bytes_write', 'bytes written from cache', 'size'),
CacheStat('cache_eviction_aggressive_set', 'eviction currently operating in aggressive mode', 'no_clear,no_scale'),
CacheStat('cache_eviction_app', 'pages evicted by application threads'),
CacheStat('cache_eviction_checkpoint', 'checkpoint blocked page eviction'),
@@ -169,7 +170,7 @@ connection_stats = [
CacheStat('cache_eviction_force_fail', 'failed eviction of pages that exceeded the in-memory maximum'),
CacheStat('cache_eviction_hazard', 'hazard pointer blocked page eviction'),
CacheStat('cache_eviction_internal', 'internal pages evicted'),
- CacheStat('cache_eviction_maximum_page_size', 'maximum page size at eviction', 'no_clear,no_scale'),
+ CacheStat('cache_eviction_maximum_page_size', 'maximum page size at eviction', 'no_clear,no_scale,size'),
CacheStat('cache_eviction_queue_empty', 'eviction server candidate queue empty when topping up'),
CacheStat('cache_eviction_queue_not_empty', 'eviction server candidate queue not empty when topping up'),
CacheStat('cache_eviction_server_evicting', 'eviction server evicting pages'),
@@ -207,17 +208,17 @@ connection_stats = [
##########################################
# Logging statistics
##########################################
- LogStat('log_buffer_size', 'total log buffer size', 'no_clear,no_scale'),
- LogStat('log_bytes_payload', 'log bytes of payload data'),
- LogStat('log_bytes_written', 'log bytes written'),
+ LogStat('log_buffer_size', 'total log buffer size', 'no_clear,no_scale,size'),
+ LogStat('log_bytes_payload', 'log bytes of payload data', 'size'),
+ LogStat('log_bytes_written', 'log bytes written', 'size'),
LogStat('log_close_yields', 'yields waiting for previous log file close'),
- LogStat('log_compress_len', 'total size of compressed records'),
- LogStat('log_compress_mem', 'total in-memory size of compressed records'),
+ LogStat('log_compress_len', 'total size of compressed records', 'size'),
+ LogStat('log_compress_mem', 'total in-memory size of compressed records', 'size'),
LogStat('log_compress_small', 'log records too small to compress'),
LogStat('log_compress_write_fails', 'log records not compressed'),
LogStat('log_compress_writes', 'log records compressed'),
LogStat('log_flush', 'log flush operations'),
- LogStat('log_max_filesize', 'maximum log file size', 'no_clear,no_scale'),
+ LogStat('log_max_filesize', 'maximum log file size', 'no_clear,no_scale,size'),
LogStat('log_prealloc_files', 'pre-allocated log files prepared'),
LogStat('log_prealloc_max', 'number of pre-allocated log files to create', 'no_clear,no_scale'),
LogStat('log_prealloc_missed', 'pre-allocated log files not ready and missed'),
@@ -228,7 +229,7 @@ connection_stats = [
LogStat('log_scans', 'log scan operations'),
LogStat('log_slot_closes', 'consolidated slot closures'),
LogStat('log_slot_coalesced', 'written slots coalesced'),
- LogStat('log_slot_consolidated', 'logging bytes consolidated'),
+ LogStat('log_slot_consolidated', 'logging bytes consolidated', 'size'),
LogStat('log_slot_joins', 'consolidated slot joins'),
LogStat('log_slot_races', 'consolidated slot join races'),
LogStat('log_slot_switch_busy', 'busy returns attempting to switch slots'),
@@ -247,7 +248,7 @@ connection_stats = [
RecStat('rec_page_delete_fast', 'fast-path pages deleted'),
RecStat('rec_pages', 'page reconciliation calls'),
RecStat('rec_pages_eviction', 'page reconciliation calls for eviction'),
- RecStat('rec_split_stashed_bytes', 'split bytes currently awaiting free', 'no_clear,no_scale'),
+ RecStat('rec_split_stashed_bytes', 'split bytes currently awaiting free', 'no_clear,no_scale,size'),
RecStat('rec_split_stashed_objects', 'split objects currently awaiting free', 'no_clear,no_scale'),
##########################################
@@ -334,18 +335,18 @@ dsrc_stats = [
CursorStat('cursor_create', 'create calls'),
CursorStat('cursor_insert', 'insert calls'),
CursorStat('cursor_insert_bulk', 'bulk-loaded cursor-insert calls'),
- CursorStat('cursor_insert_bytes', 'cursor-insert key and value bytes inserted'),
+ CursorStat('cursor_insert_bytes', 'cursor-insert key and value bytes inserted', 'size'),
CursorStat('cursor_next', 'next calls'),
CursorStat('cursor_prev', 'prev calls'),
CursorStat('cursor_remove', 'remove calls'),
- CursorStat('cursor_remove_bytes', 'cursor-remove key bytes removed'),
+ CursorStat('cursor_remove_bytes', 'cursor-remove key bytes removed', 'size'),
CursorStat('cursor_reset', 'reset calls'),
CursorStat('cursor_restart', 'restarted searches'),
CursorStat('cursor_search', 'search calls'),
CursorStat('cursor_search_near', 'search near calls'),
CursorStat('cursor_truncate', 'truncate calls'),
CursorStat('cursor_update', 'update calls'),
- CursorStat('cursor_update_bytes', 'cursor-update value bytes updated'),
+ CursorStat('cursor_update_bytes', 'cursor-update value bytes updated', 'size'),
##########################################
# Btree statistics
@@ -358,13 +359,13 @@ dsrc_stats = [
BtreeStat('btree_column_variable', 'column-store variable-size leaf pages', 'no_scale'),
BtreeStat('btree_compact_rewrite', 'pages rewritten by compaction'),
BtreeStat('btree_entries', 'number of key/value pairs', 'no_scale'),
- BtreeStat('btree_fixed_len', 'fixed-record size', 'max_aggregate,no_scale'),
+ BtreeStat('btree_fixed_len', 'fixed-record size', 'max_aggregate,no_scale,size'),
BtreeStat('btree_maximum_depth', 'maximum tree depth', 'max_aggregate,no_scale'),
- BtreeStat('btree_maxintlkey', 'maximum internal page key size', 'max_aggregate,no_scale'),
- BtreeStat('btree_maxintlpage', 'maximum internal page size', 'max_aggregate,no_scale'),
- BtreeStat('btree_maxleafkey', 'maximum leaf page key size', 'max_aggregate,no_scale'),
- BtreeStat('btree_maxleafpage', 'maximum leaf page size', 'max_aggregate,no_scale'),
- BtreeStat('btree_maxleafvalue', 'maximum leaf page value size', 'max_aggregate,no_scale'),
+ BtreeStat('btree_maxintlkey', 'maximum internal page key size', 'max_aggregate,no_scale,size'),
+ BtreeStat('btree_maxintlpage', 'maximum internal page size', 'max_aggregate,no_scale,size'),
+ BtreeStat('btree_maxleafkey', 'maximum leaf page key size', 'max_aggregate,no_scale,size'),
+ BtreeStat('btree_maxleafpage', 'maximum leaf page size', 'max_aggregate,no_scale,size'),
+ BtreeStat('btree_maxleafvalue', 'maximum leaf page value size', 'max_aggregate,no_scale,size'),
BtreeStat('btree_overflow', 'overflow pages', 'no_scale'),
BtreeStat('btree_row_internal', 'row-store internal pages', 'no_scale'),
BtreeStat('btree_row_leaf', 'row-store leaf pages', 'no_scale'),
@@ -378,7 +379,7 @@ dsrc_stats = [
LSMStat('bloom_miss', 'bloom filter misses'),
LSMStat('bloom_page_evict', 'bloom filter pages evicted from cache'),
LSMStat('bloom_page_read', 'bloom filter pages read into cache'),
- LSMStat('bloom_size', 'total size of bloom filters', 'no_scale'),
+ LSMStat('bloom_size', 'total size of bloom filters', 'no_scale,size'),
LSMStat('lsm_checkpoint_throttle', 'sleep for LSM checkpoint throttle'),
LSMStat('lsm_chunk_count', 'chunks in the LSM tree', 'no_scale'),
LSMStat('lsm_generation_max', 'highest merge generation in the LSM tree', 'max_aggregate,no_scale'),
@@ -388,22 +389,22 @@ dsrc_stats = [
##########################################
# Block manager statistics
##########################################
- BlockStat('allocation_size', 'file allocation unit size', 'max_aggregate,no_scale'),
+ BlockStat('allocation_size', 'file allocation unit size', 'max_aggregate,no_scale,size'),
BlockStat('block_alloc', 'blocks allocated'),
- BlockStat('block_checkpoint_size', 'checkpoint size', 'no_scale'),
+ BlockStat('block_checkpoint_size', 'checkpoint size', 'no_scale,size'),
BlockStat('block_extension', 'allocations requiring file extension'),
BlockStat('block_free', 'blocks freed'),
BlockStat('block_magic', 'file magic number', 'max_aggregate,no_scale'),
BlockStat('block_major', 'file major version number', 'max_aggregate,no_scale'),
BlockStat('block_minor', 'minor version number', 'max_aggregate,no_scale'),
- BlockStat('block_reuse_bytes', 'file bytes available for reuse'),
- BlockStat('block_size', 'file size in bytes', 'no_scale'),
+ BlockStat('block_reuse_bytes', 'file bytes available for reuse', 'size'),
+ BlockStat('block_size', 'file size in bytes', 'no_scale,size'),
##########################################
# Cache and eviction statistics
##########################################
- CacheStat('cache_bytes_read', 'bytes read into cache'),
- CacheStat('cache_bytes_write', 'bytes written from cache'),
+ CacheStat('cache_bytes_read', 'bytes read into cache', 'size'),
+ CacheStat('cache_bytes_write', 'bytes written from cache', 'size'),
CacheStat('cache_eviction_checkpoint', 'checkpoint blocked page eviction'),
CacheStat('cache_eviction_clean', 'unmodified pages evicted'),
CacheStat('cache_eviction_deepen', 'page split during eviction deepened the tree'),
@@ -449,8 +450,8 @@ dsrc_stats = [
RecStat('rec_page_match', 'page checksum matches'),
RecStat('rec_pages', 'page reconciliation calls'),
RecStat('rec_pages_eviction', 'page reconciliation calls for eviction'),
- RecStat('rec_prefix_compression', 'leaf page key bytes discarded using prefix compression'),
- RecStat('rec_suffix_compression', 'internal page key bytes discarded using suffix compression'),
+ RecStat('rec_prefix_compression', 'leaf page key bytes discarded using prefix compression', 'size'),
+ RecStat('rec_suffix_compression', 'internal page key bytes discarded using suffix compression', 'size'),
##########################################
# Transaction statistics
diff --git a/src/conn/conn_dhandle.c b/src/conn/conn_dhandle.c
index f1b35571533..2fab08e3afa 100644
--- a/src/conn/conn_dhandle.c
+++ b/src/conn/conn_dhandle.c
@@ -134,14 +134,11 @@ __wt_conn_btree_sync_and_close(WT_SESSION_IMPL *session, bool final, bool force)
btree = S2BT(session);
bm = btree->bm;
dhandle = session->dhandle;
- marked_dead = false;
+ evict_reset = marked_dead = false;
if (!F_ISSET(dhandle, WT_DHANDLE_OPEN))
return (0);
- /* Ensure that we aren't racing with the eviction server */
- WT_RET(__wt_evict_file_exclusive_on(session, &evict_reset));
-
/*
* If we don't already have the schema lock, make it an error to try
* to acquire it. The problem is that we are holding an exclusive
@@ -163,6 +160,13 @@ __wt_conn_btree_sync_and_close(WT_SESSION_IMPL *session, bool final, bool force)
__wt_spin_lock(session, &dhandle->close_lock);
/*
+ * Ensure we aren't racing with the eviction server; inside the close
+ * lock so threads won't race setting/clearing the tree's "no eviction"
+ * flag.
+ */
+ WT_ERR(__wt_evict_file_exclusive_on(session, &evict_reset));
+
+ /*
* The close can fail if an update cannot be written, return the EBUSY
* error to our caller for eventual retry.
*
@@ -176,23 +180,19 @@ __wt_conn_btree_sync_and_close(WT_SESSION_IMPL *session, bool final, bool force)
WT_BTREE_SALVAGE | WT_BTREE_UPGRADE | WT_BTREE_VERIFY)) {
if (force && (bm == NULL || !bm->is_mapped(bm, session))) {
F_SET(session->dhandle, WT_DHANDLE_DEAD);
+ marked_dead = true;
- /*
- * Reset the tree's eviction priority, and the tree is
- * evictable by definition.
- */
+ /* Reset the tree's eviction priority (if any). */
__wt_evict_priority_clear(session);
- F_CLR(S2BT(session), WT_BTREE_NO_EVICTION);
-
- marked_dead = true;
}
if (!marked_dead || final)
WT_ERR(__wt_checkpoint_close(session, final));
}
WT_TRET(__wt_btree_close(session));
+
/*
- * If we marked a handle as dead it will be closed by sweep, via
+ * If we marked a handle dead it will be closed by sweep, via
* another call to sync and close.
*/
if (!marked_dead) {
@@ -204,10 +204,9 @@ __wt_conn_btree_sync_and_close(WT_SESSION_IMPL *session, bool final, bool force)
F_ISSET(dhandle, WT_DHANDLE_DEAD) ||
!F_ISSET(dhandle, WT_DHANDLE_OPEN));
-err: __wt_spin_unlock(session, &dhandle->close_lock);
-
- if (evict_reset)
+err: if (evict_reset)
__wt_evict_file_exclusive_off(session);
+ __wt_spin_unlock(session, &dhandle->close_lock);
if (no_schema_lock)
F_CLR(session, WT_SESSION_NO_SCHEMA_LOCK);
diff --git a/src/conn/conn_stat.c b/src/conn/conn_stat.c
index 9ccfa8ad8db..d6e59a50da5 100644
--- a/src/conn/conn_stat.c
+++ b/src/conn/conn_stat.c
@@ -106,10 +106,6 @@ __statlog_config(WT_SESSION_IMPL *session, const char **cfg, bool *runp)
* If any statistics logging is done, this must not be a read-only
* connection.
*/
- if (F_ISSET(conn, WT_CONN_READONLY))
- WT_RET_MSG(session, EINVAL,
- "Read-only configuration incompatible with statistics "
- "logging");
WT_RET(__wt_config_gets(session, cfg, "statistics_log.sources", &cval));
WT_RET(__wt_config_subinit(session, &objectconf, &cval));
for (cnt = 0; (ret = __wt_config_next(&objectconf, &k, &v)) == 0; ++cnt)
diff --git a/src/conn/conn_sweep.c b/src/conn/conn_sweep.c
index 7628076e605..cc0aa5a1322 100644
--- a/src/conn/conn_sweep.c
+++ b/src/conn/conn_sweep.c
@@ -91,9 +91,9 @@ __sweep_expire_one(WT_SESSION_IMPL *session)
goto err;
/*
- * Mark the handle as dead and close the underlying file
- * handle. Closing the handle decrements the open file count,
- * meaning the close loop won't overrun the configured minimum.
+ * Mark the handle dead and close the underlying file handle.
+ * Closing the handle decrements the open file count, meaning the close
+ * loop won't overrun the configured minimum.
*/
ret = __wt_conn_btree_sync_and_close(session, false, true);
@@ -163,7 +163,7 @@ __sweep_discard_trees(WT_SESSION_IMPL *session, u_int *dead_handlesp)
!F_ISSET(dhandle, WT_DHANDLE_DEAD))
continue;
- /* If the handle is marked "dead", flush it from cache. */
+ /* If the handle is marked dead, flush it from cache. */
WT_WITH_DHANDLE(session, dhandle, ret =
__wt_conn_btree_sync_and_close(session, false, false));
diff --git a/src/docs/readonly.dox b/src/docs/readonly.dox
index 9935f5d1b17..ad4a94a73f1 100644
--- a/src/docs/readonly.dox
+++ b/src/docs/readonly.dox
@@ -18,7 +18,7 @@ tree merges are turned off when LSM trees are configured, and log file
archiving is disabled when logging is configured.
Where a user configured setting contradicts read-only operation, WiredTiger
-will return an error. For example, statistics logging or zero-filling
+will return an error. For example, zero-filling
log files is not allowed in read-only mode, and attempting to configure
them will return an error.
diff --git a/src/docs/wtperf.dox b/src/docs/wtperf.dox
index 6f3d2f87ee0..6d8dcab8f65 100644
--- a/src/docs/wtperf.dox
+++ b/src/docs/wtperf.dox
@@ -251,14 +251,19 @@ threads configuration might be
'threads=((count=2,reads=1)(count=8,reads=1,inserts=2,updates=1))'
which would create 2 threads doing nothing but reads and 8 threads
each doing 50% inserts and 25% reads and updates. Allowed
-configuration values are 'count', 'throttle', 'reads', 'inserts',
-'updates', 'truncate', 'truncate_pct' and 'truncate_count'. There are
-also behavior modifiers, supported modifiers are 'ops_per_txn'
+configuration values are 'count', 'throttle', 'update_delta', 'reads',
+'inserts', 'updates', 'truncate', 'truncate_pct' and 'truncate_count'.
+There are also behavior modifiers, supported modifiers are
+'ops_per_txn'
@par transaction_config (string, default=)
transaction configuration string, relevant when populate_opts_per_txn
is nonzero
@par table_name (string, default=test)
table name
+@par value_sz_max (unsigned int, default=1000)
+maximum value size when delta updates are present. Default disabled
+@par value_sz_min (unsigned int, default=1)
+minimum value size when delta updates are present. Default disabled
@par value_sz (unsigned int, default=100)
value size
@par verbose (unsigned int, default=1)
diff --git a/src/evict/evict_lru.c b/src/evict/evict_lru.c
index 35b12e2b685..884c08a02df 100644
--- a/src/evict/evict_lru.c
+++ b/src/evict/evict_lru.c
@@ -791,7 +791,7 @@ __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session, bool *evict_resetp)
btree = S2BT(session);
cache = S2C(session)->cache;
- /* If the file wasn't evictable, there's no work to do. */
+ /* If the file was never evictable, there's no work to do. */
if (F_ISSET(btree, WT_BTREE_NO_EVICTION))
return (0);
@@ -800,9 +800,16 @@ __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session, bool *evict_resetp)
* the file will be queued for eviction after this point.
*/
__wt_spin_lock(session, &cache->evict_walk_lock);
- F_SET(btree, WT_BTREE_NO_EVICTION);
+ if (!F_ISSET(btree, WT_BTREE_NO_EVICTION)) {
+ F_SET(btree, WT_BTREE_NO_EVICTION);
+ *evict_resetp = true;
+ }
__wt_spin_unlock(session, &cache->evict_walk_lock);
+ /* If some other operation has disabled eviction, we're done. */
+ if (!*evict_resetp)
+ return (0);
+
/* Clear any existing LRU eviction walk for the file. */
WT_ERR(__evict_request_walk_clear(session));
@@ -826,10 +833,10 @@ __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session, bool *evict_resetp)
while (btree->evict_busy > 0)
__wt_yield();
- *evict_resetp = true;
return (0);
err: F_CLR(btree, WT_BTREE_NO_EVICTION);
+ *evict_resetp = false;
return (ret);
}
@@ -844,7 +851,14 @@ __wt_evict_file_exclusive_off(WT_SESSION_IMPL *session)
btree = S2BT(session);
- WT_ASSERT(session, btree->evict_ref == NULL);
+ /*
+ * We have seen subtle bugs with multiple threads racing to turn
+ * eviction on/off. Make races more likely in diagnostic builds.
+ */
+ WT_DIAGNOSTIC_YIELD;
+
+ WT_ASSERT(session, btree->evict_ref == NULL &&
+ F_ISSET(btree, WT_BTREE_NO_EVICTION));
F_CLR(btree, WT_BTREE_NO_EVICTION);
}
diff --git a/src/support/power8/crc32.S b/src/support/power8/crc32.S
index 4bc1fad416d..3ef2928aaa1 100644
--- a/src/support/power8/crc32.S
+++ b/src/support/power8/crc32.S
@@ -90,6 +90,31 @@ FUNC_START(__crc32_vpmsum)
std r26,-48(r1)
std r25,-56(r1)
+ li r31, -256
+ stvx v20, r31, r1
+ li r31, -240
+ stvx v21, r31, r1
+ li r31, -224
+ stvx v22, r31, r1
+ li r31, -208
+ stvx v23, r31, r1
+ li r31, -192
+ stvx v24, r31, r1
+ li r31, -176
+ stvx v25, r31, r1
+ li r31, -160
+ stvx v26, r31, r1
+ li r31, -144
+ stvx v27, r31, r1
+ li r31, -128
+ stvx v28, r31, r1
+ li r31, -112
+ stvx v29, r31, r1
+ li r31, -96
+ stvx v30, r31, r1
+ li r31, -80
+ stvx v31, r31, r1
+
li off16,16
li off32,32
li off48,48
@@ -571,6 +596,31 @@ FUNC_START(__crc32_vpmsum)
/* Get it into r3 */
MFVRD(r3, v0)
+ li r31, -256
+ lvx v20, r31, r1
+ li r31, -240
+ lvx v21, r31, r1
+ li r31, -224
+ lvx v22, r31, r1
+ li r31, -208
+ lvx v23, r31, r1
+ li r31, -192
+ lvx v24, r31, r1
+ li r31, -176
+ lvx v25, r31, r1
+ li r31, -160
+ lvx v26, r31, r1
+ li r31, -144
+ lvx v27, r31, r1
+ li r31, -128
+ lvx v28, r31, r1
+ li r31, -112
+ lvx v29, r31, r1
+ li r31, -96
+ lvx v30, r31, r1
+ li r31, -80
+ lvx v31, r31, r1
+
ld r31,-8(r1)
ld r30,-16(r1)
ld r29,-24(r1)
diff --git a/test/suite/test_backup05.py b/test/suite/test_backup05.py
index 8ffeb6752df..991a9f71b19 100644
--- a/test/suite/test_backup05.py
+++ b/test/suite/test_backup05.py
@@ -44,14 +44,6 @@ class test_backup05(wttest.WiredTigerTestCase, suite_subprocess):
create_params = 'key_format=i,value_format=i'
freq = 5
- def copy_windows(self, olddir, newdir):
- os.mkdir(newdir)
- for fname in os.listdir(olddir):
- fullname = os.path.join(olddir, fname)
- # Skip lock file on Windows since it is locked
- if os.path.isfile(fullname) and "WiredTiger.lock" not in fullname:
- shutil.copy(fullname, newdir)
-
def check_manual_backup(self, i, olddir, newdir):
''' Simulate a manual backup from olddir and restart in newdir. '''
self.session.checkpoint()
diff --git a/test/suite/test_checkpoint01.py b/test/suite/test_checkpoint01.py
index 36f1ef733a4..9955944f73d 100644
--- a/test/suite/test_checkpoint01.py
+++ b/test/suite/test_checkpoint01.py
@@ -265,7 +265,7 @@ class test_checkpoint_cursor_update(wttest.WiredTigerTestCase):
cursor = self.session.open_cursor(self.uri, None, "checkpoint=ckpt")
cursor.set_key(key_populate(cursor, 10))
cursor.set_value("XXX")
- msg = "/not supported/"
+ msg = "/Unsupported cursor/"
self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
lambda: cursor.insert(), msg)
self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
diff --git a/test/suite/test_cursor06.py b/test/suite/test_cursor06.py
index d702f97c5dd..5545c862dd7 100644
--- a/test/suite/test_cursor06.py
+++ b/test/suite/test_cursor06.py
@@ -89,7 +89,7 @@ class test_cursor06(wttest.WiredTigerTestCase):
self.session.drop(uri, "force")
self.populate(uri)
cursor = self.session.open_cursor(uri, None, open_config)
- msg = '/not supported/'
+ msg = '/Unsupported cursor/'
if open_config == "readonly=1":
self.set_kv(cursor)
self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
diff --git a/test/suite/test_cursor_random.py b/test/suite/test_cursor_random.py
index cd91a925b0c..16ce5cae685 100644
--- a/test/suite/test_cursor_random.py
+++ b/test/suite/test_cursor_random.py
@@ -51,7 +51,7 @@ class test_cursor_random(wttest.WiredTigerTestCase):
uri = self.type
self.session.create(uri, 'key_format=S,value_format=S')
cursor = self.session.open_cursor(uri, None, self.config)
- msg = "/not supported/"
+ msg = "/Unsupported cursor/"
self.assertRaisesWithMessage(
wiredtiger.WiredTigerError, lambda: cursor.compare(cursor), msg)
self.assertRaisesWithMessage(
diff --git a/test/suite/test_join01.py b/test/suite/test_join01.py
index 7630706379c..539a3a3ae57 100644
--- a/test/suite/test_join01.py
+++ b/test/suite/test_join01.py
@@ -341,7 +341,7 @@ class test_join01(wttest.WiredTigerTestCase):
'/index cursor is being used in a join/')
# Only a small number of operations allowed on a join cursor
- msg = "/not supported/"
+ msg = "/Unsupported cursor/"
self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
lambda: jc.search(), msg)
diff --git a/test/suite/test_readonly01.py b/test/suite/test_readonly01.py
index 86604eb6bfb..59e9743ab7e 100644
--- a/test/suite/test_readonly01.py
+++ b/test/suite/test_readonly01.py
@@ -96,7 +96,10 @@ class test_readonly01(wttest.WiredTigerTestCase, suite_subprocess):
# connection with readonly.
#
self.close_conn()
- if self.dirchmod:
+ #
+ # The chmod command is not fully portable to windows.
+ #
+ if self.dirchmod and os.name == 'posix':
for f in os.listdir(self.home):
if os.path.isfile(f):
os.chmod(f, 0444)
@@ -133,7 +136,7 @@ class test_readonly01(wttest.WiredTigerTestCase, suite_subprocess):
self.create = True
def test_readonly(self):
- if self.dirchmod:
+ if self.dirchmod and os.name == 'posix':
with self.expectedStderrPattern('Permission'):
self.readonly()
else:
diff --git a/test/suite/test_readonly02.py b/test/suite/test_readonly02.py
index e94dd85857d..0df5465642d 100644
--- a/test/suite/test_readonly02.py
+++ b/test/suite/test_readonly02.py
@@ -54,10 +54,8 @@ class test_readonly02(wttest.WiredTigerTestCase, suite_subprocess):
# 1. setting readonly on a new database directory
# 2. an unclean shutdown and reopening readonly
# 3. logging with zero-fill enabled and readonly
- # 4. readonly and statistics logging
#
badcfg1 = 'log=(enabled,zero_fill=true)'
- badcfg2 = 'statistics_log=(wait=3)'
def setUpConnectionOpen(self, dir):
self.home = dir
@@ -68,8 +66,10 @@ class test_readonly02(wttest.WiredTigerTestCase, suite_subprocess):
if self.create:
# 1. setting readonly on a new database directory
# Setting readonly prevents creation so we should see an
- # ENOENT error because the lock file does not exist.
+ # error because the lock file does not exist.
msg = '/No such file/'
+ if os.name != 'posix':
+ msg = '/cannot find the file/'
os.mkdir(rdonlydir)
self.assertRaisesWithMessage(wiredtiger.WiredTigerError,
lambda: self.wiredtiger_open(
@@ -111,8 +111,6 @@ class test_readonly02(wttest.WiredTigerTestCase, suite_subprocess):
# Close the connection. Reopen readonly with other bad settings.
# 3. logging with zero-fill enabled and readonly
self.close_checkerror(self.badcfg1)
- # 4. readonly and statistics logging
- self.close_checkerror(self.badcfg2)
if __name__ == '__main__':
wttest.run()
diff --git a/test/suite/test_readonly03.py b/test/suite/test_readonly03.py
index 981a21d51ac..d9930e8f553 100644
--- a/test/suite/test_readonly03.py
+++ b/test/suite/test_readonly03.py
@@ -68,7 +68,7 @@ class test_readonly03(wttest.WiredTigerTestCase, suite_subprocess):
# Now close and reopen. Note that the connection function
# above will reopen it readonly.
self.reopen_conn()
- msg = '/not supported/'
+ msg = '/Unsupported/'
c = self.session.open_cursor(self.uri, None, None)
for op in self.cursor_ops:
c.set_key(1)