summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2022-06-28 11:40:33 +1000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-06-28 02:10:18 +0000
commita5382fb01bb2d023c80c2eb1af807eca1f145c43 (patch)
tree1958ffe25dcfd72df571cab5e60c4417d6d74b1d
parent6bdcb2bd96e5a58c49aa28e367036b9c94f5c88b (diff)
downloadmongo-a5382fb01bb2d023c80c2eb1af807eca1f145c43.tar.gz
Import wiredtiger: 4a101bb595e70d47dce5333be5a32f3d02f810cc from branch mongodb-master
ref: 5f18c68f3e..4a101bb595 for: 6.1.0-rc0 WT-9417 Update assertions in reconciliation code to be enabled in release builds where appropriate
-rw-r--r--src/third_party/wiredtiger/dist/s_string.ok1
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_discard.c6
-rw-r--r--src/third_party/wiredtiger/src/include/error.h12
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_child.c4
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_col.c2
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_row.c3
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_track.c3
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_visibility.c114
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_write.c46
10 files changed, 114 insertions, 79 deletions
diff --git a/src/third_party/wiredtiger/dist/s_string.ok b/src/third_party/wiredtiger/dist/s_string.ok
index 3377d0354e4..28fb3fe8f76 100644
--- a/src/third_party/wiredtiger/dist/s_string.ok
+++ b/src/third_party/wiredtiger/dist/s_string.ok
@@ -1501,6 +1501,7 @@ tokname
tokstart
toktype
tolower
+tombstoned
toolchain
toplevel
totalsec
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index df4357c933a..aa29dd370c5 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-master",
- "commit": "5f18c68f3e5d57e368192ef715dbd4e80d8316eb"
+ "commit": "4a101bb595e70d47dce5333be5a32f3d02f810cc"
}
diff --git a/src/third_party/wiredtiger/src/btree/bt_discard.c b/src/third_party/wiredtiger/src/btree/bt_discard.c
index 9a0d1f8630c..af5c1c523c9 100644
--- a/src/third_party/wiredtiger/src/btree/bt_discard.c
+++ b/src/third_party/wiredtiger/src/btree/bt_discard.c
@@ -73,9 +73,9 @@ __wt_page_out(WT_SESSION_IMPL *session, WT_PAGE **pagep)
if (F_ISSET(session->dhandle, WT_DHANDLE_DEAD) || F_ISSET(S2C(session), WT_CONN_CLOSING))
__wt_page_modify_clear(session, page);
- /* Assert we never discard a dirty page or a page queue for eviction. */
- WT_ASSERT(session, !__wt_page_is_modified(page));
- WT_ASSERT(session, !F_ISSET_ATOMIC_16(page, WT_PAGE_EVICT_LRU));
+ WT_ASSERT_ALWAYS(session, !__wt_page_is_modified(page), "Attempting to discard dirty page");
+ WT_ASSERT_ALWAYS(session, !F_ISSET_ATOMIC_16(page, WT_PAGE_EVICT_LRU),
+ "Attempting to discard page queued for eviction");
/*
* If a root page split, there may be one or more pages linked from the page; walk the list,
diff --git a/src/third_party/wiredtiger/src/include/error.h b/src/third_party/wiredtiger/src/include/error.h
index a59b0c51c6e..0500f957944 100644
--- a/src/third_party/wiredtiger/src/include/error.h
+++ b/src/third_party/wiredtiger/src/include/error.h
@@ -176,3 +176,15 @@
WT_RET_PANIC(session, v, __VA_ARGS__); \
} while (0)
#endif
+
+/*
+ * WT_ASSERT_ALWAYS
+ * Assert an expression, abort in both diagnostic and release mode if it fails.
+ */
+#define WT_ASSERT_ALWAYS(session, exp, failure_reason) \
+ do { \
+ if (!(exp)) { \
+ __wt_errx(session, "Assertion '%s' failed: %s", #exp, failure_reason); \
+ __wt_abort(session); \
+ } \
+ } while (0)
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_child.c b/src/third_party/wiredtiger/src/reconcile/rec_child.c
index afdf3f5ad78..68ba5a363fd 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_child.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_child.c
@@ -72,7 +72,8 @@ __rec_child_deleted(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_REF *ref,
*/
WT_ORDERED_READ(prepare_state, page_del->prepare_state);
if (prepare_state == WT_PREPARE_INPROGRESS || prepare_state == WT_PREPARE_LOCKED) {
- WT_ASSERT(session, !F_ISSET(r, WT_REC_EVICT));
+ WT_ASSERT_ALWAYS(session, !F_ISSET(r, WT_REC_EVICT),
+ "In progress prepares should never be seen in eviction");
cmsp->state = WT_CHILD_ORIGINAL;
r->leave_dirty = true;
@@ -145,6 +146,7 @@ __wt_rec_child_modify(
switch (r->tested_ref_state = ref->state) {
case WT_REF_DISK:
/* On disk, not modified by definition. */
+ // 9417 IGNORE
WT_ASSERT(session, ref->addr != NULL);
/* DISK pages do not have fast-truncate info. */
WT_ASSERT(session, ref->ft_info.del == NULL);
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_col.c b/src/third_party/wiredtiger/src/reconcile/rec_col.c
index bda288d7b00..cb0474c1036 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_col.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_col.c
@@ -8,6 +8,8 @@
#include "wt_internal.h"
+// 9417 IGNORE asserts in this file. Column store is not related to BF-25011
+
/*
* __rec_col_fix_bulk_insert_split_check --
* Check if a bulk-loaded fixed-length column store page needs to split.
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_row.c b/src/third_party/wiredtiger/src/reconcile/rec_row.c
index 87654b4bb5a..1c73bd6a8b1 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_row.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_row.c
@@ -414,7 +414,8 @@ __wt_rec_row_int(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page)
* information in the address cell, be sure to propagate the original fast-truncate
* information.
*/
- WT_ASSERT(session, cms.state == WT_CHILD_ORIGINAL);
+ WT_ASSERT_ALWAYS(session, cms.state == WT_CHILD_ORIGINAL,
+ "Not propagating the original fast-truncate information");
__wt_cell_unpack_addr(session, page->dsk, ref->addr, vpack);
if (F_ISSET(vpack, WT_CELL_UNPACK_TIME_WINDOW_CLEARED)) {
page_del = vpack->type == WT_CELL_ADDR_DEL ? &vpack->page_del : NULL;
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_track.c b/src/third_party/wiredtiger/src/reconcile/rec_track.c
index 72d2e2388ab..895566584b4 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_track.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_track.c
@@ -336,7 +336,8 @@ __ovfl_reuse_wrapup(WT_SESSION_IMPL *session, WT_PAGE *page)
}
*e = reuse->next[0];
- WT_ASSERT(session, !F_ISSET(reuse, WT_OVFL_REUSE_JUST_ADDED));
+ WT_ASSERT_ALWAYS(session, !F_ISSET(reuse, WT_OVFL_REUSE_JUST_ADDED),
+ "Attempting to reuse dirty overflow record");
if (WT_VERBOSE_ISSET(session, WT_VERB_OVERFLOW))
WT_RET(__ovfl_reuse_verbose(session, page, reuse, "free"));
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_visibility.c b/src/third_party/wiredtiger/src/reconcile/rec_visibility.c
index 9c40e3e5af1..913a0d949fd 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_visibility.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_visibility.c
@@ -18,12 +18,12 @@ __rec_update_save(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, WT_
{
WT_SAVE_UPD *supd;
- /* If nothing is committed, we must restore the update chain. */
- WT_ASSERT(session, onpage_upd != NULL || supd_restore);
- /* We can only write a standard update or a modify to the data store. */
- WT_ASSERT(session,
+ WT_ASSERT_ALWAYS(session, onpage_upd != NULL || supd_restore,
+ "If nothing is committed the update chain must be restored");
+ WT_ASSERT_ALWAYS(session,
onpage_upd == NULL || onpage_upd->type == WT_UPDATE_STANDARD ||
- onpage_upd->type == WT_UPDATE_MODIFY);
+ onpage_upd->type == WT_UPDATE_MODIFY,
+ "Only a standard update or a modify can be written to the data store");
/* For columns, ins is never null, so rip == NULL implies ins != NULL. */
WT_ASSERT(session, rip != NULL || ins != NULL);
@@ -55,8 +55,9 @@ __rec_append_orig_value(
size_t size, total_size;
bool tombstone_globally_visible;
- WT_ASSERT(
- session, upd != NULL && unpack != NULL && unpack->type != WT_CELL_DEL && !unpack->tw.prepare);
+ WT_ASSERT_ALWAYS(session,
+ upd != NULL && unpack != NULL && unpack->type != WT_CELL_DEL && !unpack->tw.prepare,
+ "__rec_append_orig_value requires an onpage, non-prepared update");
append = oldest_upd = tombstone = NULL;
total_size = 0;
@@ -107,7 +108,7 @@ __rec_append_orig_value(
* because we have to do a search for the prepared updates, which can not proceed until eviction
* finishes.
*/
- WT_ASSERT(session, oldest_upd != NULL);
+ WT_ASSERT_ALWAYS(session, oldest_upd != NULL, "No older updates found on update chain");
/*
* Additionally, we need to append a tombstone before the onpage value we're about to append to
@@ -313,7 +314,8 @@ __rec_validate_upd_chain(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_UPDATE *s
* of the selected update.
*/
if (select_tw->stop_ts < select_tw->start_ts) {
- WT_ASSERT(session, select_tw->stop_ts == WT_TS_NONE);
+ WT_ASSERT_ALWAYS(
+ session, select_tw->stop_ts == WT_TS_NONE, "No stop timestamp found for selected update");
WT_STAT_CONN_DATA_INCR(session, cache_eviction_blocked_no_ts_checkpoint_race_2);
return (EBUSY);
}
@@ -337,14 +339,15 @@ __rec_validate_upd_chain(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_UPDATE *s
if (upd->txnid == WT_TXN_ABORTED)
continue;
- /* If we have a prepared update, durable timestamp cannot be out of order. */
- WT_ASSERT(session,
+ WT_ASSERT_ALWAYS(session,
prev_upd->prepare_state == WT_PREPARE_INPROGRESS ||
- prev_upd->start_ts == prev_upd->durable_ts || prev_upd->durable_ts >= upd->durable_ts);
+ prev_upd->start_ts == prev_upd->durable_ts || prev_upd->durable_ts >= upd->durable_ts,
+ "Durable timestamps cannot be out of order for prepared updates");
/* Validate that the updates older than us have older timestamps. */
if (prev_upd->start_ts < upd->start_ts) {
- WT_ASSERT(session, prev_upd->start_ts == WT_TS_NONE);
+ WT_ASSERT_ALWAYS(
+ session, prev_upd->start_ts == WT_TS_NONE, "Previous update missing start timestamp");
WT_STAT_CONN_DATA_INCR(session, cache_eviction_blocked_no_ts_checkpoint_race_4);
return (EBUSY);
}
@@ -376,15 +379,16 @@ __rec_validate_upd_chain(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_UPDATE *s
* reconciliations ondisk value that we will be comparing against.
*/
if (vpack != NULL && !vpack->tw.prepare) {
- /* If we have a prepared update, durable timestamp cannot be out of order. */
- WT_ASSERT(session,
+ WT_ASSERT_ALWAYS(session,
prev_upd->prepare_state == WT_PREPARE_INPROGRESS ||
prev_upd->start_ts == prev_upd->durable_ts ||
- prev_upd->durable_ts >= vpack->tw.durable_start_ts);
- WT_ASSERT(session,
+ prev_upd->durable_ts >= vpack->tw.durable_start_ts,
+ "Durable timestamps cannot be out of order for prepared updates");
+ WT_ASSERT_ALWAYS(session,
prev_upd->prepare_state == WT_PREPARE_INPROGRESS ||
prev_upd->start_ts == prev_upd->durable_ts || !WT_TIME_WINDOW_HAS_STOP(&vpack->tw) ||
- prev_upd->durable_ts >= vpack->tw.durable_stop_ts);
+ prev_upd->durable_ts >= vpack->tw.durable_stop_ts,
+ "Durable timestamps cannot be out of order for prepared updates");
if (prev_upd->start_ts < vpack->tw.start_ts ||
(WT_TIME_WINDOW_HAS_STOP(&vpack->tw) && prev_upd->start_ts < vpack->tw.stop_ts)) {
WT_ASSERT(session, prev_upd->start_ts == WT_TS_NONE);
@@ -433,17 +437,13 @@ __rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_UPDATE *first_upd
wt_timestamp_t max_ts;
uint64_t max_txn, session_txnid, txnid;
bool is_hs_page;
-#ifdef HAVE_DIAGNOSTIC
bool seen_prepare;
-#endif
max_ts = WT_TS_NONE;
max_txn = WT_TXN_NONE;
is_hs_page = F_ISSET(session->dhandle, WT_DHANDLE_HS);
session_txnid = WT_SESSION_TXN_SHARED(session)->id;
-#ifdef HAVE_DIAGNOSTIC
seen_prepare = false;
-#endif
for (upd = first_upd; upd != NULL; upd = upd->next) {
if ((txnid = upd->txnid) == WT_TXN_ABORTED)
@@ -495,7 +495,8 @@ __rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_UPDATE *first_upd
* can't discard the uncommitted updates.
*/
if (upd_select->upd != NULL) {
- WT_ASSERT(session, WT_IS_METADATA(session->dhandle));
+ WT_ASSERT_ALWAYS(session, WT_IS_METADATA(session->dhandle),
+ "Uncommitted update followed by committed update in a non-metadata file");
return (__wt_set_return(session, EBUSY));
}
@@ -507,28 +508,30 @@ __rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_UPDATE *first_upd
/* Ignore prepared updates if it is checkpoint. */
if (upd->prepare_state == WT_PREPARE_LOCKED ||
upd->prepare_state == WT_PREPARE_INPROGRESS) {
- WT_ASSERT(session, upd_select->upd == NULL || upd_select->upd->txnid == upd->txnid);
+ WT_ASSERT_ALWAYS(session,
+ upd_select->upd == NULL || upd_select->upd->txnid == upd->txnid,
+ "Cannot have two different prepared transactions active on the same key");
if (F_ISSET(r, WT_REC_CHECKPOINT)) {
*upd_memsizep += WT_UPDATE_MEMSIZE(upd);
*has_newer_updatesp = true;
if (upd->start_ts > max_ts)
max_ts = upd->start_ts;
-#ifdef HAVE_DIAGNOSTIC
seen_prepare = true;
-#endif
continue;
} else {
/*
* For prepared updates written to the date store in salvage, we write the same
- * prepared value to the date store. If there is still content for that key left in
+ * prepared value to the data store. If there is still content for that key left in
* the history store, rollback to stable will bring it back to the data store.
* Otherwise, it removes the key.
*/
- WT_ASSERT(session,
+ WT_ASSERT_ALWAYS(session,
F_ISSET(r, WT_REC_EVICT) ||
(F_ISSET(r, WT_REC_VISIBILITY_ERR) &&
- F_ISSET(upd, WT_UPDATE_PREPARE_RESTORED_FROM_DS)));
- WT_ASSERT(session, upd->prepare_state == WT_PREPARE_INPROGRESS);
+ F_ISSET(upd, WT_UPDATE_PREPARE_RESTORED_FROM_DS)),
+ "rec_upd_select found an in-progress prepared update");
+ WT_ASSERT_ALWAYS(session, upd->prepare_state == WT_PREPARE_INPROGRESS,
+ "rec_upd_select found an in-progress prepared update");
}
}
@@ -566,10 +569,11 @@ __rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_UPDATE *first_upd
* writes the update that is older than a prepared update or we need to first delete the update
* from the history store.
*/
- WT_ASSERT(session,
+ WT_ASSERT_ALWAYS(session,
upd_select->upd == NULL || !F_ISSET(upd_select->upd, WT_UPDATE_HS) ||
F_ISSET(upd_select->upd, WT_UPDATE_TO_DELETE_FROM_HS) ||
- (!F_ISSET(r, WT_REC_EVICT) && seen_prepare));
+ (!F_ISSET(r, WT_REC_EVICT) && seen_prepare),
+ "Selected update that has already been written to the history store");
return (0);
}
@@ -622,7 +626,8 @@ __rec_fill_tw_from_upd_select(
WT_ASSERT(session, upd->next == NULL || upd->next->txnid != WT_TXN_ABORTED);
upd_select->upd = upd = upd->next;
/* We should not see multiple consecutive tombstones. */
- WT_ASSERT(session, upd == NULL || upd->type != WT_UPDATE_TOMBSTONE);
+ WT_ASSERT_ALWAYS(session, upd == NULL || upd->type != WT_UPDATE_TOMBSTONE,
+ "Consecutive tombstones found on the update chain");
}
}
@@ -630,11 +635,10 @@ __rec_fill_tw_from_upd_select(
/* The beginning of the validity window is the selected update's time point. */
WT_TIME_WINDOW_SET_START(select_tw, upd);
else if (select_tw->stop_ts != WT_TS_NONE || select_tw->stop_txn != WT_TXN_NONE) {
- /* We only have a tombstone on the update list. */
- WT_ASSERT(session, tombstone != NULL);
-
- /* We must have an ondisk value and it can't be a prepared update. */
- WT_ASSERT(session, vpack != NULL && vpack->type != WT_CELL_DEL && !vpack->tw.prepare);
+ WT_ASSERT_ALWAYS(
+ session, tombstone != NULL, "The only contents of the update list is a single tombstone");
+ WT_ASSERT_ALWAYS(session, vpack != NULL && vpack->type != WT_CELL_DEL && !vpack->tw.prepare,
+ "No ondisk values found that are not prepared updates");
/* Move the pointer to the last update on the update chain. */
for (last_upd = tombstone; last_upd->next != NULL; last_upd = last_upd->next)
@@ -664,10 +668,12 @@ __rec_fill_tw_from_upd_select(
* globally visible. In this case, the on page value is not appended. Verify that.
*/
if (last_upd->next != NULL) {
- WT_ASSERT(session,
+ WT_ASSERT_ALWAYS(session,
last_upd->next->txnid == vpack->tw.start_txn &&
last_upd->next->start_ts == vpack->tw.start_ts &&
- last_upd->next->type == WT_UPDATE_STANDARD && last_upd->next->next == NULL);
+ last_upd->next->type == WT_UPDATE_STANDARD && last_upd->next->next == NULL,
+ "Tombstone is globally visible, but the tombstoned update is on the update "
+ "chain");
upd_select->upd = last_upd->next;
WT_TIME_WINDOW_SET_START(select_tw, last_upd->next);
} else {
@@ -679,9 +685,11 @@ __rec_fill_tw_from_upd_select(
* If the tombstone is aborted concurrently, we should still have appended the
* onpage value.
*/
- WT_ASSERT(session,
+ WT_ASSERT_ALWAYS(session,
tombstone->txnid != WT_TXN_ABORTED &&
- __wt_txn_upd_visible_all(session, tombstone) && upd_select->upd == NULL);
+ __wt_txn_upd_visible_all(session, tombstone) && upd_select->upd == NULL,
+ "Tombstone has been aborted, but the previously tombstoned update is not on "
+ "the update chain");
upd_select->upd = tombstone;
}
} else
@@ -689,9 +697,10 @@ __rec_fill_tw_from_upd_select(
* If the tombstone is restored from the disk or history store, it must have already
* been written to the disk image in the previous eviction.
*/
- WT_ASSERT(session,
+ WT_ASSERT_ALWAYS(session,
upd_select->upd == NULL && vpack->tw.durable_stop_ts == tombstone->durable_ts &&
- vpack->tw.stop_txn == tombstone->txnid);
+ vpack->tw.stop_txn == tombstone->txnid,
+ "Tombstone is restored from disk or history store, but is not in the disk image");
}
return (0);
@@ -745,22 +754,24 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W
/* Keep track of the selected update. */
upd = upd_select->upd;
- /* Reconciliation should never see an aborted or reserved update. */
- WT_ASSERT(
- session, upd == NULL || (upd->txnid != WT_TXN_ABORTED && upd->type != WT_UPDATE_RESERVE));
+ WT_ASSERT_ALWAYS(session,
+ upd == NULL || (upd->txnid != WT_TXN_ABORTED && upd->type != WT_UPDATE_RESERVE),
+ "Reconciliation should never see an aborted or reserved update");
/*
* The checkpoint transaction is special. Make sure we never write metadata updates from a
* checkpoint in a concurrent session.
*/
- WT_ASSERT(session,
+ WT_ASSERT_ALWAYS(session,
!WT_IS_METADATA(session->dhandle) || upd == NULL || upd->txnid == WT_TXN_NONE ||
upd->txnid != S2C(session)->txn_global.checkpoint_txn_shared.id ||
- WT_SESSION_IS_CHECKPOINT(session));
+ WT_SESSION_IS_CHECKPOINT(session),
+ "Metadata updates written from a checkpoint in a concurrent session");
/* If all of the updates were aborted, quit. */
if (first_txn_upd == NULL) {
- WT_ASSERT(session, upd == NULL);
+ WT_ASSERT_ALWAYS(session, upd == NULL,
+ "__wt_rec_upd_select has selected an update when none are present on the update chain");
return (0);
}
@@ -874,7 +885,8 @@ __wt_rec_upd_select(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_INSERT *ins, W
/*
* Paranoia: check that we didn't choose an update that has since been rolled back.
*/
- WT_ASSERT(session, upd_select->upd == NULL || upd_select->upd->txnid != WT_TXN_ABORTED);
+ WT_ASSERT_ALWAYS(session, upd_select->upd == NULL || upd_select->upd->txnid != WT_TXN_ABORTED,
+ "Updated selected that has since been rolled back");
/*
* Returning an update means the original on-page value might be lost, and that's a problem if
diff --git a/src/third_party/wiredtiger/src/reconcile/rec_write.c b/src/third_party/wiredtiger/src/reconcile/rec_write.c
index 65a7412e03a..0a6a4e7027b 100644
--- a/src/third_party/wiredtiger/src/reconcile/rec_write.c
+++ b/src/third_party/wiredtiger/src/reconcile/rec_write.c
@@ -51,9 +51,10 @@ __wt_reconcile(WT_SESSION_IMPL *session, WT_REF *ref, WT_SALVAGE_COOKIE *salvage
* doesn't apply to checkpoints: there are (rare) cases where we write data at read-uncommitted
* isolation.
*/
- WT_ASSERT(session,
+ WT_ASSERT_ALWAYS(session,
!LF_ISSET(WT_REC_EVICT) || LF_ISSET(WT_REC_VISIBLE_ALL) ||
- F_ISSET(session->txn, WT_TXN_HAS_SNAPSHOT));
+ F_ISSET(session->txn, WT_TXN_HAS_SNAPSHOT),
+ "Attempting an eviction with transaction visibility and no snapshot");
/* Can't do history store eviction for history store itself or for metadata. */
WT_ASSERT(session,
@@ -222,9 +223,7 @@ __reconcile(WT_SESSION_IMPL *session, WT_REF *ref, WT_SALVAGE_COOKIE *salvage, u
WT_DECL_RET;
WT_PAGE *page;
WT_RECONCILE *r;
-#ifdef HAVE_DIAGNOSTIC
void *addr;
-#endif
btree = S2BT(session);
page = ref->page;
@@ -280,9 +279,7 @@ __reconcile(WT_SESSION_IMPL *session, WT_REF *ref, WT_SALVAGE_COOKIE *salvage, u
F_ISSET(r, WT_REC_CALL_URGENT) && !r->update_used && r->cache_write_restore)
ret = __wt_set_return(session, EBUSY);
-#ifdef HAVE_DIAGNOSTIC
addr = ref->addr;
-#endif
/*
* If we fail the reconciliation prior to calling __rec_write_wrapup then we can clean up our
@@ -292,8 +289,8 @@ __reconcile(WT_SESSION_IMPL *session, WT_REF *ref, WT_SALVAGE_COOKIE *salvage, u
* inserting updates to the history store and then failing can leave us in a bad state.
*/
if (ret != 0) {
- /* Make sure that reconciliation doesn't free the page that has been written to disk. */
- WT_ASSERT(session, addr == NULL || ref->addr != NULL);
+ WT_ASSERT_ALWAYS(session, addr == NULL || ref->addr != NULL,
+ "Reconciliation trying to free the page that has been written to disk");
WT_IGNORE_RET(__rec_write_err(session, r, page));
WT_IGNORE_RET(__reconcile_post_wrapup(session, r, page, flags, page_lockedp));
/*
@@ -408,7 +405,8 @@ __rec_write_page_status(WT_SESSION_IMPL *session, WT_RECONCILE *r)
if (__wt_atomic_cas32(&mod->page_state, WT_PAGE_DIRTY_FIRST, WT_PAGE_CLEAN))
__wt_cache_dirty_decr(session, page);
else
- WT_ASSERT(session, !F_ISSET(r, WT_REC_EVICT));
+ WT_ASSERT_ALWAYS(
+ session, !F_ISSET(r, WT_REC_EVICT), "Page state has been modified during eviction");
}
}
@@ -468,8 +466,10 @@ __rec_root_write(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags)
* There's special error handling required when re-instantiating pages in memory; it's not
* needed here, asserted for safety.
*/
- WT_ASSERT(session, mod->mod_multi[i].supd == NULL);
- WT_ASSERT(session, mod->mod_multi[i].disk_image == NULL);
+ WT_ASSERT_ALWAYS(
+ session, mod->mod_multi[i].supd == NULL, "Applying unnecessary error handling");
+ WT_ASSERT_ALWAYS(
+ session, mod->mod_multi[i].disk_image == NULL, "Applying unnecessary error handling");
WT_ERR(
__wt_multi_to_ref(session, next, &mod->mod_multi[i], &pindex->index[i], NULL, false));
@@ -589,7 +589,8 @@ __rec_init(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags, WT_SALVAGE_COO
r->last_running = ckpt_txn;
}
/* When operating on the history store table, we should never try history store eviction. */
- WT_ASSERT(session, !F_ISSET(btree->dhandle, WT_DHANDLE_HS) || !LF_ISSET(WT_REC_HS));
+ WT_ASSERT_ALWAYS(session, !F_ISSET(btree->dhandle, WT_DHANDLE_HS) || !LF_ISSET(WT_REC_HS),
+ "Attempting history store eviction while operating on the history store table");
/*
* History store table eviction is configured when eviction gets aggressive, adjust the flags
@@ -1538,8 +1539,8 @@ __wt_rec_split_crossing_bnd(WT_SESSION_IMPL *session, WT_RECONCILE *r, size_t ne
WT_RET(__rec_split_row_promote(session, r, &r->cur_ptr->min_key, r->page->type));
WT_TIME_AGGREGATE_COPY(&r->cur_ptr->ta_min, &r->cur_ptr->ta);
- /* Assert we're not re-entering this code. */
- WT_ASSERT(session, r->cur_ptr->min_offset == 0);
+ WT_ASSERT_ALWAYS(
+ session, r->cur_ptr->min_offset == 0, "Trying to re-enter __wt_rec_split_crossing_bnd");
r->cur_ptr->min_offset = WT_PTRDIFF(r->first_free, r->cur_ptr->image.mem);
/* All page boundaries reset the dictionary. */
@@ -1569,7 +1570,7 @@ __rec_split_finish_process_prev(WT_SESSION_IMPL *session, WT_RECONCILE *r)
size_t combined_size, len_to_move;
uint8_t *cur_dsk_start;
- WT_ASSERT(session, r->prev_ptr != NULL);
+ WT_ASSERT_ALWAYS(session, r->prev_ptr != NULL, "Attempting to merge with non-existing chunk");
btree = S2BT(session);
cur_ptr = r->cur_ptr;
@@ -1990,7 +1991,7 @@ __rec_compression_adjust(WT_SESSION_IMPL *session, uint32_t max, size_t compress
* race, minor trickiness so we only read and write the value once.
*/
WT_ORDERED_READ(current, *adjustp);
- WT_ASSERT(session, current >= max);
+ WT_ASSERT_ALWAYS(session, current >= max, "Writing beyond the max page size");
if (compressed_size > max) {
/*
@@ -2119,7 +2120,8 @@ __rec_split_write(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_REC_CHUNK *chunk
* the wrapup code, and we don't have a code path from here to there.)
*/
if (last_block && r->multi_next == 1 && __rec_is_checkpoint(session, r)) {
- WT_ASSERT(session, r->supd_next == 0);
+ WT_ASSERT_ALWAYS(
+ session, r->supd_next == 0, "Attempting to write final block but further updates found");
if (compressed_image == NULL)
r->wrapup_checkpoint = &chunk->image;
@@ -2151,7 +2153,7 @@ __rec_split_write(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_REC_CHUNK *chunk
if (multi->supd_restore)
goto copy_image;
- WT_ASSERT(session, chunk->entries > 0);
+ WT_ASSERT_ALWAYS(session, chunk->entries > 0, "Trying to write an empty chunk");
}
/*
@@ -2504,9 +2506,10 @@ __rec_write_wrapup(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page)
* splits can.
*/
if (F_ISSET(r, WT_REC_IN_MEMORY) || r->multi->supd_restore) {
- WT_ASSERT(session,
+ WT_ASSERT_ALWAYS(session,
F_ISSET(r, WT_REC_IN_MEMORY) ||
- (F_ISSET(r, WT_REC_EVICT) && r->leave_dirty && r->multi->supd_entries != 0));
+ (F_ISSET(r, WT_REC_EVICT) && r->leave_dirty && r->multi->supd_entries != 0),
+ "Attempting a 1-for-1 page swap when there are still updates to write");
goto split;
}
@@ -2623,7 +2626,8 @@ __rec_hs_wrapup(WT_SESSION_IMPL *session, WT_RECONCILE *r)
* Sanity check: Can't insert updates into history store from the history store itself or from
* the metadata file.
*/
- WT_ASSERT(session, !WT_IS_HS(btree->dhandle) && !WT_IS_METADATA(btree->dhandle));
+ WT_ASSERT_ALWAYS(session, !WT_IS_HS(btree->dhandle) && !WT_IS_METADATA(btree->dhandle),
+ "Attempting to write updates from the history store or metadata file into the history store");
/* Flag as unused for non diagnostic builds. */
WT_UNUSED(btree);