summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/btree/bt_ovfl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/btree/bt_ovfl.c')
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_ovfl.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/src/third_party/wiredtiger/src/btree/bt_ovfl.c b/src/third_party/wiredtiger/src/btree/bt_ovfl.c
index a0b1ff65006..f933245eaef 100644
--- a/src/third_party/wiredtiger/src/btree/bt_ovfl.c
+++ b/src/third_party/wiredtiger/src/btree/bt_ovfl.c
@@ -45,13 +45,15 @@ __ovfl_read(WT_SESSION_IMPL *session,
*/
int
__wt_ovfl_read(WT_SESSION_IMPL *session,
- WT_PAGE *page, WT_CELL_UNPACK *unpack, WT_ITEM *store)
+ WT_PAGE *page, WT_CELL_UNPACK *unpack, WT_ITEM *store, bool *decoded)
{
WT_DECL_RET;
WT_OVFL_TRACK *track;
WT_UPDATE *upd;
size_t i;
+ *decoded = false;
+
/*
* If no page specified, there's no need to lock and there's no cache
* to search, we don't care about WT_CELL_VALUE_OVFL_RM cells.
@@ -78,8 +80,9 @@ __wt_ovfl_read(WT_SESSION_IMPL *session,
break;
}
WT_ASSERT(session, i < track->remove_next);
- store->data = WT_UPDATE_DATA(upd);
+ store->data = upd->data;
store->size = upd->size;
+ *decoded = true;
} else
ret = __ovfl_read(session, unpack->data, unpack->size, store);
__wt_readunlock(session, &S2BT(session)->ovfl_lock);
@@ -147,7 +150,7 @@ __ovfl_cache_append_update(WT_SESSION_IMPL *session, WT_PAGE *page,
/* Read the overflow value. */
WT_RET(__wt_scr_alloc(session, 1024, &tmp));
- WT_ERR(__ovfl_read(session, unpack->data, unpack->size, tmp));
+ WT_ERR(__wt_dsk_cell_data_ref(session, page->type, unpack, tmp));
/*
* Create an update entry with no transaction ID to ensure global
@@ -159,10 +162,23 @@ __ovfl_cache_append_update(WT_SESSION_IMPL *session, WT_PAGE *page,
* involves atomic operations which will act as our barrier. Regardless,
* we update the page footprint as part of this operation, which acts as
* a barrier as well.
+ *
+ * The update transaction ID choice is tricky, to work around an issue
+ * in variable-length column store. Imagine an overflow value with an
+ * RLE greater than 1. We append a copy to the end of an update chain,
+ * but it's possible it's the overflow value for more than one record,
+ * and appending it to the end of one record's update chain means a
+ * subsequent enter of a globally visible value to one of the records
+ * would allow the truncation of the overflow chain that leaves other
+ * records without a value. If appending such an overflow record, set
+ * the transaction ID to the first possible transaction ID. That ID is
+ * old enough to be globally visible, but we can use it as a flag if an
+ * update record cannot be discarded when truncating an update chain.
*/
WT_ERR(__wt_update_alloc(
session, tmp, &append, &size, WT_UPDATE_STANDARD));
- append->txnid = WT_TXN_NONE;
+ append->txnid = page->type == WT_PAGE_COL_VAR &&
+ __wt_cell_rle(unpack) > 1 ? WT_TXN_FIRST : WT_TXN_NONE;
for (upd = upd_list; upd->next != NULL; upd = upd->next)
;
WT_PUBLISH(upd->next, append);