summaryrefslogtreecommitdiff
path: root/src/third_party
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2021-08-16 14:53:13 +1000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-08-16 05:21:34 +0000
commit5a20195efb81fa18645498eac5a0865372b8a663 (patch)
treee99c759b8176a49418f003e327a916bd401a2b91 /src/third_party
parentbf1abfe3e0d0eada19512d69dfe8e9e9183b946c (diff)
downloadmongo-5a20195efb81fa18645498eac5a0865372b8a663.tar.gz
Import wiredtiger: 8099896388aa3476a53d36698018fc69e4240ab5 from branch mongodb-master
ref: 8c0e76f74a..8099896388 for: 5.1.0 WT-7945 Move rollback handling to the operation layer in the cppsuite.
Diffstat (limited to 'src/third_party')
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/test/cppsuite/test_harness/workload/database_operation.cxx66
-rw-r--r--src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.cxx87
-rw-r--r--src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.h36
-rw-r--r--src/third_party/wiredtiger/test/cppsuite/tests/hs_cleanup.cxx31
5 files changed, 126 insertions, 96 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index 1b85c3af1dd..e48dcc7aa78 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": "8c0e76f74ab9d29709548b2c3c3c96583cd8af59"
+ "commit": "8099896388aa3476a53d36698018fc69e4240ab5"
}
diff --git a/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/database_operation.cxx b/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/database_operation.cxx
index e18125446fe..ebd73acf286 100644
--- a/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/database_operation.cxx
+++ b/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/database_operation.cxx
@@ -52,8 +52,9 @@ populate_worker(thread_context *tc)
for (uint64_t i = 0; i < tc->key_count; ++i) {
/* Start a txn. */
tc->transaction.begin();
- if (!tc->insert(cursor, coll.id, i)) {
- /* We failed to insert, and our transaction was rolled back retry. */
+ if (tc->insert(cursor, coll.id, i)) {
+ /* We failed to insert, rollback our transaction and retry. */
+ tc->transaction.rollback();
--i;
continue;
}
@@ -162,24 +163,31 @@ database_operation::insert_operation(thread_context *tc)
auto &cc = ccv[counter];
while (tc->transaction.active() && tc->running()) {
/* Insert a key value pair. */
- if (!tc->insert(cc.cursor, cc.coll.id, start_key + added_count)) {
- committed = false;
- break;
+ bool rollback_required = tc->insert(cc.cursor, cc.coll.id, start_key + added_count);
+ if (!rollback_required) {
+ added_count++;
+ if (tc->transaction.can_commit()) {
+ rollback_required = tc->transaction.commit();
+ if (!rollback_required)
+ /*
+ * We need to inform the database model that we've added these keys as some
+ * other thread may rely on the key_count data. Only do so if we
+ * successfully committed.
+ */
+ cc.coll.increase_key_count(added_count);
+ }
}
- added_count++;
- tc->transaction.try_commit();
+
+ if (rollback_required) {
+ added_count = 0;
+ tc->transaction.rollback();
+ }
+
/* Sleep the duration defined by the op_rate. */
tc->sleep();
}
/* Reset our cursor to avoid pinning content. */
testutil_check(cc.cursor->reset(cc.cursor.get()));
-
- /*
- * We need to inform the database model that we've added these keys as some other thread may
- * rely on the key_count data. Only do so if we successfully committed.
- */
- if (committed)
- cc.coll.increase_key_count(added_count);
counter++;
if (counter == collections_per_thread)
counter = 0;
@@ -208,9 +216,17 @@ database_operation::read_operation(thread_context *tc)
tc->transaction.begin();
while (tc->transaction.active() && tc->running()) {
- if (tc->next(cursor) == WT_ROLLBACK)
- /* We got an error, our transaction has been rolled back. */
- break;
+ auto ret = cursor->next(cursor.get());
+ if (ret != 0) {
+ if (ret == WT_NOTFOUND) {
+ cursor->reset(cursor.get());
+ } else if (ret == WT_ROLLBACK) {
+ tc->transaction.rollback();
+ tc->sleep();
+ continue;
+ } else
+ testutil_die(ret, "Unexpected error returned from cursor->next()");
+ }
tc->transaction.add_op();
tc->transaction.try_rollback();
tc->sleep();
@@ -263,21 +279,21 @@ database_operation::update_operation(thread_context *tc)
/* Choose a random key to update. */
uint64_t key_id =
random_generator::instance().generate_integer<uint64_t>(0, coll.get_key_count() - 1);
- bool successful_update = tc->update(cursor, coll.id, tc->key_to_string(key_id));
+ bool rollback_required = tc->update(cursor, coll.id, tc->key_to_string(key_id));
/* Reset our cursor to avoid pinning content. */
testutil_check(cursor->reset(cursor.get()));
- /* We received a rollback in update. */
- if (!successful_update)
- continue;
-
/* Commit the current transaction if we're able to. */
- tc->transaction.try_commit();
+ if (!rollback_required && tc->transaction.can_commit())
+ rollback_required = tc->transaction.commit();
+
+ if (rollback_required)
+ tc->transaction.rollback();
}
- /* Make sure the last operation is committed now the work is finished. */
+ /* Make sure the last operation is rolled back now the work is finished. */
if (tc->transaction.active())
- tc->transaction.commit();
+ tc->transaction.rollback();
}
} // namespace test_harness
diff --git a/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.cxx b/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.cxx
index 321cc45b61b..aadf992133e 100644
--- a/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.cxx
+++ b/src/third_party/wiredtiger/test/cppsuite/test_harness/workload/thread_context.cxx
@@ -71,6 +71,7 @@ transaction_context::begin(const std::string &config)
random_generator::instance().generate_integer<int64_t>(_min_op_count, _max_op_count);
_op_count = 0;
_in_txn = true;
+ _needs_rollback = false;
}
void
@@ -80,21 +81,22 @@ transaction_context::try_begin(const std::string &config)
begin(config);
}
-void
+/* It's possible to receive rollback in commit which is handled internally. */
+bool
transaction_context::commit(const std::string &config)
{
+ WT_DECL_RET;
testutil_assert(_in_txn);
- testutil_check(
- _session->commit_transaction(_session, config.empty() ? nullptr : config.c_str()));
- _op_count = 0;
- _in_txn = false;
-}
-
-void
-transaction_context::try_commit(const std::string &config)
-{
- if (can_commit_rollback())
- commit(config);
+ if ((ret = _session->commit_transaction(_session, config.empty() ? nullptr : config.c_str())) !=
+ 0) {
+ logger::log_msg(LOG_WARN,
+ "Failed to commit transaction in commit, received error code: " + std::to_string(ret));
+ _needs_rollback = true;
+ } else {
+ _op_count = 0;
+ _in_txn = false;
+ }
+ return (_needs_rollback);
}
void
@@ -103,6 +105,7 @@ transaction_context::rollback(const std::string &config)
testutil_assert(_in_txn);
testutil_check(
_session->rollback_transaction(_session, config.empty() ? nullptr : config.c_str()));
+ _needs_rollback = false;
_op_count = 0;
_in_txn = false;
}
@@ -110,7 +113,7 @@ transaction_context::rollback(const std::string &config)
void
transaction_context::try_rollback(const std::string &config)
{
- if (can_commit_rollback())
+ if (can_rollback())
rollback(config);
}
@@ -124,8 +127,20 @@ transaction_context::set_commit_timestamp(wt_timestamp_t ts)
testutil_check(_session->timestamp_transaction(_session, config.c_str()));
}
+void
+transaction_context::set_needs_rollback(bool rollback)
+{
+ _needs_rollback = rollback;
+}
+
bool
-transaction_context::can_commit_rollback()
+transaction_context::can_commit()
+{
+ return (!_needs_rollback && can_rollback());
+}
+
+bool
+transaction_context::can_rollback()
{
return (_in_txn && _op_count >= _target_op_count);
}
@@ -184,8 +199,8 @@ thread_context::update(scoped_cursor &cursor, uint64_t collection_id, const std:
ret = cursor->update(cursor.get());
if (ret != 0) {
if (ret == WT_ROLLBACK) {
- transaction.rollback();
- return (false);
+ transaction.set_needs_rollback(true);
+ return (true);
} else
testutil_die(ret, "unhandled error while trying to update a key");
}
@@ -193,14 +208,14 @@ thread_context::update(scoped_cursor &cursor, uint64_t collection_id, const std:
tracking_operation::INSERT, collection_id, key.c_str(), value.c_str(), ts, op_track_cursor);
if (ret != 0) {
if (ret == WT_ROLLBACK) {
- transaction.rollback();
- return (false);
+ transaction.set_needs_rollback(true);
+ return (true);
} else
testutil_die(
ret, "unhandled error while trying to save an update to the tracking table");
}
transaction.add_op();
- return (true);
+ return (false);
}
bool
@@ -226,8 +241,8 @@ thread_context::insert(scoped_cursor &cursor, uint64_t collection_id, uint64_t k
ret = cursor->insert(cursor.get());
if (ret != 0) {
if (ret == WT_ROLLBACK) {
- transaction.rollback();
- return (false);
+ transaction.set_needs_rollback(true);
+ return (true);
} else
testutil_die(ret, "unhandled error while trying to insert a key");
}
@@ -235,38 +250,14 @@ thread_context::insert(scoped_cursor &cursor, uint64_t collection_id, uint64_t k
tracking_operation::INSERT, collection_id, key.c_str(), value.c_str(), ts, op_track_cursor);
if (ret != 0) {
if (ret == WT_ROLLBACK) {
- transaction.rollback();
- return (false);
+ transaction.set_needs_rollback(true);
+ return (true);
} else
testutil_die(
ret, "unhandled error while trying to save an insert to the tracking table");
}
transaction.add_op();
- return (true);
-}
-
-int
-thread_context::next(scoped_cursor &cursor)
-{
- WT_DECL_RET;
-
- ret = cursor->next(cursor.get());
-
- if (ret == WT_NOTFOUND) {
- testutil_check(cursor->reset(cursor.get()));
- return (ret);
- }
-
- if (ret == WT_ROLLBACK) {
- transaction.rollback();
- testutil_check(cursor->reset(cursor.get()));
- return (ret);
- }
-
- if (ret != 0)
- testutil_die(ret, "cursor->next() failed with an unexpected error.");
-
- return (0);
+ return (false);
}
void
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 5255740f59c..7bb6ac66cb6 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
@@ -71,17 +71,28 @@ class transaction_context {
void begin(const std::string &config = "");
/* Begin a transaction if we are not currently in one. */
void try_begin(const std::string &config = "");
- void commit(const std::string &config = "");
- /* Attempt to commit the transaction given the requirements are met. */
- void try_commit(const std::string &config = "");
+ /*
+ * Commit a transaction and return true if a rollback is required.
+ */
+ bool commit(const std::string &config = "");
+ /* Rollback a transaction, failure will abort the test. */
void rollback(const std::string &config = "");
/* Attempt to rollback the transaction given the requirements are met. */
void try_rollback(const std::string &config = "");
/* Set a commit timestamp. */
void set_commit_timestamp(wt_timestamp_t ts);
-
- private:
- bool can_commit_rollback();
+ /* Set that the transaction needs to be rolled back. */
+ void set_needs_rollback(bool rollback);
+ /*
+ * Returns true if a transaction can be committed as determined by the op count and the state of
+ * the transaction.
+ */
+ bool can_commit();
+ /*
+ * Returns true if a transaction can be rolled back as determined by the op count and the state
+ * of the transaction.
+ */
+ bool can_rollback();
private:
/*
@@ -99,6 +110,7 @@ class transaction_context {
int64_t _max_op_count = INT64_MAX;
int64_t _target_op_count = 0;
bool _in_txn = false;
+ bool _needs_rollback = false;
WT_SESSION *_session = nullptr;
timestamp_manager *_timestamp_manager = nullptr;
@@ -124,25 +136,17 @@ class thread_context {
/*
* Generic update function, takes a collection_id and key, will generate the value.
*
- * Returns true if it successfully updates the key, false if it receives rollback from the API.
+ * Returns true if a rollback is required.
*/
bool update(scoped_cursor &cursor, uint64_t collection_id, const std::string &key);
/*
* Generic insert function, takes a collection_id and key_id, will generate the value.
*
- * Returns true if it successfully inserts the key, false if it receives rollback from the API.
+ * Returns true if a rollback is required.
*/
bool insert(scoped_cursor &cursor, uint64_t collection_id, uint64_t key_id);
- /*
- * Generic next function.
- *
- * Handles rollback and not found internally, but will return the error code to the caller so
- * the caller can distinguish between them.
- */
- int next(scoped_cursor &cursor);
-
void sleep();
bool running() const;
diff --git a/src/third_party/wiredtiger/test/cppsuite/tests/hs_cleanup.cxx b/src/third_party/wiredtiger/test/cppsuite/tests/hs_cleanup.cxx
index 4dd073cc115..03de6947a86 100644
--- a/src/third_party/wiredtiger/test/cppsuite/tests/hs_cleanup.cxx
+++ b/src/third_party/wiredtiger/test/cppsuite/tests/hs_cleanup.cxx
@@ -62,8 +62,24 @@ class hs_cleanup : public test {
while (tc->running()) {
tc->sleep();
- if (tc->next(cursor) != 0)
- continue;
+ auto ret = cursor->next(cursor.get());
+ if (ret != 0) {
+ if (ret == WT_NOTFOUND) {
+ cursor->reset(cursor.get());
+ continue;
+ }
+ if (ret == WT_ROLLBACK) {
+ /*
+ * As a result of the logic in this test its possible that the previous next
+ * call can happen outside the context of a transaction. Assert that we are in
+ * one if we got a rollback.
+ */
+ testutil_check(tc->transaction.can_rollback());
+ tc->transaction.rollback();
+ continue;
+ }
+ testutil_die(ret, "Unexpected error returned from cursor->next()");
+ }
testutil_check(cursor->get_key(cursor.get(), &key_tmp));
@@ -75,14 +91,17 @@ class hs_cleanup : public test {
* API doesn't guarantee our buffer will still be valid once it is called, as such we
* copy the buffer and then pass it into the API.
*/
- if (!tc->update(cursor, coll.id, key_value_t(key_tmp)))
- continue;
+ bool rollback_required = tc->update(cursor, coll.id, key_value_t(key_tmp));
/* Commit our transaction. */
- tc->transaction.try_commit();
+ if (!rollback_required && tc->transaction.can_commit())
+ rollback_required = tc->transaction.commit();
+
+ if (rollback_required)
+ tc->transaction.rollback();
}
/* Ensure our last transaction is resolved. */
if (tc->transaction.active())
- tc->transaction.commit();
+ tc->transaction.rollback();
}
};