diff options
Diffstat (limited to 'test/format')
| -rw-r--r-- | test/format/config.h | 4 | ||||
| -rw-r--r-- | test/format/format.h | 4 | ||||
| -rw-r--r-- | test/format/ops.c | 57 | ||||
| -rw-r--r-- | test/format/util.c | 44 |
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); +} |
