summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2014-12-10 12:11:21 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2014-12-10 12:11:21 +1100
commit77271d186e6452412237c91c34b7170129c7ce63 (patch)
treee9761abaefc5c8d467d5363ab3d725a179dc6aa3
parent1b8d8292ba4ef82819c9932cb36c4d6d502cecfa (diff)
parent69fc77260c540ab61339255eaf7533fe74315377 (diff)
downloadmongo-77271d186e6452412237c91c34b7170129c7ce63.tar.gz
Merge branch 'develop' into sweep-more
-rw-r--r--src/include/extern.h4
-rw-r--r--src/include/lsm.h3
-rw-r--r--src/lsm/lsm_cursor.c114
-rw-r--r--src/lsm/lsm_tree.c2
-rw-r--r--src/lsm/lsm_work_unit.c82
-rw-r--r--src/schema/schema_drop.c13
-rw-r--r--src/schema/schema_open.c8
-rw-r--r--src/schema/schema_stat.c4
-rw-r--r--src/schema/schema_worker.c9
-rw-r--r--src/session/session_api.c2
-rw-r--r--test/suite/test_txn02.py14
-rw-r--r--test/suite/test_txn05.py10
-rw-r--r--test/suite/test_txn07.py48
13 files changed, 147 insertions, 166 deletions
diff --git a/src/include/extern.h b/src/include/extern.h
index c982376ea46..bc75a6eda26 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -518,8 +518,8 @@ extern int __wt_schema_open_colgroups(WT_SESSION_IMPL *session, WT_TABLE *table)
extern int __wt_schema_open_index(WT_SESSION_IMPL *session, WT_TABLE *table, const char *idxname, size_t len, WT_INDEX **indexp);
extern int __wt_schema_open_indices(WT_SESSION_IMPL *session, WT_TABLE *table);
extern int __wt_schema_open_table(WT_SESSION_IMPL *session, const char *name, size_t namelen, int ok_incomplete, WT_TABLE **tablep);
-extern int __wt_schema_get_colgroup(WT_SESSION_IMPL *session, const char *uri, WT_TABLE **tablep, WT_COLGROUP **colgroupp);
-extern int __wt_schema_get_index(WT_SESSION_IMPL *session, const char *uri, WT_TABLE **tablep, WT_INDEX **indexp);
+extern int __wt_schema_get_colgroup(WT_SESSION_IMPL *session, const char *uri, int quiet, WT_TABLE **tablep, WT_COLGROUP **colgroupp);
+extern int __wt_schema_get_index(WT_SESSION_IMPL *session, const char *uri, int quiet, WT_TABLE **tablep, WT_INDEX **indexp);
extern int __wt_schema_colcheck(WT_SESSION_IMPL *session, const char *key_format, const char *value_format, WT_CONFIG_ITEM *colconf, u_int *kcolsp, u_int *vcolsp);
extern int __wt_table_check(WT_SESSION_IMPL *session, WT_TABLE *table);
extern int __wt_struct_plan(WT_SESSION_IMPL *session, WT_TABLE *table, const char *columns, size_t len, int value_only, WT_ITEM *plan);
diff --git a/src/include/lsm.h b/src/include/lsm.h
index c3365d2416b..7055de7b264 100644
--- a/src/include/lsm.h
+++ b/src/include/lsm.h
@@ -218,8 +218,7 @@ struct __wt_lsm_tree {
#define WT_LSM_TREE_COMPACTING 0x02 /* Tree being compacted */
#define WT_LSM_TREE_NEED_SWITCH 0x04 /* New chunk needs creating */
#define WT_LSM_TREE_OPEN 0x08 /* The tree is open */
-#define WT_LSM_TREE_SWITCH_INPROGRESS 0x10 /* Switch in progress */
-#define WT_LSM_TREE_THROTTLE 0x20 /* Throttle updates */
+#define WT_LSM_TREE_THROTTLE 0x10 /* Throttle updates */
uint32_t flags;
};
diff --git a/src/lsm/lsm_cursor.c b/src/lsm/lsm_cursor.c
index 5a1f22d796c..9871ee94166 100644
--- a/src/lsm/lsm_cursor.c
+++ b/src/lsm/lsm_cursor.c
@@ -19,6 +19,41 @@ static int __clsm_open_cursors(WT_CURSOR_LSM *, int, u_int, uint32_t);
static int __clsm_reset_cursors(WT_CURSOR_LSM *, WT_CURSOR *);
/*
+ * __clsm_request_switch --
+ * Request an LSM tree switch for a cursor operation.
+ */
+static inline int
+__clsm_request_switch(WT_CURSOR_LSM *clsm)
+{
+ WT_DECL_RET;
+ WT_LSM_TREE *lsm_tree;
+ WT_SESSION_IMPL *session;
+
+ lsm_tree = clsm->lsm_tree;
+ session = (WT_SESSION_IMPL *)clsm->iface.session;
+
+ if (!F_ISSET(lsm_tree, WT_LSM_TREE_NEED_SWITCH)) {
+ /*
+ * Check that we are up-to-date: don't set the switch if the
+ * tree has changed since we last opened cursors: that can lead
+ * to switching multiple times when only one switch is
+ * required, creating very small chunks.
+ */
+ WT_RET(__wt_lsm_tree_readlock(session, lsm_tree));
+ if (lsm_tree->nchunks == 0 ||
+ (clsm->dsk_gen == lsm_tree->dsk_gen &&
+ !F_ISSET(lsm_tree, WT_LSM_TREE_NEED_SWITCH))) {
+ ret = __wt_lsm_manager_push_entry(
+ session, WT_LSM_WORK_SWITCH, 0, lsm_tree);
+ F_SET(lsm_tree, WT_LSM_TREE_NEED_SWITCH);
+ }
+ WT_TRET(__wt_lsm_tree_readunlock(session, lsm_tree));
+ }
+
+ return (ret);
+}
+
+/*
* __clsm_enter_update --
* Make sure an LSM cursor is ready to perform an update.
*/
@@ -26,11 +61,10 @@ static int
__clsm_enter_update(WT_CURSOR_LSM *clsm)
{
WT_CURSOR *primary;
- WT_DECL_RET;
WT_LSM_CHUNK *primary_chunk;
WT_LSM_TREE *lsm_tree;
WT_SESSION_IMPL *session;
- int have_primary, ovfl, waited;
+ int hard_limit, have_primary, ovfl, waited;
lsm_tree = clsm->lsm_tree;
ovfl = 0;
@@ -40,11 +74,11 @@ __clsm_enter_update(WT_CURSOR_LSM *clsm)
primary = NULL;
have_primary = 0;
} else {
- if ((primary = clsm->cursors[clsm->nchunks - 1]) == NULL)
- return (0);
+ primary = clsm->cursors[clsm->nchunks - 1];
primary_chunk = clsm->primary_chunk;
- have_primary = (primary_chunk != NULL &&
- !F_ISSET(lsm_tree, WT_LSM_TREE_SWITCH_INPROGRESS));
+ have_primary = (primary != NULL && primary_chunk != NULL &&
+ (primary_chunk->switch_txn == WT_TXN_NONE ||
+ TXNID_LT(session->txn.id, primary_chunk->switch_txn)));
}
/*
@@ -58,57 +92,43 @@ __clsm_enter_update(WT_CURSOR_LSM *clsm)
* chunk grows twice as large as the configured size, block until it
* can be switched.
*/
- if (!F_ISSET(lsm_tree, WT_LSM_TREE_NEED_SWITCH)) {
- if (have_primary)
- WT_WITH_BTREE(session,
- ((WT_CURSOR_BTREE *)primary)->btree,
- ovfl = __wt_btree_size_overflow(
- session, lsm_tree->chunk_size));
+ hard_limit = F_ISSET(lsm_tree, WT_LSM_TREE_NEED_SWITCH) ? 1 : 0;
- if (ovfl || !have_primary) {
- /*
- * Check that we are up-to-date: don't set the switch
- * if the tree has changed since we last opened
- * cursors: that can lead to switching multiple times
- * when only one switch is required, creating very
- * small chunks.
- */
- WT_RET(__wt_lsm_tree_readlock(session, lsm_tree));
- if (lsm_tree->nchunks == 0 ||
- (clsm->dsk_gen == lsm_tree->dsk_gen &&
- !F_ISSET(lsm_tree, WT_LSM_TREE_NEED_SWITCH))) {
- ret = __wt_lsm_manager_push_entry(
- session, WT_LSM_WORK_SWITCH, 0, lsm_tree);
- F_SET(lsm_tree, WT_LSM_TREE_NEED_SWITCH);
- }
- WT_TRET(__wt_lsm_tree_readunlock(session, lsm_tree));
- WT_RET(ret);
- ovfl = 0;
- }
- } else if (have_primary)
+ if (have_primary) {
WT_WITH_BTREE(session, ((WT_CURSOR_BTREE *)primary)->btree,
ovfl = __wt_btree_size_overflow(
- session, 2 * lsm_tree->chunk_size));
+ session, hard_limit ?
+ 2 * lsm_tree->chunk_size : lsm_tree->chunk_size));
+
+ /* If there was no overflow, we're done. */
+ if (!ovfl)
+ return (0);
+ }
+
+ /* Request a switch. */
+ WT_RET(__clsm_request_switch(clsm));
+
+ /* If we only overflowed the soft limit, we're done. */
+ if (have_primary && !hard_limit)
+ return (0);
/*
- * If there is no primary chunk, or it has really overflowed, which
- * either means a worker thread has fallen behind or there has just
- * been a user-level checkpoint, wait until the tree changes.
+ * If there is no primary chunk, or it has overflowed the hard limit,
+ * which either means a worker thread has fallen behind or there has
+ * just been a user-level checkpoint, wait until the tree changes.
*
* We used to switch chunks in the application thread if we got to
* here, but that is problematic because there is a transaction in
* progress and it could roll back, leaving the metadata inconsistent.
*/
- if (ovfl || !have_primary) {
- for (waited = 0;
- lsm_tree->nchunks == 0 ||
- clsm->dsk_gen == lsm_tree->dsk_gen;
- ++waited) {
- if (waited % 100 == 0)
- WT_RET(__wt_lsm_manager_push_entry(
- session, WT_LSM_WORK_SWITCH, 0, lsm_tree));
- __wt_sleep(0, 10);
- }
+ for (waited = 0;
+ lsm_tree->nchunks == 0 ||
+ clsm->dsk_gen == lsm_tree->dsk_gen;
+ ++waited) {
+ if (waited % 1000 == 0)
+ WT_RET(__wt_lsm_manager_push_entry(
+ session, WT_LSM_WORK_SWITCH, 0, lsm_tree));
+ __wt_sleep(0, 10);
}
return (0);
diff --git a/src/lsm/lsm_tree.c b/src/lsm/lsm_tree.c
index 37ddc94bad4..888f12bdd94 100644
--- a/src/lsm/lsm_tree.c
+++ b/src/lsm/lsm_tree.c
@@ -807,7 +807,6 @@ __wt_lsm_tree_switch(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
!F_ISSET(lsm_tree, WT_LSM_TREE_NEED_SWITCH))
goto err;
- F_SET(lsm_tree, WT_LSM_TREE_SWITCH_INPROGRESS);
/* Update the throttle time. */
__wt_lsm_tree_throttle(session, lsm_tree, 0);
@@ -836,7 +835,6 @@ __wt_lsm_tree_switch(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree)
/* Set the switch transaction in the previous chunk, if necessary. */
if (last_chunk != NULL && last_chunk->switch_txn == WT_TXN_NONE)
last_chunk->switch_txn = __wt_txn_new_id(session);
- F_CLR(lsm_tree, WT_LSM_TREE_SWITCH_INPROGRESS);
err: WT_TRET(__wt_lsm_tree_writeunlock(session, lsm_tree));
/*
diff --git a/src/lsm/lsm_work_unit.c b/src/lsm/lsm_work_unit.c
index c27b7edb234..81a588af84d 100644
--- a/src/lsm/lsm_work_unit.c
+++ b/src/lsm/lsm_work_unit.c
@@ -70,54 +70,58 @@ __wt_lsm_get_chunk_to_flush(WT_SESSION_IMPL *session,
WT_LSM_TREE *lsm_tree, int force, WT_LSM_CHUNK **chunkp)
{
WT_DECL_RET;
- WT_LSM_CHUNK *chunk;
- u_int i, end;
+ WT_LSM_CHUNK *chunk, *evict_chunk, *flush_chunk;
+ u_int i;
*chunkp = NULL;
- chunk = NULL;
+ chunk = evict_chunk = flush_chunk = NULL;
WT_ASSERT(session, lsm_tree->queue_ref > 0);
WT_RET(__wt_lsm_tree_readlock(session, lsm_tree));
- if (!F_ISSET(lsm_tree, WT_LSM_TREE_ACTIVE))
+ if (!F_ISSET(lsm_tree, WT_LSM_TREE_ACTIVE) ||
+ lsm_tree->nchunks == 0)
return (__wt_lsm_tree_readunlock(session, lsm_tree));
- /*
- * Normally we don't want to force out the last chunk. But if we're
- * doing a forced flush, likely from a compact call, then we want
- * to include the final chunk.
- */
- end = force ? lsm_tree->nchunks : lsm_tree->nchunks - 1;
- for (i = 0; i < end; i++) {
- if (!F_ISSET(lsm_tree->chunk[i], WT_LSM_CHUNK_ONDISK) ||
- (chunk == NULL &&
- !F_ISSET(lsm_tree->chunk[i], WT_LSM_CHUNK_STABLE) &&
- !lsm_tree->chunk[i]->evicted)) {
- chunk = lsm_tree->chunk[i];
- (void)WT_ATOMIC_ADD4(chunk->refcnt, 1);
- WT_ERR(__wt_verbose(session, WT_VERB_LSM,
- "Flush%s: return chunk %u of %u: %s",
- force ? " w/ force" : "", i, end - 1, chunk->uri));
-
+ /* Search for a chunk to evict and/or a chunk to flush. */
+ for (i = 0; i < lsm_tree->nchunks; i++) {
+ chunk = lsm_tree->chunk[i];
+ if (F_ISSET(chunk, WT_LSM_CHUNK_ONDISK)) {
/*
- * If retrying a discard push an additional work unit
- * so there are enough to trigger checkpoints.
+ * Normally we don't want to force out the last chunk.
+ * But if we're doing a forced flush on behalf of a
+ * compact, then we want to include the final chunk.
*/
- if (F_ISSET(chunk, WT_LSM_CHUNK_ONDISK)) {
- /*
- * Don't be overly zealous about pushing old
- * chunks from cache. Attempting too many drops
- * can interfere with checkpoints.
- */
- if (__wt_random(session->rnd) & 1) {
- (void)WT_ATOMIC_SUB4(chunk->refcnt, 1);
- chunk = NULL;
- continue;
- }
- WT_ERR(__wt_lsm_manager_push_entry(
- session, WT_LSM_WORK_FLUSH, 0, lsm_tree));
- }
- break;
- }
+ if (evict_chunk == NULL &&
+ !chunk->evicted &&
+ !F_ISSET(chunk, WT_LSM_CHUNK_STABLE))
+ evict_chunk = chunk;
+ } else if (flush_chunk == NULL &&
+ chunk->switch_txn != 0 &&
+ (force || i < lsm_tree->nchunks - 1))
+ flush_chunk = chunk;
+ }
+
+ /*
+ * Don't be overly zealous about pushing old chunks from cache.
+ * Attempting too many drops can interfere with checkpoints.
+ *
+ * If retrying a discard push an additional work unit so there are
+ * enough to trigger checkpoints.
+ */
+ if (evict_chunk != NULL && flush_chunk != NULL) {
+ chunk = (__wt_random(session->rnd) & 1) ?
+ evict_chunk : flush_chunk;
+ WT_ERR(__wt_lsm_manager_push_entry(
+ session, WT_LSM_WORK_FLUSH, 0, lsm_tree));
+ } else
+ chunk = (evict_chunk != NULL) ? evict_chunk : flush_chunk;
+
+ if (chunk != NULL) {
+ (void)WT_ATOMIC_ADD4(chunk->refcnt, 1);
+ WT_ERR(__wt_verbose(session, WT_VERB_LSM,
+ "Flush%s: return chunk %u of %u: %s",
+ force ? " w/ force" : "",
+ i, lsm_tree->nchunks, chunk->uri));
}
err: if (ret != 0 && chunk != NULL)
diff --git a/src/schema/schema_drop.c b/src/schema/schema_drop.c
index c904142a22c..ca09d25a495 100644
--- a/src/schema/schema_drop.c
+++ b/src/schema/schema_drop.c
@@ -57,7 +57,7 @@ __drop_file(
*/
static int
__drop_colgroup(
- WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
+ WT_SESSION_IMPL *session, const char *uri, int force, const char *cfg[])
{
WT_COLGROUP *colgroup;
WT_DECL_RET;
@@ -67,7 +67,7 @@ __drop_colgroup(
/* If we can get the colgroup, detach it from the table. */
if ((ret = __wt_schema_get_colgroup(
- session, uri, &table, &colgroup)) == 0) {
+ session, uri, force, &table, &colgroup)) == 0) {
table->cg_complete = 0;
WT_TRET(__wt_schema_drop(session, colgroup->source, cfg));
}
@@ -82,14 +82,15 @@ __drop_colgroup(
*/
static int
__drop_index(
- WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
+ WT_SESSION_IMPL *session, const char *uri, int force, const char *cfg[])
{
WT_INDEX *idx;
WT_DECL_RET;
WT_TABLE *table;
/* If we can get the colgroup, detach it from the table. */
- if ((ret = __wt_schema_get_index(session, uri, &table, &idx)) == 0) {
+ if ((ret = __wt_schema_get_index(
+ session, uri, force, &table, &idx)) == 0) {
table->idx_complete = 0;
WT_TRET(__wt_schema_drop(session, idx->source, cfg));
}
@@ -168,11 +169,11 @@ __wt_schema_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[])
WT_CLEAR_BTREE_IN_SESSION(session);
if (WT_PREFIX_MATCH(uri, "colgroup:"))
- ret = __drop_colgroup(session, uri, cfg);
+ ret = __drop_colgroup(session, uri, force, cfg);
else if (WT_PREFIX_MATCH(uri, "file:"))
ret = __drop_file(session, uri, force, cfg);
else if (WT_PREFIX_MATCH(uri, "index:"))
- ret = __drop_index(session, uri, cfg);
+ ret = __drop_index(session, uri, force, cfg);
else if (WT_PREFIX_MATCH(uri, "lsm:"))
ret = __wt_lsm_tree_drop(session, uri, cfg);
else if (WT_PREFIX_MATCH(uri, "table:"))
diff --git a/src/schema/schema_open.c b/src/schema/schema_open.c
index 994c26758d0..f5937381cbb 100644
--- a/src/schema/schema_open.c
+++ b/src/schema/schema_open.c
@@ -472,7 +472,7 @@ err: if (table != NULL)
*/
int
__wt_schema_get_colgroup(WT_SESSION_IMPL *session,
- const char *uri, WT_TABLE **tablep, WT_COLGROUP **colgroupp)
+ const char *uri, int quiet, WT_TABLE **tablep, WT_COLGROUP **colgroupp)
{
WT_COLGROUP *colgroup;
WT_TABLE *table;
@@ -504,6 +504,8 @@ __wt_schema_get_colgroup(WT_SESSION_IMPL *session,
}
__wt_schema_release_table(session, table);
+ if (quiet)
+ WT_RET(ENOENT);
WT_RET_MSG(session, ENOENT, "%s not found in table", uri);
}
@@ -513,7 +515,7 @@ __wt_schema_get_colgroup(WT_SESSION_IMPL *session,
*/
int
__wt_schema_get_index(WT_SESSION_IMPL *session,
- const char *uri, WT_TABLE **tablep, WT_INDEX **indexp)
+ const char *uri, int quiet, WT_TABLE **tablep, WT_INDEX **indexp)
{
WT_DECL_RET;
WT_INDEX *idx;
@@ -554,5 +556,7 @@ err: __wt_schema_release_table(session, table);
if (*indexp != NULL)
return (0);
+ if (quiet)
+ WT_RET(ENOENT);
WT_RET_MSG(session, ENOENT, "%s not found in table", uri);
}
diff --git a/src/schema/schema_stat.c b/src/schema/schema_stat.c
index cb8e7f6c418..06b3ac5ca6e 100644
--- a/src/schema/schema_stat.c
+++ b/src/schema/schema_stat.c
@@ -19,7 +19,7 @@ __wt_curstat_colgroup_init(WT_SESSION_IMPL *session,
WT_DECL_ITEM(buf);
WT_DECL_RET;
- WT_RET(__wt_schema_get_colgroup(session, uri, NULL, &colgroup));
+ WT_RET(__wt_schema_get_colgroup(session, uri, 0, NULL, &colgroup));
WT_RET(__wt_scr_alloc(session, 0, &buf));
WT_ERR(__wt_buf_fmt(session, buf, "statistics:%s", colgroup->source));
@@ -41,7 +41,7 @@ __wt_curstat_index_init(WT_SESSION_IMPL *session,
WT_DECL_RET;
WT_INDEX *idx;
- WT_RET(__wt_schema_get_index(session, uri, NULL, &idx));
+ WT_RET(__wt_schema_get_index(session, uri, 0, NULL, &idx));
WT_RET(__wt_scr_alloc(session, 0, &buf));
WT_ERR(__wt_buf_fmt(session, buf, "statistics:%s", idx->source));
diff --git a/src/schema/schema_worker.c b/src/schema/schema_worker.c
index 9895246685f..7660a9b5054 100644
--- a/src/schema/schema_worker.c
+++ b/src/schema/schema_worker.c
@@ -60,12 +60,13 @@ __wt_schema_worker(WT_SESSION_IMPL *session,
WT_TRET(__wt_session_release_btree(session));
}
} else if (WT_PREFIX_MATCH(uri, "colgroup:")) {
- WT_ERR(__wt_schema_get_colgroup(session, uri, NULL, &colgroup));
- WT_ERR(__wt_schema_worker(session, colgroup->source,
- file_func, name_func, cfg, open_flags));
+ WT_ERR(__wt_schema_get_colgroup(
+ session, uri, 0, NULL, &colgroup));
+ WT_ERR(__wt_schema_worker(session,
+ colgroup->source, file_func, name_func, cfg, open_flags));
} else if (WT_PREFIX_SKIP(tablename, "index:")) {
idx = NULL;
- WT_ERR(__wt_schema_get_index(session, uri, NULL, &idx));
+ WT_ERR(__wt_schema_get_index(session, uri, 0, NULL, &idx));
WT_ERR(__wt_schema_worker(session, idx->source,
file_func, name_func, cfg, open_flags));
} else if (WT_PREFIX_MATCH(uri, "lsm:")) {
diff --git a/src/session/session_api.c b/src/session/session_api.c
index 2fd48a89ffc..dc3c7d7041f 100644
--- a/src/session/session_api.c
+++ b/src/session/session_api.c
@@ -247,7 +247,7 @@ __wt_open_cursor(WT_SESSION_IMPL *session,
* the underlying data source.
*/
WT_RET(__wt_schema_get_colgroup(
- session, uri, NULL, &colgroup));
+ session, uri, 0, NULL, &colgroup));
WT_RET(__wt_open_cursor(
session, colgroup->source, owner, cfg, cursorp));
} else if (WT_PREFIX_MATCH(uri, "config:"))
diff --git a/test/suite/test_txn02.py b/test/suite/test_txn02.py
index 8e6da405860..79c854d2bf6 100644
--- a/test/suite/test_txn02.py
+++ b/test/suite/test_txn02.py
@@ -161,10 +161,9 @@ class test_txn02(wttest.WiredTigerTestCase, suite_subprocess):
try:
self.check(backup_conn.open_session(), None, committed)
finally:
- # Yield so that the archive thread gets a chance to run
- # before we close the connection. time.sleep(0) is not
- # guaranteed to force a context switch. So use a small time.
- time.sleep(0.01)
+ # Sleep long enough so that the archive thread is guaranteed
+ # to run before we close the connection.
+ time.sleep(1.0)
backup_conn.close()
count += 1
#
@@ -255,8 +254,11 @@ class test_txn02(wttest.WiredTigerTestCase, suite_subprocess):
self.check_all(current, committed)
# Check the log state after the entire op completes
- # and run recovery.
- self.check_log(committed)
+ # and run recovery. check_log() takes over a second
+ # to run, so we don't want to run it for all scenarios;
+ # rather, we run it about 100 times overall.
+ if self.scenario_number % (len(test_txn02.scenarios) / 100 + 1) == 0:
+ self.check_log(committed)
if __name__ == '__main__':
wttest.run()
diff --git a/test/suite/test_txn05.py b/test/suite/test_txn05.py
index 738e3eb9e7a..cc5db523c27 100644
--- a/test/suite/test_txn05.py
+++ b/test/suite/test_txn05.py
@@ -141,10 +141,9 @@ class test_txn05(wttest.WiredTigerTestCase, suite_subprocess):
try:
self.check(backup_conn.open_session(), None, committed)
finally:
- # Let other threads like archive run before closing.
- # time.sleep(0) is not guaranteed to force a context switch.
- # Use a small timeout.
- time.sleep(0.01)
+ # Sleep long enough so that the archive thread is guaranteed
+ # to run before we close the connection.
+ time.sleep(1.0)
backup_conn.close()
count += 1
#
@@ -234,7 +233,8 @@ class test_txn05(wttest.WiredTigerTestCase, suite_subprocess):
# Check the log state after the entire op completes
# and run recovery.
- self.check_log(committed)
+ if self.scenario_number % (len(test_txn05.scenarios) / 100 + 1) == 0:
+ self.check_log(committed)
if __name__ == '__main__':
wttest.run()
diff --git a/test/suite/test_txn07.py b/test/suite/test_txn07.py
index 08dd331a086..3ba9d4d17ec 100644
--- a/test/suite/test_txn07.py
+++ b/test/suite/test_txn07.py
@@ -147,50 +147,6 @@ class test_txn07(wttest.WiredTigerTestCase, suite_subprocess):
finally:
backup_conn.close()
- def check_log(self, committed):
- self.backup(self.backup_dir)
- #
- # Open and close the backup connection a few times to force
- # repeated recovery and log archiving even if later recoveries
- # are essentially no-ops. Confirm that the backup contains
- # the committed operations after recovery.
- #
- # Cycle through the different archive values in a
- # deterministic manner.
- self.archive = self.archive_list[
- self.scenario_number % len(self.archive_list)]
- backup_conn_params = \
- 'log=(enabled,file_max=%s,archive=%s)' % (self.logmax, self.archive)
- orig_logs = fnmatch.filter(os.listdir(self.backup_dir), "*Log*")
- endcount = 2
- count = 0
- while count < endcount:
- backup_conn = wiredtiger_open(self.backup_dir, backup_conn_params)
- try:
- self.check(backup_conn.open_session(), None, committed)
- finally:
- # Let other threads like archive run before closing.
- # time.sleep(0) is not guaranteed to force a context switch.
- # Use a small timeout.
- time.sleep(0.01)
- backup_conn.close()
- count += 1
- #
- # Check logs after repeated openings. The first log should
- # have been archived if configured. Subsequent openings would not
- # archive because no checkpoint is written due to no modifications.
- #
- cur_logs = fnmatch.filter(os.listdir(self.backup_dir), "*Log*")
- for o in orig_logs:
- if self.archive == 'true':
- self.assertEqual(False, o in cur_logs)
- else:
- self.assertEqual(True, o in cur_logs)
- #
- # Run printlog and make sure it exits with zero status.
- #
- self.runWt(['-h', self.backup_dir, 'printlog'], outfilename='printlog.out')
-
def test_ops(self):
# print "Creating %s with config '%s'" % (self.uri, self.create_params)
self.session.create(self.uri, self.create_params)
@@ -273,10 +229,6 @@ class test_txn07(wttest.WiredTigerTestCase, suite_subprocess):
csmall = stat_cursor[stat.conn.log_compress_small][2]
stat_cursor.close()
- # Check the log state after the entire op completes
- # and run recovery.
- self.check_log(committed)
-
if self.compress == '':
self.assertEqual(clen, cmem)
self.assertEqual(cwrites, 0)