diff options
author | Luke Chen <luke.chen@mongodb.com> | 2020-04-06 13:40:56 +1000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-04-06 03:58:40 +0000 |
commit | d0a5a1ff47487c9b08f77610cbc02d64bab08d33 (patch) | |
tree | 1dd0c09b85062ce42f725dde0fd7d408af410da3 | |
parent | 3c97892206735c532cfeda0c0cb045c2b1f2758a (diff) | |
download | mongo-d0a5a1ff47487c9b08f77610cbc02d64bab08d33.tar.gz |
Import wiredtiger: cb9f737fc6c1d78a4ad50df50cdfa4047e04e6c4 from branch mongodb-4.0
ref: 1289661dc5..cb9f737fc6
for: 4.0.18
WT-5119 Birthmark records can be read as normal updates if reads race with checkpoints
WT-5376 WT_UPDATE.type field can race with visibility checks when returning key/value pairs
-rw-r--r-- | src/third_party/wiredtiger/import.data | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/hardware.h | 7 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/txn.i | 15 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/reconcile/rec_visibility.c | 18 |
4 files changed, 28 insertions, 14 deletions
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index 9f5d99840e1..fede97bc1cf 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-4.0", - "commit": "1289661dc517fcd41326d407a04c788926db1919" + "commit": "cb9f737fc6c1d78a4ad50df50cdfa4047e04e6c4" } diff --git a/src/third_party/wiredtiger/src/include/hardware.h b/src/third_party/wiredtiger/src/include/hardware.h index 447d082393e..a93f1e41fbc 100644 --- a/src/third_party/wiredtiger/src/include/hardware.h +++ b/src/third_party/wiredtiger/src/include/hardware.h @@ -16,6 +16,13 @@ (v) = (val); \ } while (0) +/* Write after all previous stores are completed. */ +#define WT_ORDERED_WRITE(v, val) \ + do { \ + WT_WRITE_BARRIER(); \ + (v) = (val); \ + } while (0) + /* * Read a shared location and guarantee that subsequent reads do not see any earlier state. */ diff --git a/src/third_party/wiredtiger/src/include/txn.i b/src/third_party/wiredtiger/src/include/txn.i index 38c68474397..73d953eee62 100644 --- a/src/third_party/wiredtiger/src/include/txn.i +++ b/src/third_party/wiredtiger/src/include/txn.i @@ -830,12 +830,17 @@ __wt_txn_read(WT_SESSION_IMPL *session, WT_UPDATE *upd, WT_UPDATE **updp) { static WT_UPDATE tombstone = {.txnid = WT_TXN_NONE, .type = WT_UPDATE_TOMBSTONE}; WT_VISIBLE_TYPE upd_visible; + uint8_t type; bool skipped_birthmark; *updp = NULL; + + type = WT_UPDATE_INVALID; /* [-Wconditional-uninitialized] */ for (skipped_birthmark = false; upd != NULL; upd = upd->next) { + WT_ORDERED_READ(type, upd->type); + /* Skip reserved place-holders, they're never visible. */ - if (upd->type != WT_UPDATE_RESERVE) { + if (type != WT_UPDATE_RESERVE) { upd_visible = __wt_txn_upd_visible_type(session, upd); if (upd_visible == WT_VISIBLE_TRUE) break; @@ -843,14 +848,16 @@ __wt_txn_read(WT_SESSION_IMPL *session, WT_UPDATE *upd, WT_UPDATE **updp) return (WT_PREPARE_CONFLICT); } /* An invisible birthmark is equivalent to a tombstone. */ - if (upd->type == WT_UPDATE_BIRTHMARK) + if (type == WT_UPDATE_BIRTHMARK) skipped_birthmark = true; } - if (upd == NULL && skipped_birthmark) + if (upd == NULL && skipped_birthmark) { upd = &tombstone; + type = upd->type; + } - *updp = upd == NULL || upd->type == WT_UPDATE_BIRTHMARK ? NULL : upd; + *updp = upd == NULL || type == WT_UPDATE_BIRTHMARK ? NULL : upd; return (0); } diff --git a/src/third_party/wiredtiger/src/reconcile/rec_visibility.c b/src/third_party/wiredtiger/src/reconcile/rec_visibility.c index 253152e2ddd..6d881a13c05 100644 --- a/src/third_party/wiredtiger/src/reconcile/rec_visibility.c +++ b/src/third_party/wiredtiger/src/reconcile/rec_visibility.c @@ -87,12 +87,10 @@ __rec_append_orig_value( } /* - * If we're saving the original value for a birthmark, transfer over - * the transaction ID and clear out the birthmark update. - * - * Else, set the entry's transaction information to the lowest possible - * value. Cleared memory matches the lowest possible transaction ID and - * timestamp, do nothing. + * If we're saving the original value for a birthmark, transfer over the transaction ID and + * clear out the birthmark update. Else, set the entry's transaction information to the lowest + * possible value (as cleared memory matches the lowest possible transaction ID and timestamp, + * do nothing). */ if (upd->type == WT_UPDATE_BIRTHMARK) { append->txnid = upd->txnid; @@ -102,13 +100,15 @@ __rec_append_orig_value( /* Append the new entry into the update list. */ WT_PUBLISH(upd->next, append); - __wt_cache_page_inmem_incr(session, page, size); + /* Replace the birthmark with an aborted transaction. */ if (upd->type == WT_UPDATE_BIRTHMARK) { - upd->type = WT_UPDATE_STANDARD; - upd->txnid = WT_TXN_ABORTED; + WT_ORDERED_WRITE(upd->txnid, WT_TXN_ABORTED); + WT_ORDERED_WRITE(upd->type, WT_UPDATE_STANDARD); } + __wt_cache_page_inmem_incr(session, page, size); + err: __wt_scr_free(session, &tmp); return (ret); |