diff options
author | Luke Chen <luke.chen@mongodb.com> | 2022-01-11 12:07:34 +1100 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-01-11 01:44:40 +0000 |
commit | ef77ff3c82d94cbd99db06a463ea808655110f56 (patch) | |
tree | 352f85e198bfb902fe26701ba12e904c5d3d5958 | |
parent | eb546401b77e41540281bcbbf972f7b17cd18c9b (diff) | |
download | mongo-ef77ff3c82d94cbd99db06a463ea808655110f56.tar.gz |
Import wiredtiger: 44f59f255cd2894489339ffe9f3c853ba7e5117e from branch mongodb-5.2
ref: b4eabd7093..44f59f255c
for: 5.2.0-rc5
WT-8290 Adding a new API to the session to return the rollback reason
-rw-r--r-- | src/third_party/wiredtiger/import.data | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/lang/python/wiredtiger.i | 1 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/txn.h | 8 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/txn_inline.h | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/wiredtiger.in | 11 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/session/session_api.c | 20 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/txn/txn.c | 3 | ||||
-rw-r--r-- | src/third_party/wiredtiger/test/suite/test_txn27.py | 89 |
8 files changed, 130 insertions, 6 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index af0f846eea6..a77fea8d77d 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-5.2", - "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() |