diff options
author | Luke Chen <luke.chen@mongodb.com> | 2021-09-10 15:42:59 +1000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-09-10 06:07:15 +0000 |
commit | 85f24e45b3b6ee2c5482e64c46fc267e46c02aa5 (patch) | |
tree | 4036cb20fe4ff4d09d1d4f3aad311016e4dbb90c /src/third_party | |
parent | d01d3b9f46afc6ea9a8875a0bb261acc5b9fa776 (diff) | |
download | mongo-85f24e45b3b6ee2c5482e64c46fc267e46c02aa5.tar.gz |
Import wiredtiger: 186281ffe0f77518738647c0a0aae5e0d122ad33 from branch mongodb-master
ref: 82de987481..186281ffe0
for: 5.1.0
WT-8001 Fix Inconsistent API behaviour when setting global oldest and stable timestamps
Diffstat (limited to 'src/third_party')
6 files changed, 72 insertions, 27 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index fd733bf791a..1a97e0ee9c4 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": "82de98748157acabd197e74c9a8ce203a07e9f74" + "commit": "186281ffe0f77518738647c0a0aae5e0d122ad33" } diff --git a/src/third_party/wiredtiger/src/txn/txn_timestamp.c b/src/third_party/wiredtiger/src/txn/txn_timestamp.c index 9faa37d0c57..c138f23fe57 100644 --- a/src/third_party/wiredtiger/src/txn/txn_timestamp.c +++ b/src/third_party/wiredtiger/src/txn/txn_timestamp.c @@ -387,6 +387,13 @@ __wt_txn_global_set_timestamp(WT_SESSION_IMPL *session, const char *cfg[]) last_oldest_ts = txn_global->oldest_timestamp; last_stable_ts = txn_global->stable_timestamp; + /* It is a no-op to set the oldest or stable timestamps behind the global values. */ + if (has_oldest && txn_global->has_oldest_timestamp && oldest_ts <= last_oldest_ts) + has_oldest = false; + + if (has_stable && txn_global->has_stable_timestamp && stable_ts <= last_stable_ts) + has_stable = false; + /* * First do error checking on the timestamp values. The oldest timestamp must always be less * than or equal to the stable timestamp. If we're only setting one then compare against the @@ -434,12 +441,6 @@ __wt_txn_global_set_timestamp(WT_SESSION_IMPL *session, const char *cfg[]) __wt_readunlock(session, &txn_global->rwlock); /* Check if we are actually updating anything. */ - if (has_oldest && txn_global->has_oldest_timestamp && oldest_ts <= last_oldest_ts) - has_oldest = false; - - if (has_stable && txn_global->has_stable_timestamp && stable_ts <= last_stable_ts) - has_stable = false; - if (!has_durable && !has_oldest && !has_stable) return (0); 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 c9883800199..5f5c019d3ad 100644 --- a/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c +++ b/src/third_party/wiredtiger/test/csuite/timestamp_abort/main.c @@ -149,14 +149,11 @@ thread_ts_run(void *arg) WT_RAND_STATE rnd; WT_SESSION *session; THREAD_DATA *td; - wt_timestamp_t all_dur_ts, prev_all_dur_ts; uint32_t rand_op; int dbg; char tscfg[64], ts_string[WT_TS_HEX_STRING_SIZE]; bool first; - prev_all_dur_ts = WT_TS_NONE; - td = (THREAD_DATA *)arg; __wt_random_init(&rnd); @@ -172,15 +169,6 @@ thread_ts_run(void *arg) ret = td->conn->query_timestamp(td->conn, ts_string, "get=all_durable"); testutil_check(pthread_rwlock_unlock(&ts_lock)); testutil_assert(ret == 0 || ret == WT_NOTFOUND); - /* - * All durable can intermittently move backwards, we do not want to set stable and the - * oldest timestamps backwards - refer WT-8001. - */ - all_dur_ts = strtoul(ts_string, NULL, 16); - if (!first && all_dur_ts < prev_all_dur_ts) { - __wt_sleep(0, 1000); - continue; - } if (ret == 0) { rand_op = __wt_random(&rnd) % 4; /* @@ -204,7 +192,6 @@ thread_ts_run(void *arg) testutil_check(td->conn->set_timestamp(td->conn, tscfg)); } first = false; - prev_all_dur_ts = all_dur_ts; /* * Set and reset the checkpoint retention setting on a regular basis. We want to test * racing with the internal archive thread while we're here. @@ -446,7 +433,7 @@ thread_run(void *arg) durable_ahead_commit ? active_ts + 4 : active_ts)); /* Ensure the global timestamp is not behind the all durable timestamp. */ if (durable_ahead_commit) - __wt_atomic_addv64(&global_ts, 3); + __wt_atomic_addv64(&global_ts, 4); } else testutil_check( __wt_snprintf(tscfg, sizeof(tscfg), "commit_timestamp=%" PRIx64, active_ts)); diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp02.py b/src/third_party/wiredtiger/test/suite/test_timestamp02.py index c0f45f82dc5..4bc2c7d55ae 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp02.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp02.py @@ -130,6 +130,61 @@ class test_timestamp02(wttest.WiredTigerTestCase, suite_subprocess): self.check(self.session, 'read_timestamp=' + self.timestamp_str(t + 200), dict((k, 2) for k in orig_keys[i+1:])) + # Perform validation on setting the oldest and the stable timestamps: + # - It is a success, but a no-op, to set them behind their existing values. + # - Oldest timestamp can't be more than the stable. It is reported as an error if an attempt + # is made to set that way. + # - If both the oldest and the stable are provided in the same call, the test to check if + # they are being moved backwards is done first. The value that is being set backwards is + # silently dropped, as if not provided at all. This is followed by the test on the oldest + # not being being set ahead of the stable. + + # Confirm that the oldest and the stable timestamps are as expected + self.assertTimestampsEqual(self.conn.query_timestamp("get=oldest"), self.timestamp_str(200)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=stable"), self.timestamp_str(300)) + + # Any attempt to set the oldest or stable to a value older than the current is silently + # ignored. + self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(1)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=oldest"), self.timestamp_str(200)) + self.conn.set_timestamp('stable_timestamp=' + self.timestamp_str(1)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=stable"), self.timestamp_str(300)) + + # An error to set oldest ahead of stable. + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(301)), + '/oldest timestamp \(0, 301\) must not be later than stable timestamp \(0, 300\)/') + self.assertTimestampsEqual(self.conn.query_timestamp("get=oldest"), self.timestamp_str(200)) + + self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(201)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=oldest"), self.timestamp_str(201)) + self.conn.set_timestamp('stable_timestamp=' + self.timestamp_str(301)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=stable"), self.timestamp_str(301)) + + # If both the oldest and the stable are provided in the same call, the behavior should be + # consistent with providing them individually. + self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(1) + + ',stable_timestamp=' + self.timestamp_str(1)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=oldest"), self.timestamp_str(201)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=stable"), self.timestamp_str(301)) + + self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(202) + + ',stable_timestamp=' + self.timestamp_str(1)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=oldest"), self.timestamp_str(202)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=stable"), self.timestamp_str(301)) + + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(302) + + ',stable_timestamp=' + self.timestamp_str(1)), + '/oldest timestamp \(0, 302\) must not be later than stable timestamp \(0, 301\)/') + self.assertTimestampsEqual(self.conn.query_timestamp("get=oldest"), self.timestamp_str(202)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=stable"), self.timestamp_str(301)) + + self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(302) + + ',stable_timestamp=' + self.timestamp_str(302)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=oldest"), self.timestamp_str(302)) + self.assertTimestampsEqual(self.conn.query_timestamp("get=stable"), self.timestamp_str(302)) + def test_read_your_writes(self): self.session.create(self.uri, 'key_format=i,value_format=i' + self.extra_config) diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp19.py b/src/third_party/wiredtiger/test/suite/test_timestamp19.py index e271c8f1145..17868e1b821 100644 --- a/src/third_party/wiredtiger/test/suite/test_timestamp19.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp19.py @@ -98,12 +98,6 @@ class test_timestamp19(wttest.WiredTigerTestCase): self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(10)) self.assertTimestampsEqual(self.conn.query_timestamp('get=oldest'), self.timestamp_str(40)) - # Trying to set an earlier stable timestamp is an error. - self.assertRaisesWithMessage(wiredtiger.WiredTigerError, - lambda: self.conn.set_timestamp('stable_timestamp=' + self.timestamp_str(10)), - '/oldest timestamp \(0, 40\) must not be later than stable timestamp \(0, 10\)/') - self.assertTimestampsEqual(self.conn.query_timestamp('get=stable'), self.timestamp_str(40)) - # Move the oldest and stable timestamps to 70. self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(70) + ', stable_timestamp=' + self.timestamp_str(70)) diff --git a/src/third_party/wiredtiger/test/suite/test_timestamp22.py b/src/third_party/wiredtiger/test/suite/test_timestamp22.py index b26b844dd32..55d6329af2f 100755 --- a/src/third_party/wiredtiger/test/suite/test_timestamp22.py +++ b/src/third_party/wiredtiger/test/suite/test_timestamp22.py @@ -328,6 +328,14 @@ class test_timestamp22(wttest.WiredTigerTestCase): return expected expected = self.SUCCESS + + # It is a no-op to provide oldest or stable behind the global values. If provided ahead, we + # will treat the values as if not provided at all. + if oldest <= self.oldest_ts: + oldest = -1 + if stable <= self.stable_ts: + stable = -1 + if oldest >= 0 and stable < 0: expected = expected_newer(expected, self.stable_ts, oldest, self.oldest_ts) expected = expected_newer(expected, stable, oldest, self.oldest_ts) |