summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith.bostic@mongodb.com>2017-08-23 23:00:49 -0400
committerMichael Cahill <michael.cahill@mongodb.com>2017-08-24 13:00:49 +1000
commitb29ec27e4ad1dcf6121404d6d3a4a288bf30fe6f (patch)
tree4cc1aa8be05fc8aa992f153d57b8bd9b29a731b3
parent62001a4d78a26e913f54ef9da660d45e56afebe5 (diff)
downloadmongo-b29ec27e4ad1dcf6121404d6d3a4a288bf30fe6f.tar.gz
WT-3538 Misaligned reads when using the lookaside table and timestamps (#3609)
-rw-r--r--src/btree/bt_read.c20
-rw-r--r--src/cache/cache_las.c23
2 files changed, 25 insertions, 18 deletions
diff --git a/src/btree/bt_read.c b/src/btree/bt_read.c
index 0c3cb026421..26ddde8d6ad 100644
--- a/src/btree/bt_read.c
+++ b/src/btree/bt_read.c
@@ -136,8 +136,9 @@ __las_page_instantiate(WT_SESSION_IMPL *session,
WT_CURSOR *cursor;
WT_CURSOR_BTREE cbt;
WT_DECL_ITEM(current_key);
- WT_ITEM las_addr, las_key, las_timestamp, las_value;
WT_DECL_RET;
+ WT_DECL_TIMESTAMP(timestamp)
+ WT_ITEM las_addr, las_key, las_timestamp, las_value;
WT_PAGE *page;
WT_UPDATE *first_upd, *last_upd, *upd;
size_t incr, total_incr;
@@ -154,7 +155,6 @@ __las_page_instantiate(WT_SESSION_IMPL *session,
current_recno = recno = WT_RECNO_OOB;
session_flags = 0; /* [-Werror=maybe-uninitialized] */
WT_CLEAR(las_key);
- WT_CLEAR(las_timestamp);
__wt_btcur_init(session, &cbt);
__wt_btcur_open(&cbt);
@@ -176,6 +176,7 @@ __las_page_instantiate(WT_SESSION_IMPL *session,
*/
las_addr.data = addr;
las_addr.size = addr_size;
+ las_timestamp.size = 0;
cursor->set_key(cursor, read_id, &las_addr,
(uint64_t)0, (uint32_t)0, &las_timestamp, &las_key);
if ((ret = cursor->search_near(cursor, &exact)) == 0 && exact < 0)
@@ -195,13 +196,16 @@ __las_page_instantiate(WT_SESSION_IMPL *session,
/*
* If the on-page value has become globally visible, this record
- * is no longer needed. We clear the las_timestamp structure
- * above to avoid reading uninitialized memory here when
- * timestamps are disabled (even though it is unused in that
- * case).
+ * is no longer needed.
+ *
+ * Copy the timestamp from the cursor to avoid unaligned reads.
*/
+#ifdef HAVE_TIMESTAMPS
+ WT_ASSERT(session, las_timestamp.size == WT_TIMESTAMP_SIZE);
+ memcpy(&timestamp, las_timestamp.data, las_timestamp.size);
+#endif
if (__wt_txn_visible_all(
- session, las_txnid, las_timestamp.data))
+ session, las_txnid, WT_TIMESTAMP_NULL(&timestamp)))
continue;
/* Allocate the WT_UPDATE structure. */
@@ -213,7 +217,7 @@ __las_page_instantiate(WT_SESSION_IMPL *session,
upd->txnid = upd_txnid;
#ifdef HAVE_TIMESTAMPS
WT_ASSERT(session, las_timestamp.size == WT_TIMESTAMP_SIZE);
- __wt_timestamp_set(&upd->timestamp, las_timestamp.data);
+ memcpy(&upd->timestamp, las_timestamp.data, las_timestamp.size);
#endif
switch (page->type) {
diff --git a/src/cache/cache_las.c b/src/cache/cache_las.c
index a118e5d5e41..e1e47b9eecb 100644
--- a/src/cache/cache_las.c
+++ b/src/cache/cache_las.c
@@ -288,9 +288,10 @@ __wt_las_sweep(WT_SESSION_IMPL *session)
{
WT_CONNECTION_IMPL *conn;
WT_CURSOR *cursor;
- WT_ITEM las_addr, las_key, las_timestamp;
WT_DECL_RET;
+ WT_DECL_TIMESTAMP(timestamp)
WT_ITEM *key;
+ WT_ITEM las_addr, las_key, las_timestamp;
uint64_t cnt, las_counter, las_txnid, remove_cnt;
uint32_t las_id, session_flags;
int notused;
@@ -300,7 +301,6 @@ __wt_las_sweep(WT_SESSION_IMPL *session)
key = &conn->las_sweep_key;
remove_cnt = 0;
session_flags = 0; /* [-Werror=maybe-uninitialized] */
- WT_CLEAR(las_timestamp);
__wt_las_cursor(session, &cursor, &session_flags);
@@ -359,6 +359,11 @@ __wt_las_sweep(WT_SESSION_IMPL *session)
session, key, key->data, key->size));
}
+ /*
+ * Cursor opened overwrite=true: won't return WT_NOTFOUND should
+ * another thread remove the record before we do, and the cursor
+ * remains positioned in that case.
+ */
WT_ERR(cursor->get_key(cursor, &las_id, &las_addr, &las_counter,
&las_txnid, &las_timestamp, &las_key));
@@ -366,16 +371,14 @@ __wt_las_sweep(WT_SESSION_IMPL *session)
* If the on-page record transaction ID associated with the
* record is globally visible, the record can be discarded.
*
- * Cursor opened overwrite=true: won't return WT_NOTFOUND should
- * another thread remove the record before we do, and the cursor
- * remains positioned in that case.
- *
- * We clear the las_timestamp structure above to avoid reading
- * uninitialized memory here when timestamps are disabled (even
- * though it is unused in that case).
+ * Copy the timestamp from the cursor to avoid unaligned reads.
*/
+#ifdef HAVE_TIMESTAMPS
+ WT_ASSERT(session, las_timestamp.size == WT_TIMESTAMP_SIZE);
+ memcpy(&timestamp, las_timestamp.data, las_timestamp.size);
+#endif
if (__wt_txn_visible_all(
- session, las_txnid, las_timestamp.data)) {
+ session, las_txnid, WT_TIMESTAMP_NULL(&timestamp))) {
WT_ERR(cursor->remove(cursor));
++remove_cnt;
}