diff options
author | Keith Bostic <keith.bostic@mongodb.com> | 2017-10-19 01:42:51 -0400 |
---|---|---|
committer | Sulabh Mahajan <sulabh.mahajan@mongodb.com> | 2017-10-19 16:42:51 +1100 |
commit | c641614175903787cb17bb594c55f1154a0c8f31 (patch) | |
tree | ecba18d9cf91d25f4ea0f69d3f7ecdde975daade /src | |
parent | 133924fb9d14b4f2465c70ee60cc4abf913fd0bd (diff) | |
download | mongo-c641614175903787cb17bb594c55f1154a0c8f31.tar.gz |
WT-3672 Test format failure with commit timestamp older than oldest timestamp (#3747)
* Test format failure with commit timestamp older than oldest timestamp
When validating a timestamp, include the type of timestamp with any
error message, we validate read timestamps as well as commit timestamps.
* Don't update the thread's information until after the commit, otherwise
we could race with the timestamp thread and try to commit a change at a
timestamp earlier than the "oldest" timestamp.
* Rework the timestamp() function so we can't read the global timestamp
counter until after we've read the latest-commit timestamp value from
the running threads.
Rework for clarity, and assert the expected relationship between the
thread timestamp values and the global timestamp counter.
Diffstat (limited to 'src')
-rw-r--r-- | src/include/extern.h | 2 | ||||
-rw-r--r-- | src/txn/txn.c | 4 | ||||
-rw-r--r-- | src/txn/txn_timestamp.c | 19 |
3 files changed, 13 insertions, 12 deletions
diff --git a/src/include/extern.h b/src/include/extern.h index 71bda687659..5ffae3111cc 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -821,7 +821,7 @@ extern int __wt_txn_parse_timestamp(WT_SESSION_IMPL *session, const char *name, extern int __wt_txn_global_query_timestamp( WT_SESSION_IMPL *session, char *hex_timestamp, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_update_pinned_timestamp(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_global_set_timestamp(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); -extern int __wt_timestamp_validate(WT_SESSION_IMPL *session, wt_timestamp_t *ts, WT_CONFIG_ITEM *cval, bool cmp_oldest, bool cmp_stable, bool cmp_commit) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_timestamp_validate(WT_SESSION_IMPL *session, const char *name, wt_timestamp_t *ts, WT_CONFIG_ITEM *cval, bool cmp_oldest, bool cmp_stable, bool cmp_commit) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_txn_set_timestamp(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_txn_set_commit_timestamp(WT_SESSION_IMPL *session); extern void __wt_txn_clear_commit_timestamp(WT_SESSION_IMPL *session); diff --git a/src/txn/txn.c b/src/txn/txn.c index cfdb7d26498..ab8aa039594 100644 --- a/src/txn/txn.c +++ b/src/txn/txn.c @@ -446,7 +446,7 @@ __wt_txn_config(WT_SESSION_IMPL *session, const char *cfg[]) WT_RET(__wt_txn_parse_timestamp(session, "read", &ts, &cval)); WT_RET(__wt_timestamp_validate(session, - &ts, &cval, true, false, false)); + "read", &ts, &cval, true, false, false)); __wt_timestamp_set(&txn->read_timestamp, &ts); __wt_txn_set_read_timestamp(session); txn->isolation = WT_ISO_SNAPSHOT; @@ -586,7 +586,7 @@ __wt_txn_commit(WT_SESSION_IMPL *session, const char *cfg[]) #ifdef HAVE_TIMESTAMPS WT_ERR(__wt_txn_parse_timestamp(session, "commit", &ts, &cval)); WT_ERR(__wt_timestamp_validate(session, - &ts, &cval, true, true, true)); + "commit", &ts, &cval, true, true, true)); __wt_timestamp_set(&txn->commit_timestamp, &ts); __wt_txn_set_commit_timestamp(session); #else diff --git a/src/txn/txn_timestamp.c b/src/txn/txn_timestamp.c index 8f90afeb8b4..0201036684d 100644 --- a/src/txn/txn_timestamp.c +++ b/src/txn/txn_timestamp.c @@ -481,8 +481,9 @@ __wt_txn_global_set_timestamp(WT_SESSION_IMPL *session, const char *cfg[]) * global stable and/or running transaction commit timestamp. */ int -__wt_timestamp_validate(WT_SESSION_IMPL *session, wt_timestamp_t *ts, - WT_CONFIG_ITEM *cval, bool cmp_oldest, bool cmp_stable, bool cmp_commit) +__wt_timestamp_validate(WT_SESSION_IMPL *session, const char *name, + wt_timestamp_t *ts, WT_CONFIG_ITEM *cval, + bool cmp_oldest, bool cmp_stable, bool cmp_commit) { WT_TXN *txn = &session->txn; WT_TXN_GLOBAL *txn_global = &S2C(session)->txn_global; @@ -503,12 +504,12 @@ __wt_timestamp_validate(WT_SESSION_IMPL *session, wt_timestamp_t *ts, if (older_than_oldest_ts) WT_RET_MSG(session, EINVAL, - "commit timestamp %.*s older than oldest timestamp", - (int)cval->len, cval->str); + "%s timestamp %.*s older than oldest timestamp", + name, (int)cval->len, cval->str); if (older_than_stable_ts) WT_RET_MSG(session, EINVAL, - "commit timestamp %.*s older than stable timestamp", - (int)cval->len, cval->str); + "%s timestamp %.*s older than stable timestamp", + name, (int)cval->len, cval->str); /* * Compare against the commit timestamp of the current transaction. @@ -520,9 +521,9 @@ __wt_timestamp_validate(WT_SESSION_IMPL *session, wt_timestamp_t *ts, WT_RET(__wt_timestamp_to_hex_string( session, hex_timestamp, &txn->first_commit_timestamp)); WT_RET_MSG(session, EINVAL, - "commit timestamp %.*s older than the first " + "%s timestamp %.*s older than the first " "commit timestamp %s for this transaction", - (int)cval->len, cval->str, hex_timestamp); + name, (int)cval->len, cval->str, hex_timestamp); } return (0); @@ -554,7 +555,7 @@ __wt_txn_set_timestamp(WT_SESSION_IMPL *session, const char *cfg[]) "to set a commit_timestamp"); WT_RET(__wt_txn_parse_timestamp(session, "commit", &ts, &cval)); WT_RET(__wt_timestamp_validate(session, - &ts, &cval, true, true, true)); + "commit", &ts, &cval, true, true, true)); __wt_timestamp_set(&txn->commit_timestamp, &ts); __wt_txn_set_commit_timestamp(session); #else |