summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2020-04-06 13:40:56 +1000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-04-06 03:58:40 +0000
commitd0a5a1ff47487c9b08f77610cbc02d64bab08d33 (patch)
tree1dd0c09b85062ce42f725dde0fd7d408af410da3
parent3c97892206735c532cfeda0c0cb045c2b1f2758a (diff)
downloadmongo-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.data2
-rw-r--r--src/third_party/wiredtiger/src/include/hardware.h7
-rw-r--r--src/third_party/wiredtiger/src/include/txn.i15
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_visibility.c18
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);