summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2021-10-18 14:00:30 +1100
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-10-18 03:23:58 +0000
commit9c9b46ba750801fec3f98d323fc99c83a3a0700b (patch)
tree5c788e1f30f4a0357219968f9af9c1ce9e24b583 /src
parenta317d4dd62814f27cd09d1fa2b2e553d97a6d775 (diff)
downloadmongo-9c9b46ba750801fec3f98d323fc99c83a3a0700b.tar.gz
Import wiredtiger: 51a5c5ff5b0ceea341f70a386fff5a9f68d2edac from branch mongodb-5.1
ref: e930e8d0cd..51a5c5ff5b for: 5.1.0-rc1 WT-8226 fix largest_key failed to consider prepared update
Diffstat (limited to 'src')
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_std.c15
-rw-r--r--src/third_party/wiredtiger/src/docs/cursor-ops.dox6
-rw-r--r--src/third_party/wiredtiger/src/include/txn_inline.h21
-rw-r--r--src/third_party/wiredtiger/src/include/wiredtiger.in1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor17.py41
6 files changed, 56 insertions, 30 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index c338f0f81f0..abf371b6693 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.1",
- "commit": "e930e8d0cd4c3330783e711253eae2923b1e2e3f"
+ "commit": "51a5c5ff5b0ceea341f70a386fff5a9f68d2edac"
}
diff --git a/src/third_party/wiredtiger/src/cursor/cur_std.c b/src/third_party/wiredtiger/src/cursor/cur_std.c
index de5115845c7..1bf28de3f11 100644
--- a/src/third_party/wiredtiger/src/cursor/cur_std.c
+++ b/src/third_party/wiredtiger/src/cursor/cur_std.c
@@ -1124,23 +1124,24 @@ __wt_cursor_largest_key(WT_CURSOR *cursor)
WT_DECL_RET;
WT_SESSION_IMPL *session;
bool ignore_tombstone;
+ bool visible_all;
ignore_tombstone = F_ISSET(cursor, WT_CURSTD_IGNORE_TOMBSTONE);
+ visible_all = F_ISSET(cursor, WT_CURSTD_VISIBLE_ALL);
CURSOR_API_CALL(cursor, session, largest_key, NULL);
- if (F_ISSET(session->txn, WT_TXN_SHARED_TS_READ))
- WT_ERR_MSG(session, EINVAL, "largest key cannot be called with a read timestamp");
-
WT_ERR(__wt_scr_alloc(session, 0, &key));
/* Reset the cursor to give up the cursor position. */
WT_ERR(cursor->reset(cursor));
- /* Ignore deletion */
+ /* Ignore deletion. */
F_SET(cursor, WT_CURSTD_IGNORE_TOMBSTONE);
+ /* Ignore visibility. */
+ F_SET(cursor, WT_CURSTD_VISIBLE_ALL);
- /* Call cursor prev with read uncommitted isolation level. */
- WT_WITH_TXN_ISOLATION(session, WT_ISO_READ_UNCOMMITTED, ret = cursor->prev(cursor));
+ /* Call cursor prev to get the largest key. */
+ WT_ERR(cursor->prev(cursor));
WT_ERR(ret);
/* Copy the key as we will reset the cursor after that. */
@@ -1153,6 +1154,8 @@ __wt_cursor_largest_key(WT_CURSOR *cursor)
err:
if (!ignore_tombstone)
F_CLR(cursor, WT_CURSTD_IGNORE_TOMBSTONE);
+ if (!visible_all)
+ F_CLR(cursor, WT_CURSTD_VISIBLE_ALL);
__wt_scr_free(session, &key);
if (ret != 0)
WT_TRET(cursor->reset(cursor));
diff --git a/src/third_party/wiredtiger/src/docs/cursor-ops.dox b/src/third_party/wiredtiger/src/docs/cursor-ops.dox
index 82b763b563f..9618396a77c 100644
--- a/src/third_party/wiredtiger/src/docs/cursor-ops.dox
+++ b/src/third_party/wiredtiger/src/docs/cursor-ops.dox
@@ -108,10 +108,8 @@ record does not previously exist.
The WT_SESSION::largest_key \c gets the largest key in a table regardless of
visibility.
-It can only be called without a read timestamp, otherwise it returns an invalid
-argument error. Any following prev or next calls will behave as if they were
-invoked on an unpositioned cursor no matter the largest key call is successful
-or not.
+Any following prev or next calls will behave as if they were invoked on an
+unpositioned cursor no matter the largest key call is successful or not.
@section cursor_error Cursor position after error
diff --git a/src/third_party/wiredtiger/src/include/txn_inline.h b/src/third_party/wiredtiger/src/include/txn_inline.h
index 908fe1d38dd..a6b13708057 100644
--- a/src/third_party/wiredtiger/src/include/txn_inline.h
+++ b/src/third_party/wiredtiger/src/include/txn_inline.h
@@ -766,9 +766,9 @@ __wt_txn_upd_visible_type(WT_SESSION_IMPL *session, WT_UPDATE *upd)
if (prepare_state == WT_PREPARE_LOCKED)
continue;
- if (WT_IS_HS(session->dhandle) && upd->txnid != WT_TXN_ABORTED &&
- upd->type == WT_UPDATE_STANDARD)
- /* Entries in the history store are always visible. */
+ /* Entries in the history store are always visible. */
+ if ((WT_IS_HS(session->dhandle) && upd->txnid != WT_TXN_ABORTED &&
+ upd->type == WT_UPDATE_STANDARD))
return (WT_VISIBLE_TRUE);
upd_visible = __wt_txn_visible(session, upd->txnid, upd->start_ts);
@@ -901,7 +901,10 @@ __wt_txn_read_upd_list_internal(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt,
continue;
}
- upd_visible = __wt_txn_upd_visible_type(session, upd);
+ if (F_ISSET(&cbt->iface, WT_CURSTD_VISIBLE_ALL))
+ upd_visible = WT_VISIBLE_TRUE;
+ else
+ upd_visible = __wt_txn_upd_visible_type(session, upd);
if (upd_visible == WT_VISIBLE_TRUE)
break;
@@ -1038,8 +1041,14 @@ retry:
cbt->upd_value->tw.prepare = tw.prepare;
}
- /* If the start time point is visible then we need to return the ondisk value. */
- if (WT_IS_HS(session->dhandle) || __wt_txn_tw_start_visible(session, &tw)) {
+ /*
+ * We return the onpage value in the following cases:
+ * 1. The record is from the history store.
+ * 2. It has the WT_CURSTD_VISIBLE_ALL flag set.
+ * 3. It is visible to the reader.
+ */
+ if (WT_IS_HS(session->dhandle) || F_ISSET(&cbt->iface, WT_CURSTD_VISIBLE_ALL) ||
+ __wt_txn_tw_start_visible(session, &tw)) {
if (cbt->upd_value->skip_buf) {
cbt->upd_value->buf.data = NULL;
cbt->upd_value->buf.size = 0;
diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in
index 3517c3523d2..ec50d871f90 100644
--- a/src/third_party/wiredtiger/src/include/wiredtiger.in
+++ b/src/third_party/wiredtiger/src/include/wiredtiger.in
@@ -735,6 +735,7 @@ struct __wt_cursor {
#define WT_CURSTD_RAW_SEARCH 0x0800000u
#define WT_CURSTD_VALUE_EXT 0x1000000u /* Value points out of tree. */
#define WT_CURSTD_VALUE_INT 0x2000000u /* Value points into tree. */
+#define WT_CURSTD_VISIBLE_ALL 0x4000000u
/* AUTOMATIC FLAG VALUE GENERATION STOP 32 */
#define WT_CURSTD_KEY_SET (WT_CURSTD_KEY_EXT | WT_CURSTD_KEY_INT)
#define WT_CURSTD_VALUE_SET (WT_CURSTD_VALUE_EXT | WT_CURSTD_VALUE_INT)
diff --git a/src/third_party/wiredtiger/test/suite/test_cursor17.py b/src/third_party/wiredtiger/test/suite/test_cursor17.py
index 322b82a65f8..becb6fcd5d3 100644
--- a/src/third_party/wiredtiger/test/suite/test_cursor17.py
+++ b/src/third_party/wiredtiger/test/suite/test_cursor17.py
@@ -118,32 +118,47 @@ class test_cursor17(wttest.WiredTigerTestCase):
session2 = self.setUpSessionOpen(self.conn)
cursor2 = session2.open_cursor(self.type + self.tablename, None)
session2.begin_transaction()
- cursor2[101] = self.ds.value(101)
+ cursor2[200] = self.ds.value(200)
cursor = self.session.open_cursor(self.type + self.tablename, None)
# Verify the largest key.
self.session.begin_transaction()
self.assertEqual(cursor.largest_key(), 0)
- self.assertEqual(cursor.get_key(), 101)
+ self.assertEqual(cursor.get_key(), 200)
self.session.rollback_transaction()
session2.rollback_transaction()
+
+ def test_invisible_timestamp(self):
+ self.populate(100)
- def test_read_timestamp(self):
+ cursor = self.session.open_cursor(self.type + self.tablename, None)
+ self.session.begin_transaction()
+ cursor[200] = self.ds.value(200)
+ self.session.commit_transaction("commit_timestamp=" + self.timestamp_str(10))
+
+ # Verify the largest key.
+ self.session.begin_transaction("read_timestamp=" + self.timestamp_str(5))
+ self.assertEqual(cursor.largest_key(), 0)
+ self.assertEqual(cursor.get_key(), 200)
+ self.session.rollback_transaction()
+
+ def test_prepared_update(self):
self.populate(100)
+ session2 = self.setUpSessionOpen(self.conn)
+ cursor2 = session2.open_cursor(self.type + self.tablename, None)
+ session2.begin_transaction()
+ cursor2[200] = self.ds.value(200)
+ session2.prepare_transaction("prepare_timestamp=" + self.timestamp_str(10))
+
cursor = self.session.open_cursor(self.type + self.tablename, None)
- self.session.begin_transaction('read_timestamp=' + self.timestamp_str(5))
- # Expect the largest key to throw.
- with self.expectedStderrPattern("largest key cannot be called with a read timestamp"):
- try:
- cursor.largest_key()
- except wiredtiger.WiredTigerError as e:
- gotException = True
- self.pr('got expected exception: ' + str(e))
- self.assertTrue(str(e).find('nvalid argument') >= 0)
- self.assertTrue(gotException, msg = 'expected exception')
+
+ # Verify the largest key.
+ self.session.begin_transaction("read_timestamp=" + self.timestamp_str(20))
+ self.assertEqual(cursor.largest_key(), 0)
+ self.assertEqual(cursor.get_key(), 200)
self.session.rollback_transaction()
def test_not_positioned(self):