diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/btree/bt_read.c')
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_read.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/src/third_party/wiredtiger/src/btree/bt_read.c b/src/third_party/wiredtiger/src/btree/bt_read.c index c77f409694d..2f6f4e3eb88 100644 --- a/src/third_party/wiredtiger/src/btree/bt_read.c +++ b/src/third_party/wiredtiger/src/btree/bt_read.c @@ -95,6 +95,7 @@ __page_read(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags) WT_DECL_RET; WT_ITEM tmp; WT_PAGE *notused; + WT_PAGE_DELETED *del; uint32_t page_flags; uint8_t previous_state; bool prepare; @@ -155,15 +156,32 @@ __page_read(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags) if (prepare) WT_ERR(__wt_page_inmem_prepare(session, ref)); -skip_read: /* * In the case of a fast delete, move all of the page's records to a deleted state based on the * fast-delete information. Skip for special commands that don't care about an in-memory state. + * + * Note: there are three possible cases - the state was WT_REF_DELETED and ft_info.del was NULL; + * the state was WT_REF_DELETED and ft_info.del was non-NULL; and the state was WT_REF_DISK and + * the parent page cell was a WT_CELL_ADDR_DEL cell. The last is only valid in a readonly tree. + * + * ft_info.del gets cleared and set to NULL if the deletion is found to be globally visible; + * this can happen in any of several places. */ - if (previous_state == WT_REF_DELETED && + del = NULL; + if (previous_state == WT_REF_DISK) { + WT_ASSERT(session, ref->ft_info.del == NULL); + if (addr.del_set) { + WT_ASSERT(session, F_ISSET(S2BT(session), WT_BTREE_READONLY)); + del = &addr.del; + } + } else + del = ref->ft_info.del; + + if ((previous_state == WT_REF_DELETED || del != NULL) && !F_ISSET(S2BT(session), WT_BTREE_SALVAGE | WT_BTREE_UPGRADE | WT_BTREE_VERIFY)) - WT_ERR(__wt_delete_page_instantiate(session, ref)); + WT_ERR(__wt_delete_page_instantiate(session, ref, del)); +skip_read: F_CLR(ref, WT_REF_FLAG_READING); WT_REF_SET_STATE(ref, WT_REF_MEM); @@ -225,7 +243,8 @@ __wt_page_in_func(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags ;) { switch (current_state = ref->state) { case WT_REF_DELETED: - if (LF_ISSET(WT_READ_NO_WAIT)) + /* Optionally limit reads to cache-only. */ + if (LF_ISSET(WT_READ_CACHE | WT_READ_NO_WAIT)) return (WT_NOTFOUND); if (LF_ISSET(WT_READ_SKIP_DELETED) && __wt_delete_page_skip(session, ref, !F_ISSET(txn, WT_TXN_HAS_SNAPSHOT))) |