diff options
author | Luke Chen <luke.chen@mongodb.com> | 2020-01-13 14:25:10 +1100 |
---|---|---|
committer | Luke Chen <luke.chen@mongodb.com> | 2020-01-13 14:27:49 +1100 |
commit | cf013cac38ee4b655c990fd0db341298a8d6d563 (patch) | |
tree | 064fef03b32ff4341d6cd3241fdf656024e07ef3 /src/third_party/wiredtiger/src/btree/row_modify.c | |
parent | 462cc0e91455e0c18f40722ab1dab3ea2bdca581 (diff) | |
download | mongo-cf013cac38ee4b655c990fd0db341298a8d6d563.tar.gz |
Import wiredtiger: 54a846c423023183195dccc634aff4770f11ba54 from branch mongodb-4.0
ref: e651c9e274..54a846c423
for: 4.0.15
WT-4636 Fix strace in syscall test
WT-5042 Reduce configuration parsing overhead from checkpoints
WT-5106 Remove temporary files in clang-format script
WT-5112 Handling goto labels with multiple words in s_goto.py
WT-5120 Checkpoint hangs when reconciliation doesn't release the eviction generation
WT-5125 Adding new stats for eviction target strategy
WT-5135 Change lookaside file inserts to use cursor.insert
WT-5136 Fix reading freed memory due to birthmark after uncommitted updates freed
WT-5169 WT_REF_LIMBO pages cannot support fast (leaf-page only) searches
WT-5196 Data mismatch failures with test/checkpoint after enabling LAS sweep
WT-5218 Improve eviction to differentiate between clean and dirty pages with WT_CACHE_EVICT_NOKEEP readgen
WT-5239 Fix syscall failure about metadata file open
WT-5247 Ensure that only idempotent modify operations are logged
WT-5277 Cursor key out-of-order detected in the lookaside file
Diffstat (limited to 'src/third_party/wiredtiger/src/btree/row_modify.c')
-rw-r--r-- | src/third_party/wiredtiger/src/btree/row_modify.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/src/third_party/wiredtiger/src/btree/row_modify.c b/src/third_party/wiredtiger/src/btree/row_modify.c index c6c35de6e6f..7d9425b4ac0 100644 --- a/src/third_party/wiredtiger/src/btree/row_modify.c +++ b/src/third_party/wiredtiger/src/btree/row_modify.c @@ -41,14 +41,15 @@ err: * Row-store insert, update and delete. */ int -__wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, const WT_ITEM *key, - const WT_ITEM *value, WT_UPDATE *upd_arg, u_int modify_type, bool exclusive) +__wt_row_modify(WT_CURSOR_BTREE *cbt, const WT_ITEM *key, const WT_ITEM *value, WT_UPDATE *upd_arg, + u_int modify_type, bool exclusive) { WT_DECL_RET; WT_INSERT *ins; WT_INSERT_HEAD *ins_head, **ins_headp; WT_PAGE *page; WT_PAGE_MODIFY *mod; + WT_SESSION_IMPL *session; WT_UPDATE *old_upd, *upd, **upd_entry; size_t ins_size, upd_size; uint32_t ins_slot; @@ -57,6 +58,7 @@ __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, const WT_ITEM *k ins = NULL; page = cbt->ref->page; + session = (WT_SESSION_IMPL *)cbt->iface.session; upd = upd_arg; logged = false; @@ -295,6 +297,7 @@ __wt_update_obsolete_check( WT_UPDATE *first, *next, *prev; size_t size; u_int count; + bool upd_visible_all_seen; txn_global = &S2C(session)->txn_global; @@ -309,21 +312,38 @@ __wt_update_obsolete_check( * Only updates with globally visible, self-contained data can terminate * update chains. * - * Birthmarks are a special case: once a birthmark becomes obsolete, it - * can be discarded and subsequent reads will see the on-page value (as - * expected). Inserting updates into the lookaside table relies on - * this behavior to avoid creating update chains with multiple - * birthmarks. + * Birthmarks are a special case: once a birthmark becomes obsolete, it can be discarded if + * there is a globally visible update before it and subsequent reads will see the on-page value + * (as expected). Inserting updates into the lookaside table relies on this behavior to avoid + * creating update chains with multiple birthmarks. We cannot discard the birthmark if it's the + * first globally visible update as the previous updates can be aborted and be freed causing the + * entire update chain being removed. */ - for (first = prev = NULL, count = 0; upd != NULL; prev = upd, upd = upd->next, count++) { + for (first = prev = NULL, upd_visible_all_seen = false, count = 0; upd != NULL; + prev = upd, upd = upd->next, count++) { if (upd->txnid == WT_TXN_ABORTED) continue; + if (!__wt_txn_upd_visible_all(session, upd)) first = NULL; - else if (first == NULL && upd->type == WT_UPDATE_BIRTHMARK) - first = prev; - else if (first == NULL && WT_UPDATE_DATA_VALUE(upd)) - first = upd; + else { + if (first == NULL) { + /* + * If we have seen a globally visible update before the birthmark, the birthmark can + * be discarded. + */ + if (upd_visible_all_seen && upd->type == WT_UPDATE_BIRTHMARK) + first = prev; + /* + * We cannot discard the birthmark if it is the first globally visible update as the + * previous updates can be aborted resulting the entire update chain being removed. + */ + else if (upd->type == WT_UPDATE_BIRTHMARK || WT_UPDATE_DATA_VALUE(upd)) + first = upd; + } + + upd_visible_all_seen = true; + } } /* |