summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChenhao Qu <chenhao.qu@mongodb.com>2022-01-05 17:18:54 +1100
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-01-05 06:46:29 +0000
commit22249d4747a17977a20d229f8f41185d9b99518d (patch)
treeff48292fff7a8ac4d27d5de395f2b7d1e095fbaa
parent335a69adebc6c3813701487c6b7ed4f1af4a5756 (diff)
downloadmongo-22249d4747a17977a20d229f8f41185d9b99518d.tar.gz
Import wiredtiger: 44f59f255cd2894489339ffe9f3c853ba7e5117e from branch mongodb-master
ref: b4eabd7093..44f59f255c for: 5.3.0 WT-8290 Adding a new API to the session to return the rollback reason
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/lang/python/wiredtiger.i1
-rw-r--r--src/third_party/wiredtiger/src/include/txn.h8
-rw-r--r--src/third_party/wiredtiger/src/include/txn_inline.h2
-rw-r--r--src/third_party/wiredtiger/src/include/wiredtiger.in11
-rw-r--r--src/third_party/wiredtiger/src/session/session_api.c20
-rw-r--r--src/third_party/wiredtiger/src/txn/txn.c3
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn27.py89
8 files changed, 130 insertions, 6 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index d5f71b6e206..01f561a14e5 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": "b4eabd7093752f76dafb2cbee9f3ad03da56cbb5"
+ "commit": "44f59f255cd2894489339ffe9f3c853ba7e5117e"
}
diff --git a/src/third_party/wiredtiger/lang/python/wiredtiger.i b/src/third_party/wiredtiger/lang/python/wiredtiger.i
index c77a2effda4..3bcaa9997e5 100644
--- a/src/third_party/wiredtiger/lang/python/wiredtiger.i
+++ b/src/third_party/wiredtiger/lang/python/wiredtiger.i
@@ -594,6 +594,7 @@ COMPARE_NOTFOUND_OK(__wt_cursor::_search_near)
%exception __wt_connection::get_home;
%exception __wt_connection::is_new;
%exception __wt_connection::search_near;
+%exception __wt_session::get_rollback_reason;
%exception __wt_cursor::_set_key;
%exception __wt_cursor::_set_key_str;
%exception __wt_cursor::_set_value;
diff --git a/src/third_party/wiredtiger/src/include/txn.h b/src/third_party/wiredtiger/src/include/txn.h
index cb433664094..4b16ff51a4a 100644
--- a/src/third_party/wiredtiger/src/include/txn.h
+++ b/src/third_party/wiredtiger/src/include/txn.h
@@ -14,6 +14,14 @@
#define WT_TS_NONE 0 /* Beginning of time */
#define WT_TS_MAX UINT64_MAX /* End of time */
+/*
+ * A list of reasons for returning a rollback error from the API. These reasons can be queried via
+ * the session get rollback reason API call. Users of the API could have a dependency on the format
+ * of these messages so changing them must be done with care.
+ */
+#define WT_TXN_ROLLBACK_REASON_CACHE "oldest pinned transaction ID rolled back for eviction"
+#define WT_TXN_ROLLBACK_REASON_CONFLICT "conflict between concurrent operations"
+
/* AUTOMATIC FLAG VALUE GENERATION START 0 */
#define WT_TXN_LOG_CKPT_CLEANUP 0x01u
#define WT_TXN_LOG_CKPT_PREPARE 0x02u
diff --git a/src/third_party/wiredtiger/src/include/txn_inline.h b/src/third_party/wiredtiger/src/include/txn_inline.h
index ccfae2af21d..684ae459a70 100644
--- a/src/third_party/wiredtiger/src/include/txn_inline.h
+++ b/src/third_party/wiredtiger/src/include/txn_inline.h
@@ -1393,7 +1393,7 @@ __wt_txn_modify_check(
}
WT_STAT_CONN_DATA_INCR(session, txn_update_conflict);
- ret = __wt_txn_rollback_required(session, "conflict between concurrent operations");
+ ret = __wt_txn_rollback_required(session, WT_TXN_ROLLBACK_REASON_CONFLICT);
}
/*
diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in
index 45c0c7f0500..b9d33094ad6 100644
--- a/src/third_party/wiredtiger/src/include/wiredtiger.in
+++ b/src/third_party/wiredtiger/src/include/wiredtiger.in
@@ -1942,6 +1942,17 @@ struct __wt_session {
#ifndef DOXYGEN
/*!
+ * Optionally returns the reason for the most recent rollback error returned from the API.
+ *
+ * There is no guarantee a rollback reason will be set and thus the caller
+ * must check for a NULL pointer.
+ *
+ * @param session the session handle
+ * @returns an optional string indicating the reason for the rollback
+ */
+ const char * __F(get_rollback_reason)(WT_SESSION *session);
+
+ /*!
* Call into the library.
*
* This method is used for breakpoints and to set other configuration
diff --git a/src/third_party/wiredtiger/src/session/session_api.c b/src/third_party/wiredtiger/src/session/session_api.c
index 0406ce7d1ce..55d1619c1cc 100644
--- a/src/third_party/wiredtiger/src/session/session_api.c
+++ b/src/third_party/wiredtiger/src/session/session_api.c
@@ -1858,6 +1858,20 @@ err:
}
/*
+ * __session_get_rollback_reason --
+ * WT_SESSION->get_rollback_reason method.
+ */
+static const char *
+__session_get_rollback_reason(WT_SESSION *wt_session)
+{
+ WT_SESSION_IMPL *session;
+
+ session = (WT_SESSION_IMPL *)wt_session;
+
+ return (session->txn->rollback_reason);
+}
+
+/*
* __session_checkpoint --
* WT_SESSION->checkpoint method.
*/
@@ -1976,7 +1990,8 @@ __open_session(WT_CONNECTION_IMPL *conn, WT_EVENT_HANDLER *event_handler, const
__session_truncate, __session_upgrade, __session_verify, __session_begin_transaction,
__session_commit_transaction, __session_prepare_transaction, __session_reset_snapshot,
__session_rollback_transaction, __session_timestamp_transaction, __session_query_timestamp,
- __session_checkpoint, __session_transaction_pinned_range, __wt_session_breakpoint},
+ __session_checkpoint, __session_transaction_pinned_range, __session_get_rollback_reason,
+ __wt_session_breakpoint},
stds_readonly = {NULL, NULL, __session_close, __session_reconfigure, __session_flush_tier,
__wt_session_strerror, __session_open_cursor, __session_alter_readonly,
__session_create_readonly, __wt_session_compact_readonly, __session_drop_readonly,
@@ -1986,7 +2001,8 @@ __open_session(WT_CONNECTION_IMPL *conn, WT_EVENT_HANDLER *event_handler, const
__session_begin_transaction, __session_commit_transaction,
__session_prepare_transaction_readonly, __session_reset_snapshot,
__session_rollback_transaction, __session_timestamp_transaction, __session_query_timestamp,
- __session_checkpoint_readonly, __session_transaction_pinned_range, __wt_session_breakpoint};
+ __session_checkpoint_readonly, __session_transaction_pinned_range,
+ __session_get_rollback_reason, __wt_session_breakpoint};
WT_DECL_RET;
WT_SESSION_IMPL *session, *session_ret;
uint32_t i;
diff --git a/src/third_party/wiredtiger/src/txn/txn.c b/src/third_party/wiredtiger/src/txn/txn.c
index 934b607b64a..b348dad1dfb 100644
--- a/src/third_party/wiredtiger/src/txn/txn.c
+++ b/src/third_party/wiredtiger/src/txn/txn.c
@@ -2458,8 +2458,7 @@ __wt_txn_is_blocking(WT_SESSION_IMPL *session)
* Check if either the transaction's ID or its pinned ID is equal to the oldest transaction ID.
*/
return (txn_shared->id == global_oldest || txn_shared->pinned_id == global_oldest ?
- __wt_txn_rollback_required(
- session, "oldest pinned transaction ID rolled back for eviction") :
+ __wt_txn_rollback_required(session, WT_TXN_ROLLBACK_REASON_CACHE) :
0);
}
diff --git a/src/third_party/wiredtiger/test/suite/test_txn27.py b/src/third_party/wiredtiger/test/suite/test_txn27.py
new file mode 100644
index 00000000000..4e34bbf797d
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/test_txn27.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-present MongoDB, Inc.
+# Public Domain 2008-2014 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+import wiredtiger, wttest, time
+from wtdataset import SimpleDataSet
+
+# test_txn27.py
+# Test that the API returning a rollback error sets the reason for the rollback.
+class test_txn27(wttest.WiredTigerTestCase):
+ conn_config = 'cache_size=1MB'
+
+ def test_rollback_reason(self):
+ uri = "table:txn27"
+ # Create a very basic table.
+ ds = SimpleDataSet(self, uri, 10, key_format='S', value_format='S')
+ ds.populate()
+
+ # Update key 5 in the first session.
+ session1 = self.session
+ cursor1 = session1.open_cursor(uri)
+ session1.begin_transaction()
+ cursor1[ds.key(5)] = "aaa"
+
+ # Update the same key in the second session, expect a conflict error to be produced.
+ session2 = self.conn.open_session()
+ cursor2 = session2.open_cursor(uri)
+ session2.begin_transaction()
+ cursor2.set_key(ds.key(5))
+ cursor2.set_value("bbb")
+ msg1 = '/conflict between concurrent operations/'
+ self.assertRaisesException(wiredtiger.WiredTigerError, lambda: cursor2.update(), msg1)
+ self.assertEquals('/' + session2.get_rollback_reason() + '/', msg1)
+
+ # Rollback the transactions, check that session2's rollback error was cleared.
+ session2.rollback_transaction()
+ self.assertEquals(session2.get_rollback_reason(), None)
+ session1.rollback_transaction()
+
+ # Start a new transaction and insert a value far too large for cache.
+ session1.begin_transaction()
+ cursor1.set_key(ds.key(1))
+ cursor1.set_value("a"*1024*5000)
+ self.assertEqual(0, cursor1.update())
+
+ # Let WiredTiger's accounting catch up.
+ time.sleep(2)
+
+ # Attempt to insert another value with the same transaction. This will result in the
+ # application thread being pulled into eviction and getting rolled back.
+ cursor1.set_key(ds.key(2))
+ cursor1.set_value("b"*1024)
+
+ # This is the message that we expect to be raised when a thread is rolled back due to
+ # cache pressure.
+ msg2 = 'oldest pinned transaction ID rolled back for eviction'
+ # Expect stdout to give us the true reason for the rollback.
+ with self.expectedStdoutPattern(msg2):
+ # This reason is the default reason for WT_ROLLBACK errors so we need to catch it.
+ self.assertRaisesException(wiredtiger.WiredTigerError, lambda: cursor1.update(), msg1)
+ # Expect the rollback reason to give us the true reason for the rollback.
+ self.assertEquals(session1.get_rollback_reason(), msg2)
+
+if __name__ == '__main__':
+ wttest.run()