diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/btree/bt_ovfl.c')
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_ovfl.c | 24 |
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); |