summaryrefslogtreecommitdiff
path: root/test/format
diff options
context:
space:
mode:
authorDavid Hows <david.hows@mongodb.com>2017-01-06 12:12:50 +1100
committerDavid Hows <david.hows@mongodb.com>2017-01-06 12:12:50 +1100
commitd48181f6f4db08761ed7b80b0332908b272ad0d0 (patch)
tree38929fdcc5415ee7b001b6f1a406bd5bd777b737 /test/format
parent040e3d6f764c0fb626cb47fede54469f57d0c6e0 (diff)
parent8d2324943364286056ae399043f70b8a937de312 (diff)
Merge branch 'mongodb-3.6' into mongodb-3.2mongodb-3.2.12
Diffstat (limited to 'test/format')
-rw-r--r--test/format/config.h4
-rw-r--r--test/format/format.h4
-rw-r--r--test/format/ops.c57
-rw-r--r--test/format/util.c44
4 files changed, 85 insertions, 24 deletions
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 820bc020c9b..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;
@@ -242,7 +243,7 @@ typedef struct {
} GLOBAL;
extern GLOBAL g;
-typedef struct WT_COMPILER_TYPE_ALIGN(WT_CACHE_LINE_ALIGNMENT) {
+typedef struct {
WT_RAND_STATE rnd; /* thread RNG state */
uint64_t search; /* operations */
@@ -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 283e2912daa..940318c87a9 100644
--- a/test/format/ops.c
+++ b/test/format/ops.c
@@ -50,10 +50,10 @@ static void print_item(const char *, WT_ITEM *);
void
wts_ops(int lastrun)
{
- TINFO *tinfo, total;
+ 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));
@@ -102,19 +103,24 @@ wts_ops(int lastrun)
"=============== thread ops start ===============");
}
- /* Create thread structure; start the worker threads. */
- tinfo = dcalloc((size_t)g.c_threads, sizeof(*tinfo));
+ /*
+ * Create the per-thread structures and start the worker threads.
+ * Allocate the thread structures separately to minimize false sharing.
+ */
+ tinfo_list = dcalloc((size_t)g.c_threads, sizeof(TINFO *));
for (i = 0; i < g.c_threads; ++i) {
- tinfo[i].id = (int)i + 1;
- tinfo[i].state = TINFO_RUNNING;
- testutil_check(
- pthread_create(&tinfo[i].tid, NULL, ops, &tinfo[i]));
+ tinfo_list[i] = tinfo = dcalloc(1, sizeof(TINFO));
+ tinfo->id = (int)i + 1;
+ tinfo->state = TINFO_RUNNING;
+ testutil_check(pthread_create(&tinfo->tid, NULL, ops, tinfo));
}
/*
* 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)
@@ -128,21 +134,22 @@ wts_ops(int lastrun)
/* Clear out the totals each pass. */
memset(&total, 0, sizeof(total));
for (i = 0, running = 0; i < g.c_threads; ++i) {
- total.commit += tinfo[i].commit;
- total.deadlock += tinfo[i].deadlock;
- total.insert += tinfo[i].insert;
- total.remove += tinfo[i].remove;
- total.rollback += tinfo[i].rollback;
- total.search += tinfo[i].search;
- total.update += tinfo[i].update;
-
- switch (tinfo[i].state) {
+ tinfo = tinfo_list[i];
+ total.commit += tinfo->commit;
+ total.deadlock += tinfo->deadlock;
+ total.insert += tinfo->insert;
+ total.remove += tinfo->remove;
+ total.rollback += tinfo->rollback;
+ total.search += tinfo->search;
+ total.update += tinfo->update;
+
+ switch (tinfo->state) {
case TINFO_RUNNING:
running = 1;
break;
case TINFO_COMPLETE:
- tinfo[i].state = TINFO_JOINED;
- (void)pthread_join(tinfo[i].tid, NULL);
+ tinfo->state = TINFO_JOINED;
+ (void)pthread_join(tinfo->tid, NULL);
break;
case TINFO_JOINED:
break;
@@ -154,7 +161,7 @@ wts_ops(int lastrun)
*/
if (fourths == 0 ||
(thread_ops != -1 &&
- tinfo[i].ops >= (uint64_t)thread_ops)) {
+ tinfo->ops >= (uint64_t)thread_ops)) {
/*
* On the last execution, optionally drop core
* for recovery testing.
@@ -163,7 +170,7 @@ wts_ops(int lastrun)
static char *core = NULL;
*core = 0;
}
- tinfo[i].quit = 1;
+ tinfo->quit = 1;
}
}
track("ops", 0ULL, &total);
@@ -173,10 +180,14 @@ wts_ops(int lastrun)
if (fourths != -1)
--fourths;
}
- free(tinfo);
+ for (i = 0; i < g.c_threads; ++i)
+ free(tinfo_list[i]);
+ free(tinfo_list);
/* 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)
@@ -455,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..b9788f1ac75 100644
--- a/test/format/util.c
+++ b/test/format/util.c
@@ -459,3 +459,47 @@ 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_SESSION *session;
+ u_int period;
+ bool access_value;
+ 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_value = false;
+
+ /* Open a session */
+ testutil_check(conn->open_session(conn, NULL, NULL, &session));
+
+ while (!g.workers_finished) {
+ period = mmrand(NULL, 1, 10);
+
+ snprintf(buf, sizeof(buf),
+ "access_pattern_hint=%s", access_value ? "random" : "none");
+ access_value = !access_value;
+ if (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);
+}