summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/btree/row_modify.c
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2020-01-13 14:25:10 +1100
committerLuke Chen <luke.chen@mongodb.com>2020-01-13 14:27:49 +1100
commitcf013cac38ee4b655c990fd0db341298a8d6d563 (patch)
tree064fef03b32ff4341d6cd3241fdf656024e07ef3 /src/third_party/wiredtiger/src/btree/row_modify.c
parent462cc0e91455e0c18f40722ab1dab3ea2bdca581 (diff)
downloadmongo-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.c44
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;
+ }
}
/*