summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2022-08-01 14:08:04 +1000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-08-01 04:38:52 +0000
commit46c3d49e40807e90a9e4b174d70e19f58673acc7 (patch)
treea34c8e750c511609b1baa95a205ed6c0add6437a /src/third_party/wiredtiger
parent927080cb965245721f007de718878dfe07d97b9b (diff)
downloadmongo-46c3d49e40807e90a9e4b174d70e19f58673acc7.tar.gz
Import wiredtiger: b7a5ff00407684aeccc2a374e18df5d2b4a6da2a from branch mongodb-master
ref: 929c31276c..b7a5ff0040 for: 6.1.0-rc0 WT-9592 Fix rollback to stable not clearing the WT_UPDATE_TO_DELETE_FROM_HS flag (#8131)
Diffstat (limited to 'src/third_party/wiredtiger')
-rw-r--r--src/third_party/wiredtiger/dist/api_data.py8
-rw-r--r--src/third_party/wiredtiger/import.data2
-rw-r--r--src/third_party/wiredtiger/src/config/config_def.c5
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_api.c5
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_page.c4
-rw-r--r--src/third_party/wiredtiger/src/history/hs_rec.c3
-rw-r--r--src/third_party/wiredtiger/src/include/connection.h27
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_rollback_to_stable.c17
-rw-r--r--src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c14
-rw-r--r--src/third_party/wiredtiger/test/checkpoint/test_checkpoint.h14
-rwxr-xr-xsrc/third_party/wiredtiger/test/evergreen.yml9
-rw-r--r--src/third_party/wiredtiger/test/format/config.h35
-rwxr-xr-xsrc/third_party/wiredtiger/test/format/config.sh2
-rw-r--r--src/third_party/wiredtiger/test/format/config_def.c3
-rw-r--r--src/third_party/wiredtiger/test/format/wts.c2
-rw-r--r--src/third_party/wiredtiger/test/suite/test_prepare22.py137
-rw-r--r--src/third_party/wiredtiger/test/suite/test_prepare23.py130
17 files changed, 363 insertions, 54 deletions
diff --git a/src/third_party/wiredtiger/dist/api_data.py b/src/third_party/wiredtiger/dist/api_data.py
index 3421c92e282..a3ac5881c0f 100644
--- a/src/third_party/wiredtiger/dist/api_data.py
+++ b/src/third_party/wiredtiger/dist/api_data.py
@@ -782,10 +782,10 @@ connection_runtime_config = [
choices=[
'aggressive_sweep', 'backup_rename', 'checkpoint_evict_page',
'checkpoint_reserved_txnid_delay', 'checkpoint_slow', 'checkpoint_stop', 'compact_slow',
- 'evict_reposition','failpoint_history_store_delete_key_from_ts',
- 'history_store_checkpoint_delay', 'history_store_search', 'history_store_sweep_race',
- 'prepare_checkpoint_delay', 'split_1', 'split_2', 'split_3', 'split_4', 'split_5',
- 'split_6', 'split_7', 'tiered_flush_finish']),
+ 'evict_reposition', 'failpoint_eviction_fail_after_reconciliation',
+ 'failpoint_history_store_delete_key_from_ts', 'history_store_checkpoint_delay',
+ 'history_store_search', 'history_store_sweep_race', 'prepare_checkpoint_delay', 'split_1',
+ 'split_2', 'split_3', 'split_4', 'split_5', 'split_6', 'split_7', 'tiered_flush_finish']),
Config('verbose', '[]', r'''
enable messages for various subsystems and operations. Options are given as a list,
where each message type can optionally define an associated verbosity level, such as
diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data
index ceaae8086ac..06a8fbc3d52 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": "929c31276ce6d64095eca4d00fe82c703618a336"
+ "commit": "b7a5ff00407684aeccc2a374e18df5d2b4a6da2a"
}
diff --git a/src/third_party/wiredtiger/src/config/config_def.c b/src/third_party/wiredtiger/src/config/config_def.c
index b1bf382f603..c360818b7d4 100644
--- a/src/third_party/wiredtiger/src/config/config_def.c
+++ b/src/third_party/wiredtiger/src/config/config_def.c
@@ -157,6 +157,7 @@ static const WT_CONFIG_CHECK confchk_WT_CONNECTION_reconfigure[] = {
"\"checkpoint_evict_page\",\"checkpoint_reserved_txnid_delay\","
"\"checkpoint_slow\",\"checkpoint_stop\",\"compact_slow\","
"\"evict_reposition\","
+ "\"failpoint_eviction_fail_after_reconciliation\","
"\"failpoint_history_store_delete_key_from_ts\","
"\"history_store_checkpoint_delay\",\"history_store_search\","
"\"history_store_sweep_race\",\"prepare_checkpoint_delay\","
@@ -899,6 +900,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open[] = {
"\"checkpoint_evict_page\",\"checkpoint_reserved_txnid_delay\","
"\"checkpoint_slow\",\"checkpoint_stop\",\"compact_slow\","
"\"evict_reposition\","
+ "\"failpoint_eviction_fail_after_reconciliation\","
"\"failpoint_history_store_delete_key_from_ts\","
"\"history_store_checkpoint_delay\",\"history_store_search\","
"\"history_store_sweep_race\",\"prepare_checkpoint_delay\","
@@ -983,6 +985,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_all[] = {
"\"checkpoint_evict_page\",\"checkpoint_reserved_txnid_delay\","
"\"checkpoint_slow\",\"checkpoint_stop\",\"compact_slow\","
"\"evict_reposition\","
+ "\"failpoint_eviction_fail_after_reconciliation\","
"\"failpoint_history_store_delete_key_from_ts\","
"\"history_store_checkpoint_delay\",\"history_store_search\","
"\"history_store_sweep_race\",\"prepare_checkpoint_delay\","
@@ -1065,6 +1068,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_basecfg[] = {
"\"checkpoint_evict_page\",\"checkpoint_reserved_txnid_delay\","
"\"checkpoint_slow\",\"checkpoint_stop\",\"compact_slow\","
"\"evict_reposition\","
+ "\"failpoint_eviction_fail_after_reconciliation\","
"\"failpoint_history_store_delete_key_from_ts\","
"\"history_store_checkpoint_delay\",\"history_store_search\","
"\"history_store_sweep_race\",\"prepare_checkpoint_delay\","
@@ -1145,6 +1149,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_usercfg[] = {
"\"checkpoint_evict_page\",\"checkpoint_reserved_txnid_delay\","
"\"checkpoint_slow\",\"checkpoint_stop\",\"compact_slow\","
"\"evict_reposition\","
+ "\"failpoint_eviction_fail_after_reconciliation\","
"\"failpoint_history_store_delete_key_from_ts\","
"\"history_store_checkpoint_delay\",\"history_store_search\","
"\"history_store_sweep_race\",\"prepare_checkpoint_delay\","
diff --git a/src/third_party/wiredtiger/src/conn/conn_api.c b/src/third_party/wiredtiger/src/conn/conn_api.c
index b17571c5a3c..3da3943e9db 100644
--- a/src/third_party/wiredtiger/src/conn/conn_api.c
+++ b/src/third_party/wiredtiger/src/conn/conn_api.c
@@ -2254,6 +2254,8 @@ __wt_timing_stress_config(WT_SESSION_IMPL *session, const char *cfg[])
{"checkpoint_stop", WT_TIMING_STRESS_CHECKPOINT_STOP},
{"compact_slow", WT_TIMING_STRESS_COMPACT_SLOW},
{"evict_reposition", WT_TIMING_STRESS_EVICT_REPOSITION},
+ {"failpoint_eviction_fail_after_reconciliation",
+ WT_TIMING_STRESS_FAILPOINT_EVICTION_FAIL_AFTER_RECONCILIATION},
{"failpoint_history_delete_key_from_ts",
WT_TIMING_STRESS_FAILPOINT_HISTORY_STORE_DELETE_KEY_FROM_TS},
{"history_store_checkpoint_delay", WT_TIMING_STRESS_HS_CHECKPOINT_DELAY},
@@ -2277,9 +2279,8 @@ __wt_timing_stress_config(WT_SESSION_IMPL *session, const char *cfg[])
flags = 0;
for (ft = stress_types; ft->name != NULL; ft++) {
- if ((ret = __wt_config_subgets(session, &cval, ft->name, &sval)) == 0 && sval.val != 0) {
+ if ((ret = __wt_config_subgets(session, &cval, ft->name, &sval)) == 0 && sval.val != 0)
LF_SET(ft->flag);
- }
WT_RET_NOTFOUND_OK(ret);
}
diff --git a/src/third_party/wiredtiger/src/evict/evict_page.c b/src/third_party/wiredtiger/src/evict/evict_page.c
index 0fa19229aaa..5432890eb77 100644
--- a/src/third_party/wiredtiger/src/evict/evict_page.c
+++ b/src/third_party/wiredtiger/src/evict/evict_page.c
@@ -743,5 +743,9 @@ __evict_review(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t evict_flags, bool
!__wt_page_is_modified(page) || LF_ISSET(WT_REC_HS | WT_REC_IN_MEMORY) ||
WT_IS_METADATA(btree->dhandle));
+ /* Fail 0.1% of the time. */
+ if (__wt_failpoint(session, WT_TIMING_STRESS_FAILPOINT_EVICTION_FAIL_AFTER_RECONCILIATION, 10))
+ return (EBUSY);
+
return (0);
}
diff --git a/src/third_party/wiredtiger/src/history/hs_rec.c b/src/third_party/wiredtiger/src/history/hs_rec.c
index e5312c86355..a3cc090de6d 100644
--- a/src/third_party/wiredtiger/src/history/hs_rec.c
+++ b/src/third_party/wiredtiger/src/history/hs_rec.c
@@ -452,6 +452,9 @@ __wt_hs_insert_updates(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_MULTI *mult
continue;
if (F_ISSET(upd, WT_UPDATE_TO_DELETE_FROM_HS)) {
+ WT_ASSERT_ALWAYS(session, F_ISSET(upd, WT_UPDATE_HS | WT_UPDATE_RESTORED_FROM_HS),
+ "Attempting to remove an update from the history store in WiredTiger, but the "
+ "update was missing.");
if (upd->type == WT_UPDATE_TOMBSTONE)
delete_tombstone = upd;
else {
diff --git a/src/third_party/wiredtiger/src/include/connection.h b/src/third_party/wiredtiger/src/include/connection.h
index 02b421f4191..c97eb1c73aa 100644
--- a/src/third_party/wiredtiger/src/include/connection.h
+++ b/src/third_party/wiredtiger/src/include/connection.h
@@ -587,19 +587,20 @@ struct __wt_connection_impl {
#define WT_TIMING_STRESS_CHECKPOINT_STOP 0x000020u
#define WT_TIMING_STRESS_COMPACT_SLOW 0x000040u
#define WT_TIMING_STRESS_EVICT_REPOSITION 0x000080u
-#define WT_TIMING_STRESS_FAILPOINT_HISTORY_STORE_DELETE_KEY_FROM_TS 0x000100u
-#define WT_TIMING_STRESS_HS_CHECKPOINT_DELAY 0x000200u
-#define WT_TIMING_STRESS_HS_SEARCH 0x000400u
-#define WT_TIMING_STRESS_HS_SWEEP 0x000800u
-#define WT_TIMING_STRESS_PREPARE_CHECKPOINT_DELAY 0x001000u
-#define WT_TIMING_STRESS_SPLIT_1 0x002000u
-#define WT_TIMING_STRESS_SPLIT_2 0x004000u
-#define WT_TIMING_STRESS_SPLIT_3 0x008000u
-#define WT_TIMING_STRESS_SPLIT_4 0x010000u
-#define WT_TIMING_STRESS_SPLIT_5 0x020000u
-#define WT_TIMING_STRESS_SPLIT_6 0x040000u
-#define WT_TIMING_STRESS_SPLIT_7 0x080000u
-#define WT_TIMING_STRESS_TIERED_FLUSH_FINISH 0x100000u
+#define WT_TIMING_STRESS_FAILPOINT_EVICTION_FAIL_AFTER_RECONCILIATION 0x000100u
+#define WT_TIMING_STRESS_FAILPOINT_HISTORY_STORE_DELETE_KEY_FROM_TS 0x000200u
+#define WT_TIMING_STRESS_HS_CHECKPOINT_DELAY 0x000400u
+#define WT_TIMING_STRESS_HS_SEARCH 0x000800u
+#define WT_TIMING_STRESS_HS_SWEEP 0x001000u
+#define WT_TIMING_STRESS_PREPARE_CHECKPOINT_DELAY 0x002000u
+#define WT_TIMING_STRESS_SPLIT_1 0x004000u
+#define WT_TIMING_STRESS_SPLIT_2 0x008000u
+#define WT_TIMING_STRESS_SPLIT_3 0x010000u
+#define WT_TIMING_STRESS_SPLIT_4 0x020000u
+#define WT_TIMING_STRESS_SPLIT_5 0x040000u
+#define WT_TIMING_STRESS_SPLIT_6 0x080000u
+#define WT_TIMING_STRESS_SPLIT_7 0x100000u
+#define WT_TIMING_STRESS_TIERED_FLUSH_FINISH 0x200000u
/* AUTOMATIC FLAG VALUE GENERATION STOP 32 */
uint32_t timing_stress_flags;
diff --git a/src/third_party/wiredtiger/src/txn/txn_rollback_to_stable.c b/src/third_party/wiredtiger/src/txn/txn_rollback_to_stable.c
index b99cd137ebe..9d8fe657a15 100644
--- a/src/third_party/wiredtiger/src/txn/txn_rollback_to_stable.c
+++ b/src/third_party/wiredtiger/src/txn/txn_rollback_to_stable.c
@@ -109,13 +109,12 @@ __rollback_abort_update(WT_SESSION_IMPL *session, WT_ITEM *key, WT_UPDATE *first
}
/*
- * Clear the history store flag for the stable update to indicate that this update should not be
- * written into the history store later, when all the aborted updates are removed from the
- * history store. The next time when this update is moved into the history store, it will have a
- * different stop time point.
+ * Clear the history store flags for the stable update to indicate that this update should be
+ * written to the history store later. The next time when this update is moved into the history
+ * store, it will have a different stop time point.
*/
if (stable_upd != NULL) {
- if (F_ISSET(stable_upd, WT_UPDATE_HS)) {
+ if (F_ISSET(stable_upd, WT_UPDATE_HS | WT_UPDATE_TO_DELETE_FROM_HS)) {
/* Find the update following a stable tombstone. */
if (stable_upd->type == WT_UPDATE_TOMBSTONE) {
tombstone = stable_upd;
@@ -124,7 +123,7 @@ __rollback_abort_update(WT_SESSION_IMPL *session, WT_ITEM *key, WT_UPDATE *first
if (stable_upd->txnid != WT_TXN_ABORTED) {
WT_ASSERT(session,
stable_upd->type != WT_UPDATE_TOMBSTONE &&
- F_ISSET(stable_upd, WT_UPDATE_HS));
+ F_ISSET(stable_upd, WT_UPDATE_HS | WT_UPDATE_TO_DELETE_FROM_HS));
break;
}
}
@@ -140,13 +139,13 @@ __rollback_abort_update(WT_SESSION_IMPL *session, WT_ITEM *key, WT_UPDATE *first
session, key, stable_upd == NULL ? tombstone->start_ts : stable_upd->start_ts));
/*
- * Clear the history store flag for the first stable update. Otherwise, it will not be
+ * Clear the history store flags for the first stable update. Otherwise, it will not be
* moved to history store again.
*/
if (stable_upd != NULL)
- F_CLR(stable_upd, WT_UPDATE_HS);
+ F_CLR(stable_upd, WT_UPDATE_HS | WT_UPDATE_TO_DELETE_FROM_HS);
if (tombstone != NULL)
- F_CLR(tombstone, WT_UPDATE_HS);
+ F_CLR(tombstone, WT_UPDATE_HS | WT_UPDATE_TO_DELETE_FROM_HS);
}
if (stable_update_found != NULL)
*stable_update_found = true;
diff --git a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c
index ff5d7532d4c..b51d9d7de57 100644
--- a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c
+++ b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c
@@ -69,6 +69,7 @@ main(int argc, char *argv[])
g.nworkers = 1;
g.evict_reposition_timing_stress = false;
g.sweep_stress = g.use_timestamps = false;
+ g.failpoint_eviction_fail_after_reconciliation = false;
g.failpoint_hs_delete_key_from_ts = false;
g.hs_checkpoint_timing_stress = g.reserved_txnid_timing_stress = false;
g.checkpoint_slow_timing_stress = false;
@@ -134,6 +135,9 @@ main(int argc, char *argv[])
case '6':
g.evict_reposition_timing_stress = true;
break;
+ case '7':
+ g.failpoint_eviction_fail_after_reconciliation = true;
+ break;
default:
return (usage());
}
@@ -299,12 +303,16 @@ wt_connect(const char *config_open)
progname, fast_eviction ? 5 : 20, fast_eviction ? 1 : 5, g.debug_mode ? DEBUG_MODE_CFG : "",
config_open == NULL ? "" : ",", config_open == NULL ? "" : config_open));
- if (g.evict_reposition_timing_stress || g.sweep_stress || g.failpoint_hs_delete_key_from_ts ||
+ if (g.evict_reposition_timing_stress || g.sweep_stress ||
+ g.failpoint_eviction_fail_after_reconciliation || g.failpoint_hs_delete_key_from_ts ||
g.hs_checkpoint_timing_stress || g.reserved_txnid_timing_stress ||
g.checkpoint_slow_timing_stress) {
- testutil_check(__wt_snprintf(buf, sizeof(buf), ",timing_stress_for_test=[%s%s%s%s%s%s]",
+ testutil_check(__wt_snprintf(buf, sizeof(buf), ",timing_stress_for_test=[%s%s%s%s%s%s%s]",
g.checkpoint_slow_timing_stress ? "checkpoint_slow" : "",
g.evict_reposition_timing_stress ? "evict_reposition" : "",
+ g.failpoint_eviction_fail_after_reconciliation ?
+ "failpoint_eviction_fail_after_reconciliation" :
+ "",
g.failpoint_hs_delete_key_from_ts ? "failpoint_history_store_delete_key_from_ts" : "",
g.hs_checkpoint_timing_stress ? "history_store_checkpoint_delay" : "",
g.reserved_txnid_timing_stress ? "checkpoint_reserved_txnid_delay" : "",
@@ -620,6 +628,8 @@ usage(void)
"\t\t3: hs_checkpoint_timing_stress\n"
"\t\t4: reserved_txnid_timing_stress\n"
"\t\t5: checkpoint_slow_timing_stress\n"
+ "\t\t6: evict_reposition_timing_stress\n"
+ "\t\t7: failpoint_eviction_fail_after_reconciliation\n"
"\t-T specify a table configuration\n"
"\t-t set a file type ( col | mix | row | lsm )\n"
"\t-v verify only\n"
diff --git a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.h b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.h
index 321f4321961..e8d4b6ed925 100644
--- a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.h
+++ b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.h
@@ -74,12 +74,14 @@ typedef struct {
bool reserved_txnid_timing_stress; /* Reserved transaction id timing stress */
bool sweep_stress; /* Sweep stress test */
- uint64_t ts_oldest; /* Current oldest timestamp */
- uint64_t ts_stable; /* Current stable timestamp */
- bool failpoint_hs_delete_key_from_ts; /* Failpoint for hs key deletion. */
- bool no_ts_deletes; /* Run with deletes without timestamps */
- bool prepare; /* Use prepare transactions */
- bool race_timestamps; /* Async update to oldest timestamp */
+ uint64_t ts_oldest; /* Current oldest timestamp */
+ uint64_t ts_stable; /* Current stable timestamp */
+ bool failpoint_eviction_fail_after_reconciliation; /*Fail point for eviction fail after
+ reconciliation. */
+ bool failpoint_hs_delete_key_from_ts; /* Failpoint for hs key deletion. */
+ bool no_ts_deletes; /* Run with deletes without timestamps */
+ bool prepare; /* Use prepare transactions */
+ bool race_timestamps; /* Async update to oldest timestamp */
bool tiered; /* Use tiered storage. Start flush thread */
bool use_timestamps; /* Use txn timestamps. Start clock thread */
diff --git a/src/third_party/wiredtiger/test/evergreen.yml b/src/third_party/wiredtiger/test/evergreen.yml
index 1efc0ebad49..06108937e45 100755
--- a/src/third_party/wiredtiger/test/evergreen.yml
+++ b/src/third_party/wiredtiger/test/evergreen.yml
@@ -2724,6 +2724,14 @@ tasks:
- func: "run data validation stress test checkpoint"
vars:
run_test_checkpoint_args: -x -s 6
+
+ - name: data-validation-stress-test-checkpoint-fp-hs-insert-s7
+ depends_on:
+ - name: compile
+ commands:
+ - func: "run data validation stress test checkpoint"
+ vars:
+ run_test_checkpoint_args: -x -s 7
- name: format-failure-configs-test
depends_on:
@@ -3946,6 +3954,7 @@ buildvariants:
- name: data-validation-stress-test-checkpoint-fp-hs-insert-s5
- name: data-validation-stress-test-checkpoint-fp-hs-insert-s5-no-timestamp
- name: data-validation-stress-test-checkpoint-fp-hs-insert-s6
+ - name: data-validation-stress-test-checkpoint-fp-hs-insert-s7
- name: data-validation-stress-test-checkpoint-no-timestamp
- name: unittest-test
- name: tiered-storage-extensions-test
diff --git a/src/third_party/wiredtiger/test/format/config.h b/src/third_party/wiredtiger/test/format/config.h
index cec8efe6932..aa07f42a9b3 100644
--- a/src/third_party/wiredtiger/test/format/config.h
+++ b/src/third_party/wiredtiger/test/format/config.h
@@ -117,21 +117,22 @@ typedef struct {
#define V_GLOBAL_STRESS_CHECKPOINT_RESERVED_TXNID_DELAY 85
#define V_GLOBAL_STRESS_CHECKPOINT_PREPARE 86
#define V_GLOBAL_STRESS_EVICT_REPOSITION 87
-#define V_GLOBAL_STRESS_FAILPOINT_HS_DELETE_KEY_FROM_TS 88
-#define V_GLOBAL_STRESS_HS_CHECKPOINT_DELAY 89
-#define V_GLOBAL_STRESS_HS_SEARCH 90
-#define V_GLOBAL_STRESS_HS_SWEEP 91
-#define V_GLOBAL_STRESS_SPLIT_1 92
-#define V_GLOBAL_STRESS_SPLIT_2 93
-#define V_GLOBAL_STRESS_SPLIT_3 94
-#define V_GLOBAL_STRESS_SPLIT_4 95
-#define V_GLOBAL_STRESS_SPLIT_5 96
-#define V_GLOBAL_STRESS_SPLIT_6 97
-#define V_GLOBAL_STRESS_SPLIT_7 98
-#define V_GLOBAL_TRANSACTION_IMPLICIT 99
-#define V_GLOBAL_TRANSACTION_TIMESTAMPS 100
-#define V_GLOBAL_WIREDTIGER_CONFIG 101
-#define V_GLOBAL_WIREDTIGER_RWLOCK 102
-#define V_GLOBAL_WIREDTIGER_LEAK_MEMORY 103
+#define V_GLOBAL_STRESS_FAILPOINT_EVICTION_FAIL_AFTER_RECONCILIATION 88
+#define V_GLOBAL_STRESS_FAILPOINT_HS_DELETE_KEY_FROM_TS 89
+#define V_GLOBAL_STRESS_HS_CHECKPOINT_DELAY 90
+#define V_GLOBAL_STRESS_HS_SEARCH 91
+#define V_GLOBAL_STRESS_HS_SWEEP 92
+#define V_GLOBAL_STRESS_SPLIT_1 93
+#define V_GLOBAL_STRESS_SPLIT_2 94
+#define V_GLOBAL_STRESS_SPLIT_3 95
+#define V_GLOBAL_STRESS_SPLIT_4 96
+#define V_GLOBAL_STRESS_SPLIT_5 97
+#define V_GLOBAL_STRESS_SPLIT_6 98
+#define V_GLOBAL_STRESS_SPLIT_7 99
+#define V_GLOBAL_TRANSACTION_IMPLICIT 100
+#define V_GLOBAL_TRANSACTION_TIMESTAMPS 101
+#define V_GLOBAL_WIREDTIGER_CONFIG 102
+#define V_GLOBAL_WIREDTIGER_RWLOCK 103
+#define V_GLOBAL_WIREDTIGER_LEAK_MEMORY 104
-#define V_ELEMENT_COUNT 104
+#define V_ELEMENT_COUNT 105
diff --git a/src/third_party/wiredtiger/test/format/config.sh b/src/third_party/wiredtiger/test/format/config.sh
index 460208d35ab..c742b5c2889 100755
--- a/src/third_party/wiredtiger/test/format/config.sh
+++ b/src/third_party/wiredtiger/test/format/config.sh
@@ -252,6 +252,8 @@ CONFIG configuration_list[] = {
{"stress.evict_reposition", "stress evict reposition", C_BOOL, 2, 0, 0}
+{"stress.failpoint_eviction_fail_after_reconciliation", "stress failpoint eviction fail after reconciliation", C_BOOL, 30, 0, 0}
+
{"stress.failpoint_hs_delete_key_from_ts", "stress failpoint history store delete key from ts", C_BOOL, 30, 0, 0}
{"stress.hs_checkpoint_delay", "stress history store checkpoint delay", C_BOOL, 2, 0, 0}
diff --git a/src/third_party/wiredtiger/test/format/config_def.c b/src/third_party/wiredtiger/test/format/config_def.c
index b84cec197eb..674ea73eb47 100644
--- a/src/third_party/wiredtiger/test/format/config_def.c
+++ b/src/third_party/wiredtiger/test/format/config_def.c
@@ -272,6 +272,9 @@ CONFIG configuration_list[] = {
{"stress.evict_reposition", "stress evict reposition",
C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_EVICT_REPOSITION},
+ {"stress.failpoint_eviction_fail_after_reconciliation", "stress failpoint eviction fail after reconciliation",
+ C_BOOL, 30, 0, 0, V_GLOBAL_STRESS_FAILPOINT_EVICTION_FAIL_AFTER_RECONCILIATION},
+
{"stress.failpoint_hs_delete_key_from_ts", "stress failpoint history store delete key from ts",
C_BOOL, 30, 0, 0, V_GLOBAL_STRESS_FAILPOINT_HS_DELETE_KEY_FROM_TS},
diff --git a/src/third_party/wiredtiger/test/format/wts.c b/src/third_party/wiredtiger/test/format/wts.c
index aea95bcb132..6527f472b72 100644
--- a/src/third_party/wiredtiger/test/format/wts.c
+++ b/src/third_party/wiredtiger/test/format/wts.c
@@ -162,6 +162,8 @@ configure_timing_stress(char **p, size_t max)
CONFIG_APPEND(*p, ",checkpoint_reserved_txnid_delay");
if (GV(STRESS_EVICT_REPOSITION))
CONFIG_APPEND(*p, ",evict_reposition");
+ if (GV(STRESS_FAILPOINT_EVICTION_FAIL_AFTER_RECONCILIATION))
+ CONFIG_APPEND(*p, ",failpoint_eviction_fail_after_reconciliation");
if (GV(STRESS_FAILPOINT_HS_DELETE_KEY_FROM_TS))
CONFIG_APPEND(*p, ",failpoint_history_store_delete_key_from_ts");
if (GV(STRESS_HS_CHECKPOINT_DELAY))
diff --git a/src/third_party/wiredtiger/test/suite/test_prepare22.py b/src/third_party/wiredtiger/test/suite/test_prepare22.py
new file mode 100644
index 00000000000..f35f4a50052
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/test_prepare22.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-present MongoDB, Inc.
+# Public Domain 2008-2014 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+import wiredtiger, wttest
+from wtscenario import make_scenarios
+
+# test_prepare22.py
+# Test prepare with rollback to stable without failed eviction.
+class test_prepare22(wttest.WiredTigerTestCase):
+
+ format_values = [
+ ('column', dict(key_format='r', value_format='S')),
+ ('column_fix', dict(key_format='r', value_format='8t')),
+ ('row_integer', dict(key_format='i', value_format='S')),
+ ]
+
+ delete = [
+ ('delete', dict(delete=True)),
+ ('non-delete', dict(delete=False)),
+ ]
+
+ scenarios = make_scenarios(format_values, delete)
+
+ def test_prepare22(self):
+ uri = "table:test_prepare22"
+ self.session.create(uri, 'key_format=' + self.key_format + ',value_format=' + self.value_format)
+
+ if self.value_format == '8t':
+ value_a = 97
+ value_b = 98
+ value_c = 99
+ else:
+ value_a = "a"
+ value_b = "b"
+ value_c = "c"
+
+ # Pin oldest timestamp to 1
+ self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(1))
+
+ # Do the first update
+ cursor = self.session.open_cursor(uri)
+ self.session.begin_transaction()
+ cursor[1] = value_a
+ self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(10))
+
+ # Do the second update
+ self.session.begin_transaction()
+ cursor[1] = value_b
+ self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(20))
+
+ if self.delete:
+ self.session.begin_transaction()
+ cursor.set_key(1)
+ cursor.remove()
+ self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(30))
+
+ # Do a prepared update
+ self.session.begin_transaction()
+ cursor[1] = value_c
+ self.session.prepare_transaction('prepare_timestamp=' + self.timestamp_str(40))
+
+ # Evict the page
+ session2 = self.conn.open_session()
+ evict_cursor = session2.open_cursor(uri, None, 'debug=(release_evict)')
+ session2.begin_transaction('ignore_prepare=true,read_timestamp=' + self.timestamp_str(20))
+ self.assertEquals(evict_cursor[1], value_b)
+ evict_cursor.reset()
+ evict_cursor.close()
+ session2.rollback_transaction()
+
+ # Ensure the history store is checkpointed
+ session2.checkpoint()
+
+ # Rollback the prepared transaction
+ self.session.rollback_transaction()
+
+ # Set stable timestamp to 30
+ self.conn.set_timestamp('stable_timestamp=' + self.timestamp_str(30))
+
+ # Call rollback to stable
+ self.conn.rollback_to_stable()
+
+ # Evict the page again
+ evict_cursor = session2.open_cursor(uri, None, 'debug=(release_evict)')
+ session2.begin_transaction('read_timestamp=' + self.timestamp_str(20))
+ self.assertEquals(evict_cursor[1], value_b)
+ evict_cursor.reset()
+ evict_cursor.close()
+ session2.rollback_transaction()
+
+ # Verify we can still read back value a
+ self.session.begin_transaction('read_timestamp=' + self.timestamp_str(10))
+ self.assertEquals(cursor[1], value_a)
+ self.session.rollback_transaction()
+
+ # Verify we can still read back value b
+ self.session.begin_transaction('read_timestamp=' + self.timestamp_str(20))
+ self.assertEquals(cursor[1], value_b)
+ self.session.rollback_transaction()
+
+ # Verify we can still read back the deletion
+ if self.delete:
+ self.session.begin_transaction('read_timestamp=' + self.timestamp_str(30))
+ if self.value_format == '8t':
+ self.assertEquals(cursor[1], 0)
+ else:
+ cursor.set_key(1)
+ self.assertEquals(cursor.search(), wiredtiger.WT_NOTFOUND)
+ self.session.rollback_transaction()
+
+if __name__ == '__main__':
+ wttest.run()
diff --git a/src/third_party/wiredtiger/test/suite/test_prepare23.py b/src/third_party/wiredtiger/test/suite/test_prepare23.py
new file mode 100644
index 00000000000..112fc747820
--- /dev/null
+++ b/src/third_party/wiredtiger/test/suite/test_prepare23.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python
+#
+# Public Domain 2014-present MongoDB, Inc.
+# Public Domain 2008-2014 WiredTiger, Inc.
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+import wiredtiger, wttest
+from wtscenario import make_scenarios
+
+# test_prepare23.py
+# Test prepare rollback with rollback to stable and failed eviction.
+class test_prepare23(wttest.WiredTigerTestCase):
+ conn_config = 'timing_stress_for_test=[failpoint_eviction_fail_after_reconciliation]'
+
+ format_values = [
+ ('column', dict(key_format='r', value_format='S')),
+ ('column_fix', dict(key_format='r', value_format='8t')),
+ ('row_integer', dict(key_format='i', value_format='S')),
+ ]
+
+ delete = [
+ ('delete', dict(delete=True)),
+ ('non-delete', dict(delete=False)),
+ ]
+
+ scenarios = make_scenarios(format_values, delete)
+
+ def test_prepare23(self):
+ uri = "table:test_prepare23"
+ self.session.create(uri, 'key_format=' + self.key_format + ',value_format=' + self.value_format)
+
+ if self.value_format == '8t':
+ value_a = 97
+ value_b = 98
+ value_c = 99
+ else:
+ value_a = "a"
+ value_b = "b"
+ value_c = "c"
+
+ # Pin oldest timestamp to 1
+ self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(1))
+
+ cursor = self.session.open_cursor(uri)
+ session2 = self.conn.open_session()
+ evict_cursor = session2.open_cursor(uri, None, 'debug=(release_evict)')
+ ts = 0
+ for i in range (1, 1001):
+ # Do the first update
+ self.session.begin_transaction()
+ cursor[i] = value_a
+ self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(ts + 10))
+
+ # Do the second update
+ self.session.begin_transaction()
+ cursor[i] = value_b
+ self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(ts + 20))
+
+ if self.delete:
+ self.session.begin_transaction()
+ cursor.set_key(i)
+ cursor.remove()
+ self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(ts + 30))
+
+ # Do a prepared update
+ self.session.begin_transaction()
+ cursor[i] = value_c
+ self.session.prepare_transaction('prepare_timestamp=' + self.timestamp_str(ts + 40))
+
+ # Evict the page
+ session2.begin_transaction('ignore_prepare=true,read_timestamp=' + self.timestamp_str(ts + 20))
+ self.assertEquals(evict_cursor[i], value_b)
+ evict_cursor.reset()
+ session2.rollback_transaction()
+
+ # Rollback the prepared transaction
+ self.session.rollback_transaction()
+
+ # Set stable timestamp to 30 * i
+ self.conn.set_timestamp('stable_timestamp=' + self.timestamp_str(ts + 30))
+
+ # Call rollback to stable
+ self.conn.rollback_to_stable()
+
+ # Verify we can still read back value a
+ self.session.begin_transaction('read_timestamp=' + self.timestamp_str(ts + 10))
+ self.assertEquals(cursor[i], value_a)
+ self.session.rollback_transaction()
+
+ # Verify we can still read back value b
+ self.session.begin_transaction('read_timestamp=' + self.timestamp_str(ts + 20))
+ self.assertEquals(cursor[i], value_b)
+ self.session.rollback_transaction()
+
+ # Verify we can still read back the deletion
+ if self.delete:
+ self.session.begin_transaction('read_timestamp=' + self.timestamp_str(ts + 30))
+ if self.value_format == '8t':
+ self.assertEquals(cursor[i], 0)
+ else:
+ cursor.set_key(i)
+ self.assertEquals(cursor.search(), wiredtiger.WT_NOTFOUND)
+ self.session.rollback_transaction()
+
+ ts += 40
+
+if __name__ == '__main__':
+ wttest.run()