diff options
author | Etienne Petrel <etienne.petrel@mongodb.com> | 2022-04-26 00:19:15 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-04-26 00:48:08 +0000 |
commit | 6e86a832f76cb16a0d943c51eb0679a5500d53b9 (patch) | |
tree | dbb0df26f533912552ccedaa365c376c02ef5223 /src | |
parent | 7fd4bcc374933297664e03582681a3a6bd312bab (diff) | |
download | mongo-6e86a832f76cb16a0d943c51eb0679a5500d53b9.tar.gz |
Import wiredtiger: b055c2402564bc521d73c274afa3d3bc989a0d3b from branch mongodb-master
ref: d1261c2d35..b055c24025
for: 6.1.0-rc0
WT-9147 No need to walk the whole update chain in __wt_rec_upd_select except for metadata
Diffstat (limited to 'src')
-rw-r--r-- | src/third_party/wiredtiger/import.data | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/reconcile/rec_visibility.c | 31 |
2 files changed, 29 insertions, 4 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index 92cbfc23bac..cbf3dcbdf58 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": "d1261c2d35dc756bf8b30c0fa0a59a97137ec54d" + "commit": "b055c2402564bc521d73c274afa3d3bc989a0d3b" } diff --git a/src/third_party/wiredtiger/src/reconcile/rec_visibility.c b/src/third_party/wiredtiger/src/reconcile/rec_visibility.c index 4a7153ed196..b2022431e0c 100644 --- a/src/third_party/wiredtiger/src/reconcile/rec_visibility.c +++ b/src/third_party/wiredtiger/src/reconcile/rec_visibility.c @@ -418,8 +418,6 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W if ((txnid = upd->txnid) == WT_TXN_ABORTED) continue; - upd_memsize += WT_UPDATE_MEMSIZE(upd); - /* * Track the first update in the chain that is not aborted and the maximum transaction ID. */ @@ -432,6 +430,7 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W * Special handling for application threads evicting their own updates. */ if (!is_hs_page && F_ISSET(r, WT_REC_APP_EVICTION_SNAPSHOT) && txnid == session_txnid) { + upd_memsize += WT_UPDATE_MEMSIZE(upd); has_newer_updates = true; continue; } @@ -459,6 +458,17 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W !is_hs_page && (F_ISSET(r, WT_REC_VISIBLE_ALL) ? WT_TXNID_LE(r->last_running, txnid) : !__txn_visible_id(session, txnid))) { + /* + * Rare case: metadata writes at read uncommitted isolation level, eviction may see a + * committed update followed by uncommitted updates. Give up in that case because we + * can't discard the uncommitted updates. + */ + if (upd_select->upd != NULL) { + WT_ASSERT(session, WT_IS_METADATA(session->dhandle)); + return (__wt_set_return(session, EBUSY)); + } + + upd_memsize += WT_UPDATE_MEMSIZE(upd); has_newer_updates = true; continue; } @@ -468,6 +478,7 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W upd->prepare_state == WT_PREPARE_INPROGRESS) { WT_ASSERT(session, upd_select->upd == NULL || upd_select->upd->txnid == upd->txnid); if (F_ISSET(r, WT_REC_CHECKPOINT)) { + upd_memsize += WT_UPDATE_MEMSIZE(upd); has_newer_updates = true; if (upd->start_ts > max_ts) max_ts = upd->start_ts; @@ -495,7 +506,12 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W if (upd_select->upd == NULL) upd_select->upd = upd; - if (!F_ISSET(r, WT_REC_EVICT)) + /* + * We only need to walk the whole update chain if we are evicting metadata as it is written + * with read uncommitted isolation and we may see a committed update followed by uncommitted + * updates + */ + if (!F_ISSET(r, WT_REC_EVICT) || !WT_IS_METADATA(session->dhandle)) break; } @@ -726,6 +742,15 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W supd_restore = F_ISSET(r, WT_REC_EVICT) && (has_newer_updates || F_ISSET(S2C(session), WT_CONN_IN_MEMORY)); + /* + * The total update size only contains uncommitted updates. This is wrong for the in memory + * case because we cannot discard any update until they are obsolete. Add them to the size. + */ + if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY) && onpage_upd != NULL) { + for (upd = tombstone != NULL ? tombstone : onpage_upd; upd != NULL; upd = upd->next) + if (upd->txnid != WT_TXN_ABORTED) + upd_memsize += WT_UPDATE_MEMSIZE(upd); + } WT_RET(__rec_update_save( session, r, ins, rip, onpage_upd, tombstone, supd_restore, upd_memsize)); |