summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/btree/row_modify.c
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2019-07-19 17:41:16 +1000
committerLuke Chen <luke.chen@mongodb.com>2019-07-19 17:41:16 +1000
commit1883b014d6be5929082a1ddd5b5b8a6a8f9facef (patch)
treef6940c7e8f3914bd8cbaff9d859aae1a0d9c6eb9 /src/third_party/wiredtiger/src/btree/row_modify.c
parentffdb59938db0dfc8ec48e8b74df7a54d07b3a128 (diff)
downloadmongo-1883b014d6be5929082a1ddd5b5b8a6a8f9facef.tar.gz
Import wiredtiger: 6746e5e700b75903480a57a9d77b72df46dbc944 from branch mongodb-4.2
ref: 3f68638211..6746e5e700 for: 4.3.1 WT-4899 Fix bugs that could allow more than one birthmark in an update chain WT-4900 Implement all_durable timestamp WT-4908 Add verbose failure messages during the metadata recovery phase WT-4930 Fix likely coding errors of error returns after jump to error WT-4931 Fix clang testing in Jenkins Pull Request testing WT-4932 Add logging files to WiredTiger big/little-endian testing WT-4934 Fix and update clang-tidy testing WT-4936 Update clang-scan expected output WT-4937 Fix verify_wt_datafiles.sh to run if no LD_LIBRARY_PATH variable set WT-4939 Fix a test for skipping checkpoints which never returns success WT-4940 Reconciliation should set prepared/uncommitted for each update WT-4943 Fix a bug where uncommitted updates could be discarded
Diffstat (limited to 'src/third_party/wiredtiger/src/btree/row_modify.c')
-rw-r--r--src/third_party/wiredtiger/src/btree/row_modify.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/src/third_party/wiredtiger/src/btree/row_modify.c b/src/third_party/wiredtiger/src/btree/row_modify.c
index 9cd2d4df2c3..efa6433c9b2 100644
--- a/src/third_party/wiredtiger/src/btree/row_modify.c
+++ b/src/third_party/wiredtiger/src/btree/row_modify.c
@@ -308,11 +308,12 @@ __wt_update_alloc(WT_SESSION_IMPL *session, const WT_ITEM *value,
* Check for obsolete updates.
*/
WT_UPDATE *
-__wt_update_obsolete_check(
- WT_SESSION_IMPL *session, WT_PAGE *page, WT_UPDATE *upd)
+__wt_update_obsolete_check(WT_SESSION_IMPL *session,
+ WT_PAGE *page, WT_UPDATE *upd, bool update_accounting)
{
WT_TXN_GLOBAL *txn_global;
- WT_UPDATE *first, *next;
+ WT_UPDATE *first, *next, *prev;
+ size_t size;
uint64_t oldest, stable;
u_int count, upd_seen, upd_unstable;
@@ -333,28 +334,34 @@ __wt_update_obsolete_check(
*
* Only updates with globally visible, self-contained data can terminate
* update chains.
+ *
+ * Birthmarks are a special case: once a birthmark becomes obsolete, it
+ * can be discarded and subsequent reads will see the on-page value (as
+ * expected). Inserting updates into the lookaside table relies on
+ * this behavior to avoid creating update chains with multiple
+ * birthmarks.
*/
- for (first = NULL, count = 0; upd != NULL; upd = upd->next, count++) {
+ for (first = prev = NULL, count = 0;
+ upd != NULL;
+ prev = upd, upd = upd->next, count++) {
if (upd->txnid == WT_TXN_ABORTED)
continue;
- /*
- * If the update isn't visible, it is not obsolete.
- */
++upd_seen;
if (!__wt_txn_upd_visible_all(session, upd)) {
first = NULL;
/*
- * While we're here, also check for the update
- * being kept only for timestamp history to
- * gauge updates being kept due to history.
+ * While we're here, also check for the update being
+ * kept only for timestamp history to gauge updates
+ * being kept due to history.
*/
if (upd->start_ts != WT_TS_NONE &&
upd->start_ts >= oldest &&
upd->start_ts < stable)
++upd_unstable;
- } else if (first == NULL && (WT_UPDATE_DATA_VALUE(upd) ||
- upd->type == WT_UPDATE_BIRTHMARK))
- first = upd;
+ } else if (first == NULL && upd->type == WT_UPDATE_BIRTHMARK)
+ first = prev;
+ else if (first == NULL && WT_UPDATE_DATA_VALUE(upd))
+ first = upd;
}
__wt_cache_update_lookaside_score(session, upd_seen, upd_unstable);
@@ -367,8 +374,19 @@ __wt_update_obsolete_check(
*/
if (first != NULL &&
(next = first->next) != NULL &&
- __wt_atomic_cas_ptr(&first->next, next, NULL))
+ __wt_atomic_cas_ptr(&first->next, next, NULL)) {
+ /*
+ * Decrement the dirty byte count while holding the page lock,
+ * else we can race with checkpoints cleaning a page.
+ */
+ if (update_accounting) {
+ for (size = 0, upd = next; upd != NULL; upd = upd->next)
+ size += WT_UPDATE_MEMSIZE(upd);
+ if (size != 0)
+ __wt_cache_page_inmem_decr(session, page, size);
+ }
return (next);
+ }
/*
* If the list is long, don't retry checks on this page until the