diff options
author | Will Korteland <will.korteland@mongodb.com> | 2022-05-26 01:21:52 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-05-26 01:50:52 +0000 |
commit | b215020470389bcaa26ccb50445a6beebce43bc3 (patch) | |
tree | ce226d306e3e9fef99f0b99959616b287bd57539 | |
parent | 75348ed8f3b534ba877436233f5023ac500dc893 (diff) | |
download | mongo-b215020470389bcaa26ccb50445a6beebce43bc3.tar.gz |
Import wiredtiger: 8264e0e17fa236055672700926544a4cb9ccd138 from branch mongodb-master
ref: 3edd40c339..8264e0e17f
for: 6.1.0-rc0
Reverted ticket(s):
WT-9186 Prevent transactions committing data at a timestamp prior to the stable using the timestamp_transaction API
9 files changed, 116 insertions, 149 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index c0630f435f5..677aaa5f5aa 100644 --- a/src/third_party/wiredtiger/import.data +++ b/src/third_party/wiredtiger/import.data @@ -2,5 +2,5 @@ "vendor": "wiredtiger", "github": "wiredtiger/wiredtiger.git", "branch": "mongodb-master", - "commit": "3edd40c339b1e9729281f537bfcdc05dce89b779" + "commit": "8264e0e17fa236055672700926544a4cb9ccd138" } diff --git a/src/third_party/wiredtiger/src/include/txn_inline.h b/src/third_party/wiredtiger/src/include/txn_inline.h index 9393875b7d6..d9441b7af69 100644 --- a/src/third_party/wiredtiger/src/include/txn_inline.h +++ b/src/third_party/wiredtiger/src/include/txn_inline.h @@ -1122,8 +1122,6 @@ __wt_txn_begin(WT_SESSION_IMPL *session, const char *cfg[]) txn = session->txn; txn->isolation = session->isolation; txn->txn_logsync = S2C(session)->txn_logsync; - txn->commit_timestamp = WT_TS_NONE; - txn->first_commit_timestamp = WT_TS_NONE; WT_ASSERT(session, !F_ISSET(txn, WT_TXN_RUNNING)); diff --git a/src/third_party/wiredtiger/src/txn/txn_timestamp.c b/src/third_party/wiredtiger/src/txn/txn_timestamp.c index f7acb69abf4..0f3141ee55a 100644 --- a/src/third_party/wiredtiger/src/txn/txn_timestamp.c +++ b/src/third_party/wiredtiger/src/txn/txn_timestamp.c @@ -509,20 +509,9 @@ __wt_txn_validate_commit_timestamp(WT_SESSION_IMPL *session, wt_timestamp_t *com stable_ts = txn_global->stable_timestamp; if (!F_ISSET(txn, WT_TXN_HAS_TS_PREPARE)) { - /* Compare against the first commit timestamp of the current transaction. */ - if (F_ISSET(txn, WT_TXN_HAS_TS_COMMIT)) { - if (commit_ts < txn->first_commit_timestamp) - WT_RET_MSG(session, EINVAL, - "commit timestamp %s older than the first commit timestamp %s for this " - "transaction", - __wt_timestamp_to_string(commit_ts, ts_string[0]), - __wt_timestamp_to_string(txn->first_commit_timestamp, ts_string[1])); - commit_ts = txn->first_commit_timestamp; - } - /* - * For a non-prepared transactions the commit timestamp should not be less or equal to the - * stable timestamp. + * For a non-prepared transactions the commit timestamp should not be less than the stable + * timestamp. */ if (has_oldest_ts && commit_ts < oldest_ts) WT_RET_MSG(session, EINVAL, "commit timestamp %s is less than the oldest timestamp %s", @@ -534,6 +523,16 @@ __wt_txn_validate_commit_timestamp(WT_SESSION_IMPL *session, wt_timestamp_t *com __wt_timestamp_to_string(commit_ts, ts_string[0]), __wt_timestamp_to_string(stable_ts, ts_string[1])); + /* + * Compare against the commit timestamp of the current transaction. Return an error if the + * given timestamp is older than the first commit timestamp. + */ + if (F_ISSET(txn, WT_TXN_HAS_TS_COMMIT) && commit_ts < txn->first_commit_timestamp) + WT_RET_MSG(session, EINVAL, + "commit timestamp %s older than the first commit timestamp %s for this transaction", + __wt_timestamp_to_string(commit_ts, ts_string[0]), + __wt_timestamp_to_string(txn->first_commit_timestamp, ts_string[1])); + WT_RET(__txn_assert_after_reads(session, "commit", commit_ts)); } else { /* diff --git a/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.cpp b/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.cpp index 0f81367b25e..57eece9c4fe 100644 --- a/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.cpp +++ b/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.cpp @@ -148,14 +148,14 @@ transaction_context::try_rollback(const std::string &config) rollback(config); } -int +void transaction_context::set_commit_timestamp(wt_timestamp_t ts) { /* We don't want to set zero timestamps on transactions if we're not using timestamps. */ if (!_timestamp_manager->enabled()) - return 0; + return; const std::string config = COMMIT_TS + "=" + timestamp_manager::decimal_to_hex(ts); - return _session->timestamp_transaction(_session, config.c_str()); + testutil_check(_session->timestamp_transaction(_session, config.c_str())); } void @@ -220,7 +220,7 @@ thread_context::update( testutil_assert(cursor.get() != nullptr); wt_timestamp_t ts = tsm->get_next_ts(); - testutil_check(transaction.set_commit_timestamp(ts)); + transaction.set_commit_timestamp(ts); cursor->set_key(cursor.get(), key.c_str()); cursor->set_value(cursor.get(), value.c_str()); @@ -257,7 +257,7 @@ thread_context::insert( testutil_assert(cursor.get() != nullptr); wt_timestamp_t ts = tsm->get_next_ts(); - testutil_check(transaction.set_commit_timestamp(ts)); + transaction.set_commit_timestamp(ts); cursor->set_key(cursor.get(), key.c_str()); cursor->set_value(cursor.get(), value.c_str()); @@ -292,18 +292,7 @@ thread_context::remove(scoped_cursor &cursor, uint64_t collection_id, const std: testutil_assert(cursor.get() != nullptr); wt_timestamp_t ts = tsm->get_next_ts(); - - /* - * FIXME: WT-9198 We're concurrently doing a transaction that contains a bunch of operations - * while moving the stable timestamp. Eat the occasional EINVAL from the transaction's first - * commit timestamp being earlier than the stable timestamp. - */ - ret = transaction.set_commit_timestamp(ts); - testutil_assert(ret == 0 || ret == EINVAL); - if (ret != 0) { - transaction.set_needs_rollback(true); - return (false); - } + transaction.set_commit_timestamp(ts); cursor->set_key(cursor.get(), key.c_str()); ret = cursor->remove(cursor.get()); diff --git a/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.h b/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.h index e968db51ec9..290bd9d0d5d 100644 --- a/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.h +++ b/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.h @@ -67,7 +67,7 @@ class transaction_context { /* Attempt to rollback the transaction given the requirements are met. */ void try_rollback(const std::string &config = ""); /* Set a commit timestamp. */ - int set_commit_timestamp(wt_timestamp_t ts); + void set_commit_timestamp(wt_timestamp_t ts); /* Set that the transaction needs to be rolled back. */ void set_needs_rollback(bool rollback); /* diff --git a/src/third_party/wiredtiger/test/csuite/tiered_abort/main.c b/src/third_party/wiredtiger/test/csuite/tiered_abort/main.c index 76aa0dd7eb2..74e9f8b5789 100644 --- a/src/third_party/wiredtiger/test/csuite/tiered_abort/main.c +++ b/src/third_party/wiredtiger/test/csuite/tiered_abort/main.c @@ -85,7 +85,7 @@ static const char *const uri_shadow = "shadow"; static const char *const sentinel_file = "sentinel_ready"; static bool use_ts; -static uint64_t global_ts = 1; +static volatile uint64_t global_ts = 1; static uint32_t flush_calls = 1; /* @@ -136,8 +136,8 @@ typedef struct { * ticket is fixed. Flush_tier should be able to run with ongoing operations. */ static pthread_rwlock_t flush_lock; -static uint32_t nth; /* Number of threads. */ -static wt_timestamp_t *active_timestamps; /* Oldest timestamps still in use. */ +/* Lock for transactional ops that set or query a timestamp. */ +static pthread_rwlock_t ts_lock; static void handler(int) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void usage(void) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); @@ -160,31 +160,35 @@ usage(void) static WT_THREAD_RET thread_ts_run(void *arg) { - WT_CONNECTION *conn; + WT_DECL_RET; WT_SESSION *session; THREAD_DATA *td; - wt_timestamp_t last_ts, ts; - char tscfg[64]; + char tscfg[64], ts_string[WT_TS_HEX_STRING_SIZE]; td = (THREAD_DATA *)arg; - conn = td->conn; - testutil_check(conn->open_session(conn, NULL, NULL, &session)); - /* Update the oldest/stable timestamps every 1 millisecond. */ - for (last_ts = 0;; __wt_sleep(0, 1000)) { - /* Get the last committed timestamp periodically in order to update the oldest timestamp. */ - ts = maximum_stable_ts(active_timestamps, nth); - if (ts == last_ts) + testutil_check(td->conn->open_session(td->conn, NULL, NULL, &session)); + /* Update the oldest timestamp every 1 millisecond. */ + for (;; __wt_sleep(0, 1000)) { + /* + * We get the last committed timestamp periodically in order to update the oldest timestamp, + * that requires locking out transactional ops that set or query a timestamp. If there is no + * work to do, all-durable will be 0 and we just wait. + */ + testutil_check(pthread_rwlock_wrlock(&ts_lock)); + ret = td->conn->query_timestamp(td->conn, ts_string, "get=all_durable"); + testutil_check(pthread_rwlock_unlock(&ts_lock)); + testutil_assert(ret == 0); + if (testutil_timestamp_parse(ts_string) == 0) continue; - last_ts = ts; /* * Set both the oldest and stable timestamp so that we don't need to maintain read * availability at older timestamps. */ testutil_check(__wt_snprintf( - tscfg, sizeof(tscfg), "oldest_timestamp=%" PRIx64 ",stable_timestamp=%" PRIx64, ts, ts)); - testutil_check(conn->set_timestamp(conn, tscfg)); + tscfg, sizeof(tscfg), "oldest_timestamp=%s,stable_timestamp=%s", ts_string, ts_string)); + testutil_check(td->conn->set_timestamp(td->conn, tscfg)); } /* NOTREACHED */ } @@ -343,13 +347,15 @@ thread_run(void *arg) testutil_check(session->begin_transaction(session, NULL)); if (use_ts) { - active_ts = __wt_atomic_fetch_addv64(&global_ts, 2); + testutil_check(pthread_rwlock_rdlock(&ts_lock)); + active_ts = __wt_atomic_addv64(&global_ts, 2); testutil_check( __wt_snprintf(tscfg, sizeof(tscfg), "commit_timestamp=%" PRIx64, active_ts)); /* * Set the transaction's timestamp now before performing the operation. */ testutil_check(session->timestamp_transaction(session, tscfg)); + testutil_check(pthread_rwlock_unlock(&ts_lock)); } cur_coll->set_key(cur_coll, kname); @@ -416,15 +422,11 @@ rollback: locked = false; } } - - /* We're done with the timestamps, allow oldest and stable to move forward. */ - if (use_ts) - WT_PUBLISH(active_timestamps[td->info], active_ts); } /* NOTREACHED */ } -static void run_workload(const char *) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); +static void run_workload(uint32_t, const char *) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); /* * run_workload -- @@ -432,7 +434,7 @@ static void run_workload(const char *) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); * until it is killed by the parent. */ static void -run_workload(const char *build_dir) +run_workload(uint32_t nth, const char *build_dir) { WT_CONNECTION *conn; WT_SESSION *session; @@ -443,7 +445,6 @@ run_workload(const char *build_dir) thr = dcalloc(nth + NUM_INT_THREADS, sizeof(*thr)); td = dcalloc(nth + NUM_INT_THREADS, sizeof(THREAD_DATA)); - active_timestamps = dcalloc(nth, sizeof(wt_timestamp_t)); /* * Size the cache appropriately for the number of threads. Each thread adds keys sequentially to @@ -659,7 +660,7 @@ main(int argc, char *argv[]) pid_t pid; uint64_t absent_coll, absent_local, absent_oplog, absent_shadow, count, key, last_key; uint64_t commit_fp, durable_fp, stable_val; - uint32_t i, timeout; + uint32_t i, nth, timeout; int ch, status, ret; const char *working_dir; char buf[512], bucket_dir[512], build_dir[512], fname[512], kname[64]; @@ -727,6 +728,7 @@ main(int argc, char *argv[]) testutil_build_dir(opts, build_dir, 512); testutil_check(pthread_rwlock_init(&flush_lock, NULL)); + testutil_check(pthread_rwlock_init(&ts_lock, NULL)); testutil_work_dir_from_path(home, sizeof(home), working_dir); /* @@ -769,7 +771,7 @@ main(int argc, char *argv[]) testutil_assert_errno((pid = fork()) >= 0); if (pid == 0) { /* child */ - run_workload(build_dir); + run_workload(nth, build_dir); /* NOTREACHED */ } @@ -1008,6 +1010,7 @@ main(int argc, char *argv[]) fatal = true; } testutil_check(pthread_rwlock_destroy(&flush_lock)); + testutil_check(pthread_rwlock_destroy(&ts_lock)); if (fatal) return (EXIT_FAILURE); printf("%" PRIu64 " records verified\n", count); diff --git a/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c b/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c index a20b1d23d81..7ba89f2d72a 100644 --- a/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c +++ b/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c @@ -80,7 +80,7 @@ static const char *const uri_shadow = "shadow"; static const char *const ckpt_file = "checkpoint_done"; static bool columns, compat, inmem, stress, use_ts; -static uint64_t global_ts = 1; +static volatile uint64_t global_ts = 1; /* * The configuration sets the eviction update and dirty targets at 20% so that on average, each @@ -126,8 +126,8 @@ typedef struct { uint32_t info; } THREAD_DATA; -static uint32_t nth; /* Number of threads. */ -static wt_timestamp_t *active_timestamps; /* Oldest timestamps still in use. */ +/* Lock for transactional ops that set or query a timestamp. */ +static pthread_rwlock_t ts_lock; static void handler(int) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void usage(void) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); @@ -150,38 +150,63 @@ usage(void) static WT_THREAD_RET thread_ts_run(void *arg) { - WT_CONNECTION *conn; + WT_DECL_RET; WT_RAND_STATE rnd; WT_SESSION *session; THREAD_DATA *td; - wt_timestamp_t last_ts, ts; + wt_timestamp_t all_dur_ts, prev_all_dur_ts; uint32_t rand_op; int dbg; - char tscfg[64]; + char tscfg[64], ts_string[WT_TS_HEX_STRING_SIZE]; + bool first; - td = (THREAD_DATA *)arg; - conn = td->conn; + prev_all_dur_ts = WT_TS_NONE; - testutil_check(conn->open_session(conn, NULL, NULL, &session)); - __wt_random_init_seed((WT_SESSION_IMPL *)session, &rnd); + td = (THREAD_DATA *)arg; + __wt_random_init(&rnd); - /* Update the oldest/stable timestamps every 1 millisecond. */ - for (last_ts = 0;; __wt_sleep(0, 1000)) { - /* Get the last committed timestamp periodically in order to update the oldest timestamp. */ - ts = maximum_stable_ts(active_timestamps, nth); - if (ts == last_ts) + testutil_check(td->conn->open_session(td->conn, NULL, NULL, &session)); + first = true; + /* Update the oldest timestamp every 1 millisecond. */ + for (;; __wt_sleep(0, 1000)) { + /* + * We get the last committed timestamp periodically in order to update the oldest timestamp, + * that requires locking out transactional ops that set or query a timestamp. If there is no + * work to do, all-durable will be 0 and we just wait. + */ + testutil_check(pthread_rwlock_wrlock(&ts_lock)); + ret = td->conn->query_timestamp(td->conn, ts_string, "get=all_durable"); + testutil_check(pthread_rwlock_unlock(&ts_lock)); + testutil_assert(ret == 0); + /* + * All durable can intermittently move backwards, we do not want to set stable and the + * oldest timestamps backwards. + */ + all_dur_ts = testutil_timestamp_parse(ts_string); + if (all_dur_ts == 0 || all_dur_ts < prev_all_dur_ts) continue; - last_ts = ts; + prev_all_dur_ts = all_dur_ts; - /* Let the oldest timestamp lag 25% of the time. */ rand_op = __wt_random(&rnd) % 4; - if (rand_op == 1) - testutil_check(__wt_snprintf(tscfg, sizeof(tscfg), "stable_timestamp=%" PRIx64, ts)); - else - testutil_check(__wt_snprintf(tscfg, sizeof(tscfg), - "oldest_timestamp=%" PRIx64 ",stable_timestamp=%" PRIx64, ts, ts)); - testutil_check(conn->set_timestamp(conn, tscfg)); - + /* + * Periodically let the oldest timestamp lag. Other times set the stable and oldest + * timestamps as separate API calls. The rest of the time set them both as one call. + */ + if (rand_op == 0) { + testutil_check(__wt_snprintf(tscfg, sizeof(tscfg), "stable_timestamp=%s", ts_string)); + testutil_check(td->conn->set_timestamp(td->conn, tscfg)); + testutil_check(__wt_snprintf(tscfg, sizeof(tscfg), "oldest_timestamp=%s", ts_string)); + testutil_check(td->conn->set_timestamp(td->conn, tscfg)); + } else { + if (!first && rand_op == 1) + testutil_check( + __wt_snprintf(tscfg, sizeof(tscfg), "stable_timestamp=%s", ts_string)); + else + testutil_check(__wt_snprintf(tscfg, sizeof(tscfg), + "oldest_timestamp=%s,stable_timestamp=%s", ts_string, ts_string)); + testutil_check(td->conn->set_timestamp(td->conn, tscfg)); + } + first = false; /* * Set and reset the checkpoint retention setting on a regular basis. We want to test racing * with the internal log removal thread while we're here. @@ -193,7 +218,7 @@ thread_ts_run(void *arg) else testutil_check( __wt_snprintf(tscfg, sizeof(tscfg), "debug_mode=(checkpoint_retention=5)")); - testutil_check(conn->reconfigure(conn, tscfg)); + testutil_check(td->conn->reconfigure(td->conn, tscfg)); } /* NOTREACHED */ } @@ -342,8 +367,8 @@ thread_run(void *arg) testutil_check(prepared_session->begin_transaction(prepared_session, NULL)); if (use_ts) { - /* Allocate two timestamps. */ - active_ts = __wt_atomic_fetch_addv64(&global_ts, 2); + testutil_check(pthread_rwlock_rdlock(&ts_lock)); + active_ts = __wt_atomic_addv64(&global_ts, 2); testutil_check( __wt_snprintf(tscfg, sizeof(tscfg), "commit_timestamp=%" PRIx64, active_ts)); /* @@ -352,6 +377,7 @@ thread_run(void *arg) * collection session in that case would continue to use this timestamp. */ testutil_check(session->timestamp_transaction(session, tscfg)); + testutil_check(pthread_rwlock_unlock(&ts_lock)); } if (columns) { @@ -449,15 +475,11 @@ rollback: if (use_prep) testutil_check(prepared_session->rollback_transaction(prepared_session, NULL)); } - - /* We're done with the timestamps, allow oldest and stable to move forward. */ - if (use_ts) - WT_PUBLISH(active_timestamps[td->info], active_ts); } /* NOTREACHED */ } -static void run_workload(void) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); +static void run_workload(uint32_t) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); /* * run_workload -- @@ -465,7 +487,7 @@ static void run_workload(void) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); * until it is killed by the parent. */ static void -run_workload(void) +run_workload(uint32_t nth) { WT_CONNECTION *conn; WT_SESSION *session; @@ -477,7 +499,6 @@ run_workload(void) thr = dcalloc(nth + 2, sizeof(*thr)); td = dcalloc(nth + 2, sizeof(THREAD_DATA)); - active_timestamps = dcalloc(nth, sizeof(wt_timestamp_t)); /* * Size the cache appropriately for the number of threads. Each thread adds keys sequentially to @@ -536,7 +557,9 @@ run_workload(void) */ testutil_check(session->close(session, NULL)); - /* The checkpoint, timestamp and worker threads are added at the end. */ + /* + * The checkpoint thread and the timestamp threads are added at the end. + */ ckpt_id = nth; td[ckpt_id].conn = conn; td[ckpt_id].info = nth; @@ -634,7 +657,7 @@ main(int argc, char *argv[]) pid_t pid; uint64_t absent_coll, absent_local, absent_oplog, absent_shadow, count, key, last_key; uint64_t commit_fp, durable_fp, stable_val; - uint32_t i, timeout; + uint32_t i, nth, timeout; int ch, status, ret; const char *working_dir; char buf[512], fname[64], kname[64], statname[1024]; @@ -703,6 +726,7 @@ main(int argc, char *argv[]) usage(); testutil_work_dir_from_path(home, sizeof(home), working_dir); + testutil_check(pthread_rwlock_init(&ts_lock, NULL)); /* * If the user wants to verify they need to tell us how many threads there were so we can find @@ -746,7 +770,7 @@ main(int argc, char *argv[]) testutil_assert_errno((pid = fork()) >= 0); if (pid == 0) { /* child */ - run_workload(); + run_workload(nth); /* NOTREACHED */ } @@ -991,6 +1015,7 @@ main(int argc, char *argv[]) printf("OPLOG: %" PRIu64 " record(s) absent from %" PRIu64 "\n", absent_oplog, count); fatal = true; } + testutil_check(pthread_rwlock_destroy(&ts_lock)); if (fatal) return (EXIT_FAILURE); printf("%" PRIu64 " records verified\n", count); diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp28.py b/src/third_party/wiredtiger/test/suite/test_timestamp28.py index 74086a1b8bd..259499d7182 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp28.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp28.py @@ -31,54 +31,29 @@ import wiredtiger, wttest from wtdataset import SimpleDataSet -from wtscenario import make_scenarios # Timestamps: smoke test that commit is tested at both commit and set time. class test_timestamp28(wttest.WiredTigerTestCase): - timestamps = [ - ('stable', dict(timestamp='stable_timestamp')), - ('oldest', dict(timestamp='oldest_timestamp')), - ] - error_logs = { - 'stable_timestamp': '/must be after/', - 'oldest_timestamp': '/is less than/', - } - scenarios = make_scenarios(timestamps) - def test_timestamp28(self): - uri = 'table:timestamp28' ds = SimpleDataSet(self, uri, 50, key_format='i', value_format='S') ds.populate() c = self.session.open_cursor(uri) - self.conn.set_timestamp(self.timestamp + '=' + self.timestamp_str(30)) + self.conn.set_timestamp('stable_timestamp=' + self.timestamp_str(30)) self.session.begin_transaction() c[5] = 'xxx' - self.assertRaisesWithMessage(wiredtiger.WiredTigerError, lambda: self.session.commit_transaction( - 'commit_timestamp=' + self.timestamp_str(20)), self.error_logs[self.timestamp]) + 'commit_timestamp=' + self.timestamp_str(20)), '/must be after/') - self.conn.set_timestamp(self.timestamp + '=' + self.timestamp_str(40)) + self.conn.set_timestamp('stable_timestamp=' + self.timestamp_str(40)) self.session.begin_transaction() c[5] = 'xxx' self.session.timestamp_transaction('commit_timestamp=' + self.timestamp_str(50)) - self.conn.set_timestamp(self.timestamp + '=' + self.timestamp_str(60)) - self.assertRaisesWithMessage(wiredtiger.WiredTigerError, - lambda: self.session.commit_transaction(), self.error_logs[self.timestamp]) - - # Confirm the earliest commit time is tested. - self.session.begin_transaction() - c[5] = 'xxx' - self.session.timestamp_transaction('commit_timestamp=' + self.timestamp_str(70)) - c[6] = 'xxx' - self.session.timestamp_transaction('commit_timestamp=' + self.timestamp_str(71)) - c[7] = 'xxx' - self.conn.set_timestamp(self.timestamp + "=" + self.timestamp_str(75)) + self.conn.set_timestamp('stable_timestamp=' + self.timestamp_str(60)) self.assertRaisesWithMessage(wiredtiger.WiredTigerError, - lambda: self.session.commit_transaction( - 'commit_timestamp=' + self.timestamp_str(80)), self.error_logs[self.timestamp]) + lambda: self.session.commit_transaction(), '/must be after/') if __name__ == '__main__': wttest.run() diff --git a/src/third_party/wiredtiger/test/utility/test_util.h b/src/third_party/wiredtiger/test/utility/test_util.h index 1ae875865ce..7c45587358a 100644 --- a/src/third_party/wiredtiger/test/utility/test_util.h +++ b/src/third_party/wiredtiger/test/utility/test_util.h @@ -310,28 +310,6 @@ testutil_timestamp_parse(const char *str) return (ts); } -/* - * maximum_stable_ts -- - * Return the largest usable stable timestamp from a list of n committed timestamps. - */ -static inline wt_timestamp_t -maximum_stable_ts(wt_timestamp_t *commit_timestamps, uint32_t n) -{ - wt_timestamp_t commit_ts, ts; - uint32_t i; - - for (ts = WT_TS_MAX, i = 0; i < n; i++) { - commit_ts = commit_timestamps[i]; - if (commit_ts == WT_TS_NONE) - return (WT_TS_NONE); - if (commit_ts < ts) - ts = commit_ts; - } - - /* Return one less than the earliest in-use timestamp. */ - return (ts == WT_TS_MAX ? WT_TS_NONE : ts - 1); -} - /* Allow tests to add their own death handling. */ extern void (*custom_die)(void); |