diff options
author | Etienne Petrel <etienne.petrel@mongodb.com> | 2021-11-18 14:43:46 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-11-18 15:39:41 +0000 |
commit | 63639d4b9348c7a9943ab38121c5701b8dc09892 (patch) | |
tree | 5047ac77eb656f166da75860f144aad4f405aa94 /src | |
parent | 041cb777961858638cbb834015d24d6bc2f2fd08 (diff) | |
download | mongo-63639d4b9348c7a9943ab38121c5701b8dc09892.tar.gz |
Import wiredtiger: 73e6a5f9733205d2b0c1d58a78480fc2f5b08085 from branch mongodb-master
ref: 76bac330da..73e6a5f973
for: 5.2.0
WT-8303 Implement weak hazard pointers
Diffstat (limited to 'src')
-rw-r--r-- | src/third_party/wiredtiger/.clang-format | 1 | ||||
-rw-r--r-- | src/third_party/wiredtiger/dist/filelist | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | src/third_party/wiredtiger/dist/s_clang-scan | 0 | ||||
-rw-r--r-- | src/third_party/wiredtiger/import.data | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/conn/conn_open.c | 1 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/evict/evict_page.c | 8 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/extern.h | 7 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/session.h | 24 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/txn.h | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/wt_internal.h | 4 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/session/session_api.c | 14 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/support/hazard.c | 13 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/support/hazard_weak.c | 280 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/txn/txn.c | 24 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/txn/txn_log.c | 23 |
15 files changed, 393 insertions, 11 deletions
diff --git a/src/third_party/wiredtiger/.clang-format b/src/third_party/wiredtiger/.clang-format index ad0583e71e0..b5595a1f863 100644 --- a/src/third_party/wiredtiger/.clang-format +++ b/src/third_party/wiredtiger/.clang-format @@ -78,6 +78,7 @@ ForEachMacros: - WT_COL_FOREACH - WT_EXT_FOREACH - WT_EXT_FOREACH_OFF + - WT_HAZARD_WEAK_FORALL - WT_INTL_FOREACH_BEGIN - WT_INTL_FOREACH_REVERSE_BEGIN - WT_MODIFY_FOREACH_BEGIN diff --git a/src/third_party/wiredtiger/dist/filelist b/src/third_party/wiredtiger/dist/filelist index a37d0e116e0..a50ec3d667c 100644 --- a/src/third_party/wiredtiger/dist/filelist +++ b/src/third_party/wiredtiger/dist/filelist @@ -200,6 +200,7 @@ src/support/global.c src/support/hash_city.c src/support/hash_fnv.c src/support/hazard.c +src/support/hazard_weak.c src/support/hex.c src/support/huffman.c src/support/lock_ext.c diff --git a/src/third_party/wiredtiger/dist/s_clang-scan b/src/third_party/wiredtiger/dist/s_clang-scan index 9a5ee3d4587..9a5ee3d4587 100644..100755 --- a/src/third_party/wiredtiger/dist/s_clang-scan +++ b/src/third_party/wiredtiger/dist/s_clang-scan diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index 4b0d980b99e..d84cebd36d1 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": "76bac330dabda8d508cc57ed7e00ee68b08f6ec2" + "commit": "73e6a5f9733205d2b0c1d58a78480fc2f5b08085" } diff --git a/src/third_party/wiredtiger/src/conn/conn_open.c b/src/third_party/wiredtiger/src/conn/conn_open.c index 5d01264502d..d7fe6368fe1 100644 --- a/src/third_party/wiredtiger/src/conn/conn_open.c +++ b/src/third_party/wiredtiger/src/conn/conn_open.c @@ -178,6 +178,7 @@ __wt_connection_close(WT_CONNECTION_IMPL *conn) __wt_free(session, s->dhhash); __wt_stash_discard_all(session, s); __wt_free(session, s->hazard); + __wt_hazard_weak_destroy(session, s); } /* Destroy the file-system configuration. */ diff --git a/src/third_party/wiredtiger/src/evict/evict_page.c b/src/third_party/wiredtiger/src/evict/evict_page.c index de249ec4a4b..a0e7314c0cc 100644 --- a/src/third_party/wiredtiger/src/evict/evict_page.c +++ b/src/third_party/wiredtiger/src/evict/evict_page.c @@ -152,6 +152,14 @@ __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, uint8_t previous_state, uint32 } /* + * We have exclusive access, invalidate any weak hazard pointers. Note: In the future we will + * investigate a better place to invalidate the weak hazard pointers. Ideally, we want to delay + * invalidation as long as possible so that if eviction of this page were to fail, we would not + * have invalidated the weak hazard pointers unnecessarily. + */ + __wt_hazard_weak_invalidate(session, ref); + + /* * Review the page for conditions that would block its eviction. If the check fails (for * example, we find a page with active children), quit. Make this check for clean pages, too: * while unlikely eviction would choose an internal page with children, it's not disallowed. diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h index 9d0be1b7016..3558d2dfe7e 100644 --- a/src/third_party/wiredtiger/src/include/extern.h +++ b/src/third_party/wiredtiger/src/include/extern.h @@ -782,6 +782,10 @@ extern int __wt_hazard_set_func(WT_SESSION_IMPL *session, WT_REF *ref, bool *bus const char *func, int line #endif ) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_hazard_weak_clear(WT_SESSION_IMPL *session, WT_TXN_OP *op) + WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_hazard_weak_set(WT_SESSION_IMPL *session, WT_REF *ref, WT_TXN_OP *op) + WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_hex2byte(const u_char *from, u_char *to) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to) @@ -1786,6 +1790,9 @@ extern void __wt_gen_init(WT_SESSION_IMPL *session); extern void __wt_gen_next(WT_SESSION_IMPL *session, int which, uint64_t *genp); extern void __wt_gen_next_drain(WT_SESSION_IMPL *session, int which); extern void __wt_hazard_close(WT_SESSION_IMPL *session); +extern void __wt_hazard_weak_close(WT_SESSION_IMPL *session); +extern void __wt_hazard_weak_destroy(WT_SESSION_IMPL *session_safe, WT_SESSION_IMPL *s); +extern void __wt_hazard_weak_invalidate(WT_SESSION_IMPL *session, WT_REF *ref); extern void __wt_hs_close(WT_SESSION_IMPL *session); extern void __wt_hs_upd_time_window(WT_CURSOR *hs_cursor, WT_TIME_WINDOW **twp); extern void __wt_huffman_close(WT_SESSION_IMPL *session, void *huffman_arg); diff --git a/src/third_party/wiredtiger/src/include/session.h b/src/third_party/wiredtiger/src/include/session.h index 85690b57fbd..5273e1234b4 100644 --- a/src/third_party/wiredtiger/src/include/session.h +++ b/src/third_party/wiredtiger/src/include/session.h @@ -30,6 +30,28 @@ struct __wt_hazard { #endif }; +/* + * WT_HAZARD_WEAK -- + * A weak hazard pointer. + */ +struct __wt_hazard_weak { + WT_REF *ref; /* Page reference */ + bool valid; /* Is the weak hazard pointer still valid? */ +}; + +/* + * WT_HAZARD_WEAK_ARRAY -- + * A per-session array of weak hazard pointers. These are grown by adding a new array, and are + * only freed when the session is closed. + */ +struct __wt_hazard_weak_array { + uint32_t hazard_size; /* Weak hazard pointer array slots */ + uint32_t hazard_inuse; /* Weak hazard pointer array slots in-use */ + uint32_t nhazard; /* Count of active weak hazard pointers */ + WT_HAZARD_WEAK_ARRAY *next; + WT_HAZARD_WEAK hazard[0]; /* Weak hazard pointer array */ +}; + /* Get the connection implementation for a session */ #define S2C(session) ((WT_CONNECTION_IMPL *)(session)->iface.connection) @@ -279,6 +301,8 @@ struct __wt_session_impl { uint32_t nhazard; /* Count of active hazard pointers */ WT_HAZARD *hazard; /* Hazard pointer array */ + WT_HAZARD_WEAK_ARRAY *hazard_weak; + /* * Operation tracking. */ diff --git a/src/third_party/wiredtiger/src/include/txn.h b/src/third_party/wiredtiger/src/include/txn.h index cb433664094..b1c2b50a743 100644 --- a/src/third_party/wiredtiger/src/include/txn.h +++ b/src/third_party/wiredtiger/src/include/txn.h @@ -196,6 +196,8 @@ typedef enum { struct __wt_txn_op { WT_BTREE *btree; WT_TXN_TYPE type; + WT_HAZARD_WEAK *whp; + union { /* WT_TXN_OP_BASIC_ROW, WT_TXN_OP_INMEM_ROW */ struct { diff --git a/src/third_party/wiredtiger/src/include/wt_internal.h b/src/third_party/wiredtiger/src/include/wt_internal.h index 429c1c92c40..0d6319d6ec2 100644 --- a/src/third_party/wiredtiger/src/include/wt_internal.h +++ b/src/third_party/wiredtiger/src/include/wt_internal.h @@ -211,6 +211,10 @@ struct __wt_fstream; typedef struct __wt_fstream WT_FSTREAM; struct __wt_hazard; typedef struct __wt_hazard WT_HAZARD; +struct __wt_hazard_weak; +typedef struct __wt_hazard_weak WT_HAZARD_WEAK; +struct __wt_hazard_weak_array; +typedef struct __wt_hazard_weak_array WT_HAZARD_WEAK_ARRAY; struct __wt_ikey; typedef struct __wt_ikey WT_IKEY; struct __wt_index; diff --git a/src/third_party/wiredtiger/src/session/session_api.c b/src/third_party/wiredtiger/src/session/session_api.c index 74e2cdab612..ca4762298e2 100644 --- a/src/third_party/wiredtiger/src/session/session_api.c +++ b/src/third_party/wiredtiger/src/session/session_api.c @@ -191,6 +191,8 @@ __wt_session_release_resources(WT_SESSION_IMPL *session) static void __session_clear(WT_SESSION_IMPL *session) { + WT_HAZARD_WEAK_ARRAY *wha; + /* * There's no serialization support around the review of the hazard array, which means threads * checking for hazard pointers first check the active field (which may be 0) and then use the @@ -205,6 +207,11 @@ __session_clear(WT_SESSION_IMPL *session) session->hazard_inuse = 0; session->nhazard = 0; + + for (wha = session->hazard_weak; wha != NULL; wha = wha->next) { + wha->hazard_inuse = 0; + wha->nhazard = 0; + } } /* @@ -2064,6 +2071,13 @@ __open_session(WT_CONNECTION_IMPL *conn, WT_EVENT_HANDLER *event_handler, const session_ret->hazard_size = WT_SESSION_INITIAL_HAZARD_SLOTS; session_ret->hazard_inuse = 0; session_ret->nhazard = 0; + + WT_ERR(__wt_calloc(session, 1, + sizeof(WT_HAZARD_WEAK_ARRAY) + WT_SESSION_INITIAL_HAZARD_SLOTS * sizeof(WT_HAZARD_WEAK), + &session_ret->hazard_weak)); + session_ret->hazard_weak->hazard_size = WT_SESSION_INITIAL_HAZARD_SLOTS; + session_ret->hazard_weak->hazard_inuse = 0; + session_ret->hazard_weak->nhazard = 0; } /* diff --git a/src/third_party/wiredtiger/src/support/hazard.c b/src/third_party/wiredtiger/src/support/hazard.c index 0470f441cd5..1eaf46992ff 100644 --- a/src/third_party/wiredtiger/src/support/hazard.c +++ b/src/third_party/wiredtiger/src/support/hazard.c @@ -7,7 +7,6 @@ */ #include "wt_internal.h" - #ifdef HAVE_DIAGNOSTIC static void __hazard_dump(WT_SESSION_IMPL *); #endif @@ -51,7 +50,8 @@ hazard_grow(WT_SESSION_IMPL *session) * leak the memory. */ __wt_gen_next(session, WT_GEN_HAZARD, &hazard_gen); - WT_IGNORE_RET(__wt_stash_add(session, WT_GEN_HAZARD, hazard_gen, ohazard, 0)); + WT_IGNORE_RET( + __wt_stash_add(session, WT_GEN_HAZARD, hazard_gen, ohazard, size * sizeof(WT_HAZARD))); return (0); } @@ -237,7 +237,7 @@ __wt_hazard_close(WT_SESSION_IMPL *session) break; } if (session->nhazard == 0 && !found) - return; + goto weak; __wt_errx(session, "session %p: close hazard pointer table: table not empty", (void *)session); @@ -263,6 +263,10 @@ __wt_hazard_close(WT_SESSION_IMPL *session) if (session->nhazard != 0) __wt_errx(session, "session %p: close hazard pointer table: count didn't match entries", (void *)session); + +weak: + /* Same for weak hazard pointers. */ + __wt_hazard_weak_close(session); } /* @@ -361,7 +365,8 @@ __wt_hazard_count(WT_SESSION_IMPL *session, WT_REF *ref) uint32_t i, hazard_inuse; u_int count; - hazard_get_reference(session, &hp, &hazard_inuse); + hp = session->hazard; + hazard_inuse = session->hazard_inuse; for (count = 0, i = 0; i < hazard_inuse; ++hp, ++i) if (hp->ref == ref) diff --git a/src/third_party/wiredtiger/src/support/hazard_weak.c b/src/third_party/wiredtiger/src/support/hazard_weak.c new file mode 100644 index 00000000000..463a8afe097 --- /dev/null +++ b/src/third_party/wiredtiger/src/support/hazard_weak.c @@ -0,0 +1,280 @@ +/*- + * Copyright (c) 2014-present MongoDB, Inc. + * Copyright (c) 2008-2014 WiredTiger, Inc. + * All rights reserved. + * + * See the file LICENSE for redistribution information. + */ + +#include "wt_internal.h" + +#define WT_HAZARD_WEAK_FORALL(s, wha, whp) \ + for (wha = (s)->hazard_weak; wha != NULL; wha = wha->next) \ + for (whp = wha->hazard; whp < wha->hazard + wha->hazard_inuse; whp++) + +#define WT_HAZARD_WEAK_FORALL_BARRIER(s, wha, whp) \ + for (wha = (s)->hazard_weak; wha != NULL; wha = wha->next) { \ + uint32_t __hazard_inuse; \ + WT_ORDERED_READ(__hazard_inuse, wha->hazard_inuse); \ + for (whp = wha->hazard; whp < wha->hazard + __hazard_inuse; whp++) + +#define WT_HAZARD_WEAK_FORALL_BARRIER_END } + +/* + * __wt_hazard_weak_close -- + * Verify that no weak hazard pointers are set. + */ +void +__wt_hazard_weak_close(WT_SESSION_IMPL *session) +{ + WT_HAZARD_WEAK *whp; + WT_HAZARD_WEAK_ARRAY *wha; + uint32_t nhazard_weak; + bool found; + + /* + * Check for a set weak hazard pointer and complain if we find one. We could just check the + * session's weak hazard pointer count, but this is a useful diagnostic. + */ + for (found = false, nhazard_weak = 0, wha = session->hazard_weak; wha != NULL; + nhazard_weak += wha->nhazard, wha = wha->next) + for (whp = wha->hazard; whp < wha->hazard + wha->hazard_inuse; whp++) + if (whp->ref != NULL) { + found = true; + break; + } + + if (nhazard_weak == 0 && !found) + return; + + __wt_errx( + session, "session %p: close weak hazard pointer table: table not empty", (void *)session); + + WT_HAZARD_WEAK_FORALL (session, wha, whp) + if (whp->ref != NULL) { + whp->ref = NULL; + --wha->nhazard; + --nhazard_weak; + } + + if (nhazard_weak != 0) + __wt_errx(session, + "session %p: close weak hazard pointer table: count didn't match entries", + (void *)session); +} + +/* + * hazard_weak_grow -- + * Grow a weak hazard pointer array. What we have is a list of arrays doubling in size, with the + * largest array being at the head of the list. The array at the head of the list is the only + * one we actively use to set the new weak hazard pointers. The older arrays get emptied as the + * sessions using them resolve their transactions, eventually leaving them all empty. + */ +static int +hazard_weak_grow(WT_SESSION_IMPL *session) +{ + WT_HAZARD_WEAK_ARRAY *wha; + size_t size; + + /* + * Allocate a new, larger hazard pointer array and link it into place. + */ + size = session->hazard_weak->hazard_size; + WT_RET(__wt_calloc( + session, sizeof(WT_HAZARD_WEAK_ARRAY) + 2 * size * sizeof(WT_HAZARD_WEAK), 1, &wha)); + wha->next = session->hazard_weak; + wha->hazard_size = (uint32_t)(size * 2); + + /* + * Swap the new hazard pointer array into place after initialization is complete (initialization + * must complete before eviction can see the new hazard pointer array). + */ + WT_PUBLISH(session->hazard_weak, wha); + + return (0); +} + +/* + * __wt_hazard_weak_destroy -- + * Free all memory associated with weak hazard pointers + */ +void +__wt_hazard_weak_destroy(WT_SESSION_IMPL *session_safe, WT_SESSION_IMPL *s) +{ + WT_HAZARD_WEAK_ARRAY *wha, *next; + + for (wha = s->hazard_weak; wha != NULL; wha = next) { + next = wha->next; + __wt_free(session_safe, wha); + } +} + +/* + * __wt_hazard_weak_set -- + * Set a weak hazard pointer. A hazard pointer must be held on the ref. + */ +int +__wt_hazard_weak_set(WT_SESSION_IMPL *session, WT_REF *ref, WT_TXN_OP *op) +{ + WT_HAZARD_WEAK *whp; + WT_HAZARD_WEAK_ARRAY *wha; + + WT_ASSERT(session, ref != NULL); + WT_ASSERT(session, op->whp == NULL); + + /* If a file can never be evicted, hazard pointers aren't required. */ + if (F_ISSET(op->btree, WT_BTREE_IN_MEMORY)) + return (0); + + /* If we have filled the current hazard pointer array, grow it. */ + for (wha = session->hazard_weak; wha != NULL && wha->nhazard >= wha->hazard_size; + wha = wha->next) + WT_ASSERT( + session, wha->nhazard == wha->hazard_size && wha->hazard_inuse == wha->hazard_size); + + if (wha == NULL) { + WT_RET(hazard_weak_grow(session)); + wha = session->hazard_weak; + } + + /* + * If there are no available hazard pointer slots, make another one visible. + */ + if (wha->nhazard >= wha->hazard_inuse) { + WT_ASSERT( + session, wha->nhazard == wha->hazard_inuse && wha->hazard_inuse < wha->hazard_size); + whp = &wha->hazard[wha->hazard_inuse++]; + } else { + WT_ASSERT( + session, wha->nhazard < wha->hazard_inuse && wha->hazard_inuse <= wha->hazard_size); + + /* + * There must be an empty slot in the array, find it. Skip most of the active slots by + * starting after the active count slot; there may be a free slot before there, but checking + * is expensive. If we reach the end of the array, continue the search from the beginning of + * the array. + */ + for (whp = wha->hazard + wha->nhazard;; ++whp) { + if (whp >= wha->hazard + wha->hazard_inuse) + whp = wha->hazard; + if (whp->ref == NULL) + break; + } + } + + ++wha->nhazard; + + WT_ASSERT(session, whp->ref == NULL); + + /* + * We rely on a hazard pointer protecting the ref, so for weak hazard pointers this is much + * simpler than the regular hazard pointer case. + */ + whp->ref = ref; + whp->valid = true; + + op->whp = whp; + return (0); +} + +/* + * __wt_hazard_weak_clear -- + * Clear a weak hazard pointer, given a modify operation. + */ +int +__wt_hazard_weak_clear(WT_SESSION_IMPL *session, WT_TXN_OP *op) +{ + WT_HAZARD_WEAK *whp; + WT_HAZARD_WEAK_ARRAY *wha; + + /* If a file can never be evicted, hazard pointers aren't required. */ + if (F_ISSET(op->btree, WT_BTREE_IN_MEMORY)) + return (0); + + whp = op->whp; + /* + * An empty slot reflects a serious error, we should always find the weak hazard pointer. Panic, + * because we messed up in and it could imply corruption. + */ + if (whp == NULL || whp->ref == NULL) + WT_RET_PANIC(session, WT_PANIC, + "session %p: could not find the weak hazard pointer for a modify operation", + (void *)session); + + /* + * We don't publish the weak hazard pointer clear as we only clear while holding the hazard + * pointer to the page, preventing eviction from looking for this weak pointer. + */ + whp->ref = NULL; + + /* + * Find the array this hazard pointer belongs to, and do the accounting for using one less slot. + */ + for (wha = session->hazard_weak; wha != NULL; wha = wha->next) { + if (whp >= wha->hazard && whp < wha->hazard + wha->hazard_size) { + if (wha->nhazard == 0) + WT_RET_PANIC(session, EINVAL, + "session %p: While clearing weak hazard pointer, the count of the pointers " + "went negative for the relevant array.", + (void *)session); + if (--wha->nhazard == 0) + WT_PUBLISH(wha->hazard_inuse, 0); + break; + } + } + /* + * We should always be able to find the array. Panic, because we messed up and it could imply + * corruption. + */ + if (wha == NULL) + WT_RET_PANIC(session, EINVAL, + "session %p: While clearing weak hazard pointer could not find the array.", + (void *)session); + + /* Clear the hazard stored in the modify operation. */ + op->whp = NULL; + + return (0); +} + +/* + * __wt_hazard_weak_invalidate -- + * Invalidate any weak hazard pointers on a page that is locked for eviction. + */ +void +__wt_hazard_weak_invalidate(WT_SESSION_IMPL *session, WT_REF *ref) +{ + WT_CONNECTION_IMPL *conn; + WT_HAZARD_WEAK *whp; + WT_HAZARD_WEAK_ARRAY *wha; + WT_SESSION_IMPL *s; + uint32_t i, session_cnt, walk_cnt; + + /* If a file can never be evicted, hazard pointers aren't required. */ + if (F_ISSET(S2BT(session), WT_BTREE_IN_MEMORY)) + return; + + conn = S2C(session); + + /* + * No lock is required because the session array is fixed size, but it may contain inactive + * entries. We must review any active session that might contain a hazard pointer, so insert a + * read barrier after reading the active session count. That way, no matter what sessions come + * or go, we'll check the slots for all of the sessions that could have been active when we + * started our check. + */ + WT_ORDERED_READ(session_cnt, conn->session_cnt); + for (s = conn->sessions, i = walk_cnt = 0; i < session_cnt; ++s, ++i) { + if (!s->active) + continue; + + WT_HAZARD_WEAK_FORALL_BARRIER(s, wha, whp) + { + ++walk_cnt; + if (whp->ref == ref) + whp->valid = false; + } + WT_HAZARD_WEAK_FORALL_BARRIER_END + } + WT_STAT_CONN_INCRV(session, cache_hazard_walks, walk_cnt); +} diff --git a/src/third_party/wiredtiger/src/txn/txn.c b/src/third_party/wiredtiger/src/txn/txn.c index bddfbe26ac7..7930ba85341 100644 --- a/src/third_party/wiredtiger/src/txn/txn.c +++ b/src/third_party/wiredtiger/src/txn/txn.c @@ -1780,6 +1780,14 @@ __wt_txn_commit(WT_SESSION_IMPL *session, const char *cfg[]) } /* + * For now just confirm that each operation has a weak hazard pointer and clear it + * before proceeding. + */ + if ((op->type == WT_TXN_OP_BASIC_ROW || op->type == WT_TXN_OP_INMEM_ROW) && + !WT_IS_METADATA(op->btree->dhandle) && upd->type != WT_UPDATE_RESERVE) + WT_ERR(__wt_hazard_weak_clear(session, op)); + + /* * Don't reset the timestamp of the history store records with history store * transaction timestamp. Those records should already have the original time window * when they are inserted into the history store. @@ -2022,6 +2030,14 @@ __wt_txn_prepare(WT_SESSION_IMPL *session, const char *cfg[]) break; } + /* + * For now just confirm that each operation has a weak hazard pointer and clear it + * before proceeding. + */ + if ((op->type == WT_TXN_OP_BASIC_ROW || op->type == WT_TXN_OP_INMEM_ROW) && + !WT_IS_METADATA(op->btree->dhandle) && upd->type != WT_UPDATE_RESERVE) + WT_RET(__wt_hazard_weak_clear(session, op)); + ++prepared_updates; /* Set prepare timestamp. */ @@ -2146,6 +2162,14 @@ __wt_txn_rollback(WT_SESSION_IMPL *session, const char *cfg[]) upd = op->u.op_upd; if (!prepare) { + /* + * For now just confirm that each operation has a weak hazard pointer and clear it + * before proceeding. + */ + if ((op->type == WT_TXN_OP_BASIC_ROW || op->type == WT_TXN_OP_INMEM_ROW) && + !WT_IS_METADATA(op->btree->dhandle) && upd->type != WT_UPDATE_RESERVE) + WT_TRET(__wt_hazard_weak_clear(session, op)); + if (S2C(session)->cache->hs_fileid != 0 && op->btree->id == S2C(session)->cache->hs_fileid) break; diff --git a/src/third_party/wiredtiger/src/txn/txn_log.c b/src/third_party/wiredtiger/src/txn/txn_log.c index 192dfc09cf2..cbed44285bc 100644 --- a/src/third_party/wiredtiger/src/txn/txn_log.c +++ b/src/third_party/wiredtiger/src/txn/txn_log.c @@ -162,6 +162,9 @@ __txn_oplist_printlog( void __wt_txn_op_free(WT_SESSION_IMPL *session, WT_TXN_OP *op) { + /* The weak pointer should have already been freed. */ + WT_ASSERT(session, op->whp == NULL); + switch (op->type) { case WT_TXN_OP_NONE: /* @@ -257,12 +260,6 @@ __wt_txn_log_op(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) conn = S2C(session); txn = session->txn; - if (!FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED) || - F_ISSET(session, WT_SESSION_NO_LOGGING) || - (F_ISSET(S2BT(session), WT_BTREE_NO_LOGGING) && - !FLD_ISSET(conn->log_flags, WT_CONN_LOG_DEBUG_MODE))) - return (0); - /* We'd better have a transaction. */ WT_ASSERT(session, F_ISSET(txn, WT_TXN_RUNNING) && F_ISSET(txn, WT_TXN_HAS_ID)); @@ -270,6 +267,20 @@ __wt_txn_log_op(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) op = txn->mod + txn->mod_count - 1; fileid = op->btree->id; + /* Set the weak hazard pointer for this update. */ + if ((op->type == WT_TXN_OP_BASIC_ROW || op->type == WT_TXN_OP_INMEM_ROW)) { + if (!WT_IS_METADATA(op->btree->dhandle)) { + WT_ASSERT(session, cbt != NULL); + WT_RET(__wt_hazard_weak_set(session, cbt->ref, op)); + } + } + + if (!FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED) || + F_ISSET(session, WT_SESSION_NO_LOGGING) || + (F_ISSET(S2BT(session), WT_BTREE_NO_LOGGING) && + !FLD_ISSET(conn->log_flags, WT_CONN_LOG_DEBUG_MODE))) + return (0); + /* * If this operation is diagnostic only, set the ignore bit on the fileid so that recovery can * skip it. |