summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Chen <luke.chen@mongodb.com>2022-12-05 15:46:31 +1100
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-12-05 05:22:18 +0000
commit4eecc7eea204498b1fc179f00bab747b94d85675 (patch)
tree842c4e88a63b56a403c551f35f262e3ee8c057f0
parentb0ec261419c66af4700e5366446007171f79f49d (diff)
downloadmongo-4eecc7eea204498b1fc179f00bab747b94d85675.tar.gz
Import wiredtiger: 29d40146fc78114efd83aa579c5d9c013f0a6016 from branch mongodb-6.0
ref: af07f15ca3..29d40146fc for: 6.0.4 WT-9592 Fix rollback to stable not clearing the WT_UPDATE_TO_DELETE_FROM_HS flag
-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.c5
-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.c21
-rw-r--r--src/third_party/wiredtiger/test/checkpoint/test_checkpoint.h56
-rwxr-xr-xsrc/third_party/wiredtiger/test/evergreen.yml15
-rw-r--r--src/third_party/wiredtiger/test/format/config.h35
-rw-r--r--src/third_party/wiredtiger/test/format/config.sh2
-rw-r--r--src/third_party/wiredtiger/test/format/config_def.c354
-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, 591 insertions, 234 deletions
diff --git a/src/third_party/wiredtiger/dist/api_data.py b/src/third_party/wiredtiger/dist/api_data.py
index e91a54bed72..c0069c39309 100644
--- a/src/third_party/wiredtiger/dist/api_data.py
+++ b/src/third_party/wiredtiger/dist/api_data.py
@@ -858,10 +858,10 @@ connection_runtime_config = [
type='list', undoc=True,
choices=[
'aggressive_sweep', 'backup_rename', 'checkpoint_reserved_txnid_delay', 'checkpoint_slow',
- 'checkpoint_stop', 'compact_slow', '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']),
+ 'checkpoint_stop', 'compact_slow', '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 f8f6117c38b..e04495e5632 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-6.0",
- "commit": "af07f15ca3491e6cb9d278f3afefb93dcc8248ec"
+ "commit": "29d40146fc78114efd83aa579c5d9c013f0a6016"
}
diff --git a/src/third_party/wiredtiger/src/config/config_def.c b/src/third_party/wiredtiger/src/config/config_def.c
index ec45a828928..e8319ff8403 100644
--- a/src/third_party/wiredtiger/src/config/config_def.c
+++ b/src/third_party/wiredtiger/src/config/config_def.c
@@ -160,6 +160,7 @@ static const WT_CONFIG_CHECK confchk_WT_CONNECTION_reconfigure[] = {
"choices=[\"aggressive_sweep\",\"backup_rename\","
"\"checkpoint_reserved_txnid_delay\",\"checkpoint_slow\","
"\"checkpoint_stop\",\"compact_slow\","
+ "\"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\","
@@ -901,6 +902,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open[] = {
"choices=[\"aggressive_sweep\",\"backup_rename\","
"\"checkpoint_reserved_txnid_delay\",\"checkpoint_slow\","
"\"checkpoint_stop\",\"compact_slow\","
+ "\"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\","
@@ -985,6 +987,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_all[] = {
"choices=[\"aggressive_sweep\",\"backup_rename\","
"\"checkpoint_reserved_txnid_delay\",\"checkpoint_slow\","
"\"checkpoint_stop\",\"compact_slow\","
+ "\"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\","
@@ -1067,6 +1070,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_basecfg[] = {
"choices=[\"aggressive_sweep\",\"backup_rename\","
"\"checkpoint_reserved_txnid_delay\",\"checkpoint_slow\","
"\"checkpoint_stop\",\"compact_slow\","
+ "\"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\","
@@ -1147,6 +1151,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_usercfg[] = {
"choices=[\"aggressive_sweep\",\"backup_rename\","
"\"checkpoint_reserved_txnid_delay\",\"checkpoint_slow\","
"\"checkpoint_stop\",\"compact_slow\","
+ "\"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 83df335f041..fdaae9d177f 100644
--- a/src/third_party/wiredtiger/src/conn/conn_api.c
+++ b/src/third_party/wiredtiger/src/conn/conn_api.c
@@ -2244,6 +2244,8 @@ __wt_timing_stress_config(WT_SESSION_IMPL *session, const char *cfg[])
{"checkpoint_slow", WT_TIMING_STRESS_CHECKPOINT_SLOW},
{"checkpoint_stop", WT_TIMING_STRESS_CHECKPOINT_STOP},
{"compact_slow", WT_TIMING_STRESS_COMPACT_SLOW},
+ {"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},
@@ -2267,9 +2269,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 15e2286a429..49dfd1c2e85 100644
--- a/src/third_party/wiredtiger/src/evict/evict_page.c
+++ b/src/third_party/wiredtiger/src/evict/evict_page.c
@@ -708,5 +708,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 2514ec4fa90..c50dd509d5a 100644
--- a/src/third_party/wiredtiger/src/history/hs_rec.c
+++ b/src/third_party/wiredtiger/src/history/hs_rec.c
@@ -468,6 +468,11 @@ __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)) {
+ /*
+ * If we want to remove an update from the history store in WiredTiger, it must be
+ * in history store.
+ */
+ WT_ASSERT(session, F_ISSET(upd, WT_UPDATE_HS | WT_UPDATE_RESTORED_FROM_HS));
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 7926c8bd5e7..45985cc38df 100644
--- a/src/third_party/wiredtiger/src/include/connection.h
+++ b/src/third_party/wiredtiger/src/include/connection.h
@@ -591,19 +591,20 @@ struct __wt_connection_impl {
#define WT_TIMING_STRESS_CHECKPOINT_SLOW 0x00008u
#define WT_TIMING_STRESS_CHECKPOINT_STOP 0x00010u
#define WT_TIMING_STRESS_COMPACT_SLOW 0x00020u
-#define WT_TIMING_STRESS_FAILPOINT_HISTORY_STORE_DELETE_KEY_FROM_TS 0x00040u
-#define WT_TIMING_STRESS_HS_CHECKPOINT_DELAY 0x00080u
-#define WT_TIMING_STRESS_HS_SEARCH 0x00100u
-#define WT_TIMING_STRESS_HS_SWEEP 0x00200u
-#define WT_TIMING_STRESS_PREPARE_CHECKPOINT_DELAY 0x00400u
-#define WT_TIMING_STRESS_SPLIT_1 0x00800u
-#define WT_TIMING_STRESS_SPLIT_2 0x01000u
-#define WT_TIMING_STRESS_SPLIT_3 0x02000u
-#define WT_TIMING_STRESS_SPLIT_4 0x04000u
-#define WT_TIMING_STRESS_SPLIT_5 0x08000u
-#define WT_TIMING_STRESS_SPLIT_6 0x10000u
-#define WT_TIMING_STRESS_SPLIT_7 0x20000u
-#define WT_TIMING_STRESS_TIERED_FLUSH_FINISH 0x40000u
+#define WT_TIMING_STRESS_FAILPOINT_EVICTION_FAIL_AFTER_RECONCILIATION 0x00040u
+#define WT_TIMING_STRESS_FAILPOINT_HISTORY_STORE_DELETE_KEY_FROM_TS 0x00080u
+#define WT_TIMING_STRESS_HS_CHECKPOINT_DELAY 0x00100u
+#define WT_TIMING_STRESS_HS_SEARCH 0x00200u
+#define WT_TIMING_STRESS_HS_SWEEP 0x00400u
+#define WT_TIMING_STRESS_PREPARE_CHECKPOINT_DELAY 0x00800u
+#define WT_TIMING_STRESS_SPLIT_1 0x01000u
+#define WT_TIMING_STRESS_SPLIT_2 0x02000u
+#define WT_TIMING_STRESS_SPLIT_3 0x04000u
+#define WT_TIMING_STRESS_SPLIT_4 0x08000u
+#define WT_TIMING_STRESS_SPLIT_5 0x10000u
+#define WT_TIMING_STRESS_SPLIT_6 0x20000u
+#define WT_TIMING_STRESS_SPLIT_7 0x40000u
+#define WT_TIMING_STRESS_TIERED_FLUSH_FINISH 0x80000u
/* AUTOMATIC FLAG VALUE GENERATION STOP 64 */
uint64_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 35436e03947..fba7c1e7cb9 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
@@ -119,13 +119,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;
@@ -134,7 +133,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;
}
}
@@ -150,13 +149,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 cc6964d7db3..8a8d142c021 100644
--- a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c
+++ b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c
@@ -68,6 +68,7 @@ main(int argc, char *argv[])
g.ntables = 3;
g.nworkers = 1;
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;
@@ -127,8 +128,12 @@ main(int argc, char *argv[])
case '5':
g.checkpoint_slow_timing_stress = true;
break;
+ case '7':
+ g.failpoint_eviction_fail_after_reconciliation = true;
+ break;
default:
return (usage());
+ break;
}
break;
case 't':
@@ -273,7 +278,10 @@ wt_connect(const char *config_open)
g.reserved_txnid_timing_stress || g.checkpoint_slow_timing_stress) {
timing_stress = true;
testutil_check(__wt_snprintf(timing_stress_config, sizeof(timing_stress_config),
- ",timing_stress_for_test=[%s%s%s%s%s]", g.sweep_stress ? "aggressive_sweep" : "",
+ ",timing_stress_for_test=[%s%s%s%s%s%s]", g.sweep_stress ? "aggressive_sweep" : "",
+ 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" : "",
@@ -292,8 +300,10 @@ wt_connect(const char *config_open)
*/
if (g.sweep_stress)
testutil_check(__wt_snprintf(config, sizeof(config),
- "create,cache_cursors=false,statistics=(fast),statistics_log=(json,wait=1),error_prefix="
- "\"%s\",file_manager=(close_handle_minimum=1,close_idle_time=1,close_scan_interval=1),"
+ "create,cache_cursors=false,statistics=(fast),statistics_log=(json,wait=1),error_"
+ "prefix="
+ "\"%s\",file_manager=(close_handle_minimum=1,close_idle_time=1,close_scan_interval=1)"
+ ","
"log=(enabled),cache_size=1GB, eviction_dirty_trigger=%i, "
"eviction_dirty_target=%i,%s%s%s%s",
progname, fast_eviction ? 5 : 20, fast_eviction ? 1 : 5, timing_stress_config,
@@ -301,7 +311,8 @@ wt_connect(const char *config_open)
config_open == NULL ? "" : config_open));
else
testutil_check(__wt_snprintf(config, sizeof(config),
- "create,cache_cursors=false,statistics=(fast),statistics_log=(json,wait=1),log=(enabled),"
+ "create,cache_cursors=false,statistics=(fast),statistics_log=(json,wait=1),log=("
+ "enabled),"
"error_prefix=\"%s\",cache_size=1G, eviction_dirty_trigger=%i, "
"eviction_dirty_target=%i,%s%s%s%s",
progname, fast_eviction ? 5 : 20, fast_eviction ? 1 : 5,
@@ -589,6 +600,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 1d8bd72ab0c..ece2be67b1e 100644
--- a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.h
+++ b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.h
@@ -55,33 +55,35 @@ typedef struct {
} COOKIE;
typedef struct {
- char *home; /* Home directory */
- const char *checkpoint_name; /* Checkpoint name */
- WT_CONNECTION *conn; /* WiredTiger connection */
- bool debug_mode; /* History store stress test */
- u_int nkeys; /* Keys to load */
- u_int nops; /* Operations per thread */
- FILE *logfp; /* Message log file. */
- int nworkers; /* Number workers configured */
- int ntables; /* Number tables configured */
- int ntables_created; /* Number tables opened */
- volatile int running; /* Whether to stop */
- int status; /* Exit status */
- bool sweep_stress; /* Sweep stress test */
- bool failpoint_hs_delete_key_from_ts; /* Failpoint for hs key deletion. */
- bool hs_checkpoint_timing_stress; /* History store checkpoint timing stress */
- bool reserved_txnid_timing_stress; /* Reserved transaction id timing stress */
- bool checkpoint_slow_timing_stress; /* Checkpoint slow timing stress */
- uint64_t ts_oldest; /* Current oldest timestamp */
- uint64_t ts_stable; /* Current stable timestamp */
- bool mixed_mode_deletes; /* Run with mixed mode deletes */
- bool use_timestamps; /* Use txn timestamps */
- bool race_timestamps; /* Async update to oldest timestamp */
- bool prepare; /* Use prepare transactions */
- COOKIE *cookies; /* Per-thread info */
- WT_RWLOCK clock_lock; /* Clock synchronization */
- wt_thread_t checkpoint_thread; /* Checkpoint thread */
- wt_thread_t clock_thread; /* Clock thread */
+ char *home; /* Home directory */
+ const char *checkpoint_name; /* Checkpoint name */
+ WT_CONNECTION *conn; /* WiredTiger connection */
+ bool debug_mode; /* History store stress test */
+ u_int nkeys; /* Keys to load */
+ u_int nops; /* Operations per thread */
+ FILE *logfp; /* Message log file. */
+ int nworkers; /* Number workers configured */
+ int ntables; /* Number tables configured */
+ int ntables_created; /* Number tables opened */
+ volatile int running; /* Whether to stop */
+ int status; /* Exit status */
+ bool sweep_stress; /* Sweep stress test */
+ bool failpoint_hs_delete_key_from_ts; /* Failpoint for hs key deletion. */
+ bool hs_checkpoint_timing_stress; /* History store checkpoint timing stress */
+ bool reserved_txnid_timing_stress; /* Reserved transaction id timing stress */
+ bool checkpoint_slow_timing_stress; /* Checkpoint slow timing stress */
+ 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 mixed_mode_deletes; /* Run with mixed mode deletes */
+ bool use_timestamps; /* Use txn timestamps */
+ bool race_timestamps; /* Async update to oldest timestamp */
+ bool prepare; /* Use prepare transactions */
+ COOKIE *cookies; /* Per-thread info */
+ WT_RWLOCK clock_lock; /* Clock synchronization */
+ wt_thread_t checkpoint_thread; /* Checkpoint thread */
+ wt_thread_t clock_thread; /* Clock thread */
} GLOBAL;
extern GLOBAL g;
diff --git a/src/third_party/wiredtiger/test/evergreen.yml b/src/third_party/wiredtiger/test/evergreen.yml
index 1eb0ac2ae5e..cd28c788dbf 100755
--- a/src/third_party/wiredtiger/test/evergreen.yml
+++ b/src/third_party/wiredtiger/test/evergreen.yml
@@ -2538,6 +2538,20 @@ tasks:
set -o errexit
set -o verbose
${test_env_vars|} ../../../tools/run_parallel.sh 'nice ./recovery-test.sh "${data_validation_stress_test_args} -s 5" WT_TEST.$t test_checkpoint' 120
+
+ - name: data-validation-stress-test-checkpoint-fp-hs-insert-s7
+ depends_on:
+ - name: compile
+ commands:
+ - func: "fetch artifacts"
+ - command: shell.exec
+ params:
+ working_dir: "wiredtiger/cmake_build/test/checkpoint"
+ shell: bash
+ script: |
+ set -o errexit
+ set -o verbose
+ ${test_env_vars|} ../../../tools/run_parallel.sh 'nice ./recovery-test.sh "${data_validation_stress_test_args} -s 7" WT_TEST.$t test_checkpoint' 120
- name: format-failure-configs-test
depends_on:
@@ -3727,6 +3741,7 @@ buildvariants:
- name: data-validation-stress-test-checkpoint-fp-hs-insert-s4
- 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-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 14fb612d31d..fc803cb4790 100644
--- a/src/third_party/wiredtiger/test/format/config.h
+++ b/src/third_party/wiredtiger/test/format/config.h
@@ -115,21 +115,22 @@ typedef struct {
#define V_GLOBAL_STRESS_CHECKPOINT 83
#define V_GLOBAL_STRESS_CHECKPOINT_RESERVED_TXNID_DELAY 84
#define V_GLOBAL_STRESS_CHECKPOINT_PREPARE 85
-#define V_GLOBAL_STRESS_FAILPOINT_HS_DELETE_KEY_FROM_TS 86
-#define V_GLOBAL_STRESS_HS_CHECKPOINT_DELAY 87
-#define V_GLOBAL_STRESS_HS_SEARCH 88
-#define V_GLOBAL_STRESS_HS_SWEEP 89
-#define V_GLOBAL_STRESS_SPLIT_1 90
-#define V_GLOBAL_STRESS_SPLIT_2 91
-#define V_GLOBAL_STRESS_SPLIT_3 92
-#define V_GLOBAL_STRESS_SPLIT_4 93
-#define V_GLOBAL_STRESS_SPLIT_5 94
-#define V_GLOBAL_STRESS_SPLIT_6 95
-#define V_GLOBAL_STRESS_SPLIT_7 96
-#define V_GLOBAL_TRANSACTION_IMPLICIT 97
-#define V_GLOBAL_TRANSACTION_TIMESTAMPS 98
-#define V_GLOBAL_WIREDTIGER_CONFIG 99
-#define V_GLOBAL_WIREDTIGER_RWLOCK 100
-#define V_GLOBAL_WIREDTIGER_LEAK_MEMORY 101
+#define V_GLOBAL_STRESS_FAILPOINT_EVICTION_FAIL_AFTER_RECONCILIATION 86
+#define V_GLOBAL_STRESS_FAILPOINT_HS_DELETE_KEY_FROM_TS 87
+#define V_GLOBAL_STRESS_HS_CHECKPOINT_DELAY 88
+#define V_GLOBAL_STRESS_HS_SEARCH 89
+#define V_GLOBAL_STRESS_HS_SWEEP 90
+#define V_GLOBAL_STRESS_SPLIT_1 91
+#define V_GLOBAL_STRESS_SPLIT_2 92
+#define V_GLOBAL_STRESS_SPLIT_3 93
+#define V_GLOBAL_STRESS_SPLIT_4 94
+#define V_GLOBAL_STRESS_SPLIT_5 95
+#define V_GLOBAL_STRESS_SPLIT_6 96
+#define V_GLOBAL_STRESS_SPLIT_7 97
+#define V_GLOBAL_TRANSACTION_IMPLICIT 98
+#define V_GLOBAL_TRANSACTION_TIMESTAMPS 99
+#define V_GLOBAL_WIREDTIGER_CONFIG 100
+#define V_GLOBAL_WIREDTIGER_RWLOCK 101
+#define V_GLOBAL_WIREDTIGER_LEAK_MEMORY 102
-#define V_ELEMENT_COUNT 102
+#define V_ELEMENT_COUNT 103
diff --git a/src/third_party/wiredtiger/test/format/config.sh b/src/third_party/wiredtiger/test/format/config.sh
index 23af56e2724..97aaacbe88d 100644
--- a/src/third_party/wiredtiger/test/format/config.sh
+++ b/src/third_party/wiredtiger/test/format/config.sh
@@ -248,6 +248,8 @@ CONFIG configuration_list[] = {
{"stress.checkpoint_prepare", "stress checkpoint prepare", 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 78613c1c1ab..628cddff6a8 100644
--- a/src/third_party/wiredtiger/test/format/config_def.c
+++ b/src/third_party/wiredtiger/test/format/config_def.c
@@ -2,32 +2,36 @@
#include "format.h"
-CONFIG configuration_list[] = {{"assert.read_timestamp", "assert read_timestamp", C_BOOL, 2, 0, 0,
- V_GLOBAL_ASSERT_READ_TIMESTAMP},
+CONFIG configuration_list[] = {
+ {"assert.read_timestamp", "assert read_timestamp",
+ C_BOOL, 2, 0, 0, V_GLOBAL_ASSERT_READ_TIMESTAMP},
- {"assert.write_timestamp", "set write_timestamp_usage and assert write_timestamp", C_BOOL, 2, 0,
- 0, V_GLOBAL_ASSERT_WRITE_TIMESTAMP},
+ {"assert.write_timestamp", "set write_timestamp_usage and assert write_timestamp",
+ C_BOOL, 2, 0, 0, V_GLOBAL_ASSERT_WRITE_TIMESTAMP},
- {"backup", "configure backups", C_BOOL, 20, 0, 0, V_GLOBAL_BACKUP},
+ {"backup", "configure backups",
+ C_BOOL, 20, 0, 0, V_GLOBAL_BACKUP},
- {"backup.incremental", "backup type (off | block | log)", C_IGNORE | C_STRING, 0, 0, 0,
- V_GLOBAL_BACKUP_INCREMENTAL},
+ {"backup.incremental", "backup type (off | block | log)",
+ C_IGNORE | C_STRING, 0, 0, 0, V_GLOBAL_BACKUP_INCREMENTAL},
- {"backup.incr_granularity", "incremental backup block granularity (KB)", 0x0, 4, 16384, 16384,
- V_GLOBAL_BACKUP_INCR_GRANULARITY},
+ {"backup.incr_granularity", "incremental backup block granularity (KB)",
+ 0x0, 4, 16384, 16384, V_GLOBAL_BACKUP_INCR_GRANULARITY},
- {"block_cache", "enable the block cache", C_BOOL, 10, 0, 0, V_GLOBAL_BLOCK_CACHE},
+ {"block_cache", "enable the block cache",
+ C_BOOL, 10, 0, 0, V_GLOBAL_BLOCK_CACHE},
- {"block_cache.cache_on_checkpoint", "block cache: cache checkpoint writes", C_BOOL, 30, 0, 0,
- V_GLOBAL_BLOCK_CACHE_CACHE_ON_CHECKPOINT},
+ {"block_cache.cache_on_checkpoint", "block cache: cache checkpoint writes",
+ C_BOOL, 30, 0, 0, V_GLOBAL_BLOCK_CACHE_CACHE_ON_CHECKPOINT},
- {"block_cache.cache_on_writes", "block cache: populate the cache on writes", C_BOOL, 60, 0, 0,
- V_GLOBAL_BLOCK_CACHE_CACHE_ON_WRITES},
+ {"block_cache.cache_on_writes", "block cache: populate the cache on writes",
+ C_BOOL, 60, 0, 0, V_GLOBAL_BLOCK_CACHE_CACHE_ON_WRITES},
- {"block_cache.size", "block cache size (MB)", 0x0, 1, 100, 100 * 1024, V_GLOBAL_BLOCK_CACHE_SIZE},
+ {"block_cache.size", "block cache size (MB)",
+ 0x0, 1, 100, 100 * 1024, V_GLOBAL_BLOCK_CACHE_SIZE},
- {"btree.bitcnt", "fixed-length column-store object size (number of bits)", C_TABLE | C_TYPE_FIX,
- 1, 8, 8, V_TABLE_BTREE_BITCNT},
+ {"btree.bitcnt", "fixed-length column-store object size (number of bits)",
+ C_TABLE | C_TYPE_FIX, 1, 8, 8, V_TABLE_BTREE_BITCNT},
{"btree.compression", "data compression (off | lz4 | snappy | zlib | zstd)",
C_IGNORE | C_STRING | C_TABLE, 0, 0, 0, V_TABLE_BTREE_COMPRESSION},
@@ -38,244 +42,280 @@ CONFIG configuration_list[] = {{"assert.read_timestamp", "assert read_timestamp"
{"btree.huffman_value", "configure huffman encoded values",
C_BOOL | C_TABLE | C_TYPE_ROW | C_TYPE_VAR, 20, 0, 0, V_TABLE_BTREE_HUFFMAN_VALUE},
- {"btree.internal_key_truncation", "truncate internal keys", C_BOOL | C_TABLE, 95, 0, 0,
- V_TABLE_BTREE_INTERNAL_KEY_TRUNCATION},
+ {"btree.internal_key_truncation", "truncate internal keys",
+ C_BOOL | C_TABLE, 95, 0, 0, V_TABLE_BTREE_INTERNAL_KEY_TRUNCATION},
- {"btree.internal_page_max", "btree internal node maximum size", C_TABLE, 9, 17, 27,
- V_TABLE_BTREE_INTERNAL_PAGE_MAX},
+ {"btree.internal_page_max", "btree internal node maximum size",
+ C_TABLE, 9, 17, 27, V_TABLE_BTREE_INTERNAL_PAGE_MAX},
- {"btree.key_max", "maximum key size", C_TABLE | C_TYPE_ROW, 20, 128, MEGABYTE(10),
- V_TABLE_BTREE_KEY_MAX},
+ {"btree.key_max", "maximum key size",
+ C_TABLE | C_TYPE_ROW, 20, 128, MEGABYTE(10), V_TABLE_BTREE_KEY_MAX},
- {"btree.key_min", "minimum key size", C_TABLE | C_TYPE_ROW, KEY_LEN_CONFIG_MIN, 32, 256,
- V_TABLE_BTREE_KEY_MIN},
+ {"btree.key_min", "minimum key size",
+ C_TABLE | C_TYPE_ROW, KEY_LEN_CONFIG_MIN, 32, 256, V_TABLE_BTREE_KEY_MIN},
- {"btree.leaf_page_max", "btree leaf node maximum size", C_TABLE, 9, 17, 27,
- V_TABLE_BTREE_LEAF_PAGE_MAX},
+ {"btree.leaf_page_max", "btree leaf node maximum size",
+ C_TABLE, 9, 17, 27, V_TABLE_BTREE_LEAF_PAGE_MAX},
- {"btree.memory_page_max", "maximum cache page size", C_TABLE, 1, 10, 128,
- V_TABLE_BTREE_MEMORY_PAGE_MAX},
+ {"btree.memory_page_max", "maximum cache page size",
+ C_TABLE, 1, 10, 128, V_TABLE_BTREE_MEMORY_PAGE_MAX},
- {"btree.prefix_len", "common key prefix", C_TABLE | C_TYPE_ROW | C_ZERO_NOTSET,
- PREFIX_LEN_CONFIG_MIN, PREFIX_LEN_CONFIG_MAX, PREFIX_LEN_CONFIG_MAX, V_TABLE_BTREE_PREFIX_LEN},
+ {"btree.prefix_len", "common key prefix",
+ C_TABLE | C_TYPE_ROW | C_ZERO_NOTSET, PREFIX_LEN_CONFIG_MIN, PREFIX_LEN_CONFIG_MAX, PREFIX_LEN_CONFIG_MAX, V_TABLE_BTREE_PREFIX_LEN},
- {"btree.prefix_compression", "configure prefix compressed keys", C_BOOL | C_TABLE | C_TYPE_ROW,
- 80, 0, 0, V_TABLE_BTREE_PREFIX_COMPRESSION},
+ {"btree.prefix_compression", "configure prefix compressed keys",
+ C_BOOL | C_TABLE | C_TYPE_ROW, 80, 0, 0, V_TABLE_BTREE_PREFIX_COMPRESSION},
{"btree.prefix_compression_min", "minimum gain before prefix compression is used (bytes)",
C_TABLE | C_TYPE_ROW, 0, 8, 256, V_TABLE_BTREE_PREFIX_COMPRESSION_MIN},
- {"btree.repeat_data_pct", "duplicate values (percentage)", C_TABLE | C_TYPE_VAR, 0, 90, 90,
- V_TABLE_BTREE_REPEAT_DATA_PCT},
+ {"btree.repeat_data_pct", "duplicate values (percentage)",
+ C_TABLE | C_TYPE_VAR, 0, 90, 90, V_TABLE_BTREE_REPEAT_DATA_PCT},
- {"btree.reverse", "reverse order collation", C_BOOL | C_TABLE | C_TYPE_ROW, 10, 0, 0,
- V_TABLE_BTREE_REVERSE},
+ {"btree.reverse", "reverse order collation",
+ C_BOOL | C_TABLE | C_TYPE_ROW, 10, 0, 0, V_TABLE_BTREE_REVERSE},
- {"btree.split_pct", "page split size as a percentage of the maximum page size", C_TABLE, 50, 100,
- 100, V_TABLE_BTREE_SPLIT_PCT},
+ {"btree.split_pct", "page split size as a percentage of the maximum page size",
+ C_TABLE, 50, 100, 100, V_TABLE_BTREE_SPLIT_PCT},
- {"btree.value_max", "maximum value size", C_TABLE | C_TYPE_ROW | C_TYPE_VAR, 32, 4096,
- MEGABYTE(10), V_TABLE_BTREE_VALUE_MAX},
+ {"btree.value_max", "maximum value size",
+ C_TABLE | C_TYPE_ROW | C_TYPE_VAR, 32, 4096, MEGABYTE(10), V_TABLE_BTREE_VALUE_MAX},
- {"btree.value_min", "minimum value size", C_TABLE | C_TYPE_ROW | C_TYPE_VAR, 0, 20, 4096,
- V_TABLE_BTREE_VALUE_MIN},
+ {"btree.value_min", "minimum value size",
+ C_TABLE | C_TYPE_ROW | C_TYPE_VAR, 0, 20, 4096, V_TABLE_BTREE_VALUE_MIN},
- {"cache", "cache size (MB)", 0x0, 1, 100, 100 * 1024, V_GLOBAL_CACHE},
+ {"cache", "cache size (MB)",
+ 0x0, 1, 100, 100 * 1024, V_GLOBAL_CACHE},
- {"cache.evict_max", "maximum number of eviction workers", 0x0, 0, 5, 100,
- V_GLOBAL_CACHE_EVICT_MAX},
+ {"cache.evict_max", "maximum number of eviction workers",
+ 0x0, 0, 5, 100, V_GLOBAL_CACHE_EVICT_MAX},
- {"cache.minimum", "minimum cache size (MB)", C_IGNORE, 0, 0, 100 * 1024, V_GLOBAL_CACHE_MINIMUM},
+ {"cache.minimum", "minimum cache size (MB)",
+ C_IGNORE, 0, 0, 100 * 1024, V_GLOBAL_CACHE_MINIMUM},
- {"checkpoint", "checkpoint type (on | off | wiredtiger)", C_IGNORE | C_STRING, 0, 0, 0,
- V_GLOBAL_CHECKPOINT},
+ {"checkpoint", "checkpoint type (on | off | wiredtiger)",
+ C_IGNORE | C_STRING, 0, 0, 0, V_GLOBAL_CHECKPOINT},
- {"checkpoint.log_size", "MB of log to wait if wiredtiger checkpoints configured", 0x0, 20, 200,
- 1024, V_GLOBAL_CHECKPOINT_LOG_SIZE},
+ {"checkpoint.log_size", "MB of log to wait if wiredtiger checkpoints configured",
+ 0x0, 20, 200, 1024, V_GLOBAL_CHECKPOINT_LOG_SIZE},
- {"checkpoint.wait", "seconds to wait if wiredtiger checkpoints configured", 0x0, 5, 100, 3600,
- V_GLOBAL_CHECKPOINT_WAIT},
+ {"checkpoint.wait", "seconds to wait if wiredtiger checkpoints configured",
+ 0x0, 5, 100, 3600, V_GLOBAL_CHECKPOINT_WAIT},
{"disk.checksum", "checksum type (on | off | uncompressed | unencrypted)",
C_IGNORE | C_STRING | C_TABLE, 0, 0, 0, V_TABLE_DISK_CHECKSUM},
- {"disk.data_extend", "configure data file extension", C_BOOL, 5, 0, 0, V_GLOBAL_DISK_DATA_EXTEND},
+ {"disk.data_extend", "configure data file extension",
+ C_BOOL, 5, 0, 0, V_GLOBAL_DISK_DATA_EXTEND},
- {"disk.direct_io", "configure direct I/O for data objects", C_BOOL | C_IGNORE, 0, 0, 1,
- V_GLOBAL_DISK_DIRECT_IO},
+ {"disk.direct_io", "configure direct I/O for data objects",
+ C_BOOL | C_IGNORE, 0, 0, 1, V_GLOBAL_DISK_DIRECT_IO},
- {"disk.encryption", "encryption type (off | rotn-7)", C_IGNORE | C_STRING, 0, 0, 0,
- V_GLOBAL_DISK_ENCRYPTION},
+ {"disk.encryption", "encryption type (off | rotn-7)",
+ C_IGNORE | C_STRING, 0, 0, 0, V_GLOBAL_DISK_ENCRYPTION},
- {"disk.firstfit", "configure first-fit allocation", C_BOOL | C_TABLE, 10, 0, 0,
- V_TABLE_DISK_FIRSTFIT},
+ {"disk.firstfit", "configure first-fit allocation",
+ C_BOOL | C_TABLE, 10, 0, 0, V_TABLE_DISK_FIRSTFIT},
- {"disk.mmap", "configure mmap operations (reads only)", C_BOOL, 90, 0, 0, V_GLOBAL_DISK_MMAP},
+ {"disk.mmap", "configure mmap operations (reads only)",
+ C_BOOL, 90, 0, 0, V_GLOBAL_DISK_MMAP},
- {"disk.mmap_all", "configure mmap operations (read and write)", C_BOOL, 5, 0, 0,
- V_GLOBAL_DISK_MMAP_ALL},
+ {"disk.mmap_all", "configure mmap operations (read and write)",
+ C_BOOL, 5, 0, 0, V_GLOBAL_DISK_MMAP_ALL},
- {"format.abort", "drop core during timed run", C_BOOL, 0, 0, 0, V_GLOBAL_FORMAT_ABORT},
+ {"format.abort", "drop core during timed run",
+ C_BOOL, 0, 0, 0, V_GLOBAL_FORMAT_ABORT},
- {"format.independent_thread_rng", "configure independent thread RNG space", C_BOOL, 75, 0, 0,
- V_GLOBAL_FORMAT_INDEPENDENT_THREAD_RNG},
+ {"format.independent_thread_rng", "configure independent thread RNG space",
+ C_BOOL, 75, 0, 0, V_GLOBAL_FORMAT_INDEPENDENT_THREAD_RNG},
- {"format.major_timeout", "long-running operations timeout (minutes)", C_IGNORE, 0, 0, 1000,
- V_GLOBAL_FORMAT_MAJOR_TIMEOUT},
+ {"format.major_timeout", "long-running operations timeout (minutes)",
+ C_IGNORE, 0, 0, 1000, V_GLOBAL_FORMAT_MAJOR_TIMEOUT},
- /*
- * 0%
- * FIXME-WT-7418: Temporarily disable import until WT_ROLLBACK error and wt_copy_and_sync error is
- * fixed. It should be (C_BOOL, 20, 0, 0).
- */
- {"import", "import table from newly created database", C_BOOL, 0, 0, 0, V_GLOBAL_IMPORT},
+/*
+ * 0%
+ * FIXME-WT-7418: Temporarily disable import until WT_ROLLBACK error and wt_copy_and_sync error is
+ * fixed. It should be (C_BOOL, 20, 0, 0).
+ */
+ {"import", "import table from newly created database",
+ C_BOOL, 0, 0, 0, V_GLOBAL_IMPORT},
- {"logging", "configure logging", C_BOOL, 50, 0, 0, V_GLOBAL_LOGGING},
+ {"logging", "configure logging",
+ C_BOOL, 50, 0, 0, V_GLOBAL_LOGGING},
{"logging.compression", "logging compression (off | lz4 | snappy | zlib | zstd)",
C_IGNORE | C_STRING, 0, 0, 0, V_GLOBAL_LOGGING_COMPRESSION},
- {"logging.file_max", "maximum log file size (KB)", 0x0, 100, 512000, 2097152,
- V_GLOBAL_LOGGING_FILE_MAX},
+ {"logging.file_max", "maximum log file size (KB)",
+ 0x0, 100, 512000, 2097152, V_GLOBAL_LOGGING_FILE_MAX},
- {"logging.prealloc", "configure log file pre-allocation", C_BOOL, 50, 0, 0,
- V_GLOBAL_LOGGING_PREALLOC},
+ {"logging.prealloc", "configure log file pre-allocation",
+ C_BOOL, 50, 0, 0, V_GLOBAL_LOGGING_PREALLOC},
- {"logging.remove", "configure log file removal", C_BOOL, 50, 0, 0, V_GLOBAL_LOGGING_REMOVE},
+ {"logging.remove", "configure log file removal",
+ C_BOOL, 50, 0, 0, V_GLOBAL_LOGGING_REMOVE},
- {"lsm.auto_throttle", "throttle LSM inserts", C_BOOL | C_TABLE | C_TYPE_LSM, 90, 0, 0,
- V_TABLE_LSM_AUTO_THROTTLE},
+ {"lsm.auto_throttle", "throttle LSM inserts",
+ C_BOOL | C_TABLE | C_TYPE_LSM, 90, 0, 0, V_TABLE_LSM_AUTO_THROTTLE},
- {"lsm.bloom", "configure bloom filters", C_BOOL | C_TABLE | C_TYPE_LSM, 95, 0, 0,
- V_TABLE_LSM_BLOOM},
+ {"lsm.bloom", "configure bloom filters",
+ C_BOOL | C_TABLE | C_TYPE_LSM, 95, 0, 0, V_TABLE_LSM_BLOOM},
- {"lsm.bloom_bit_count", "number of bits per item for bloom filters", C_TABLE | C_TYPE_LSM, 4, 64,
- 1000, V_TABLE_LSM_BLOOM_BIT_COUNT},
+ {"lsm.bloom_bit_count", "number of bits per item for bloom filters",
+ C_TABLE | C_TYPE_LSM, 4, 64, 1000, V_TABLE_LSM_BLOOM_BIT_COUNT},
- {"lsm.bloom_hash_count", "number of hash values per item for bloom filters", C_TABLE | C_TYPE_LSM,
- 4, 32, 100, V_TABLE_LSM_BLOOM_HASH_COUNT},
+ {"lsm.bloom_hash_count", "number of hash values per item for bloom filters",
+ C_TABLE | C_TYPE_LSM, 4, 32, 100, V_TABLE_LSM_BLOOM_HASH_COUNT},
- {"lsm.bloom_oldest", "configure bloom_oldest=true", C_BOOL | C_TABLE | C_TYPE_LSM, 10, 0, 0,
- V_TABLE_LSM_BLOOM_OLDEST},
+ {"lsm.bloom_oldest", "configure bloom_oldest=true",
+ C_BOOL | C_TABLE | C_TYPE_LSM, 10, 0, 0, V_TABLE_LSM_BLOOM_OLDEST},
- {"lsm.chunk_size", "LSM chunk size (MB)", C_TABLE | C_TYPE_LSM, 1, 10, 100,
- V_TABLE_LSM_CHUNK_SIZE},
+ {"lsm.chunk_size", "LSM chunk size (MB)",
+ C_TABLE | C_TYPE_LSM, 1, 10, 100, V_TABLE_LSM_CHUNK_SIZE},
{"lsm.merge_max", "maximum number of chunks to include in an LSM merge operation",
C_TABLE | C_TYPE_LSM, 4, 20, 100, V_TABLE_LSM_MERGE_MAX},
- {"lsm.worker_threads", "number of LSM worker threads", C_TYPE_LSM, 3, 4, 20,
- V_GLOBAL_LSM_WORKER_THREADS},
+ {"lsm.worker_threads", "number of LSM worker threads",
+ C_TYPE_LSM, 3, 4, 20, V_GLOBAL_LSM_WORKER_THREADS},
- {"ops.alter", "configure table alterations", C_BOOL, 10, 0, 0, V_GLOBAL_OPS_ALTER},
+ {"ops.alter", "configure table alterations",
+ C_BOOL, 10, 0, 0, V_GLOBAL_OPS_ALTER},
- {"ops.compaction", "configure compaction", C_BOOL, 10, 0, 0, V_GLOBAL_OPS_COMPACTION},
+ {"ops.compaction", "configure compaction",
+ C_BOOL, 10, 0, 0, V_GLOBAL_OPS_COMPACTION},
- {"ops.hs_cursor", "configure history store cursor reads", C_BOOL, 50, 0, 0,
- V_GLOBAL_OPS_HS_CURSOR},
+ {"ops.hs_cursor", "configure history store cursor reads",
+ C_BOOL, 50, 0, 0, V_GLOBAL_OPS_HS_CURSOR},
- {"ops.pct.delete", "delete operations (percentage)", C_IGNORE | C_TABLE, 0, 0, 100,
- V_TABLE_OPS_PCT_DELETE},
+ {"ops.pct.delete", "delete operations (percentage)",
+ C_IGNORE | C_TABLE, 0, 0, 100, V_TABLE_OPS_PCT_DELETE},
- {"ops.pct.insert", "insert operations (percentage)", C_IGNORE | C_TABLE, 0, 0, 100,
- V_TABLE_OPS_PCT_INSERT},
+ {"ops.pct.insert", "insert operations (percentage)",
+ C_IGNORE | C_TABLE, 0, 0, 100, V_TABLE_OPS_PCT_INSERT},
- {"ops.pct.modify", "modify operations (percentage)", C_IGNORE | C_TABLE, 0, 0, 100,
- V_TABLE_OPS_PCT_MODIFY},
+ {"ops.pct.modify", "modify operations (percentage)",
+ C_IGNORE | C_TABLE, 0, 0, 100, V_TABLE_OPS_PCT_MODIFY},
- {"ops.pct.read", "read operations (percentage)", C_IGNORE | C_TABLE, 0, 0, 100,
- V_TABLE_OPS_PCT_READ},
+ {"ops.pct.read", "read operations (percentage)",
+ C_IGNORE | C_TABLE, 0, 0, 100, V_TABLE_OPS_PCT_READ},
- {"ops.pct.write", "update operations (percentage)", C_IGNORE | C_TABLE, 0, 0, 100,
- V_TABLE_OPS_PCT_WRITE},
+ {"ops.pct.write", "update operations (percentage)",
+ C_IGNORE | C_TABLE, 0, 0, 100, V_TABLE_OPS_PCT_WRITE},
- {"ops.prepare", "configure transaction prepare", C_BOOL, 5, 0, 0, V_GLOBAL_OPS_PREPARE},
+ {"ops.prepare", "configure transaction prepare",
+ C_BOOL, 5, 0, 0, V_GLOBAL_OPS_PREPARE},
- {"ops.random_cursor", "configure random cursor reads", C_BOOL, 10, 0, 0,
- V_GLOBAL_OPS_RANDOM_CURSOR},
+ {"ops.random_cursor", "configure random cursor reads",
+ C_BOOL, 10, 0, 0, V_GLOBAL_OPS_RANDOM_CURSOR},
- {"ops.salvage", "configure salvage", C_BOOL, 100, 1, 0, V_GLOBAL_OPS_SALVAGE},
+ {"ops.salvage", "configure salvage",
+ C_BOOL, 100, 1, 0, V_GLOBAL_OPS_SALVAGE},
- {"ops.truncate", "configure truncation", C_BOOL | C_TABLE, 100, 0, 0, V_TABLE_OPS_TRUNCATE},
+ {"ops.truncate", "configure truncation",
+ C_BOOL | C_TABLE, 100, 0, 0, V_TABLE_OPS_TRUNCATE},
- {"ops.verify", "configure verify", C_BOOL, 100, 1, 0, V_GLOBAL_OPS_VERIFY},
+ {"ops.verify", "configure verify",
+ C_BOOL, 100, 1, 0, V_GLOBAL_OPS_VERIFY},
- {"quiet", "quiet run (same as -q)", C_BOOL | C_IGNORE, 0, 0, 1, V_GLOBAL_QUIET},
+ {"quiet", "quiet run (same as -q)",
+ C_BOOL | C_IGNORE, 0, 0, 1, V_GLOBAL_QUIET},
- {"runs.in_memory", "configure in-memory", C_BOOL | C_IGNORE, 0, 0, 1, V_GLOBAL_RUNS_IN_MEMORY},
+ {"runs.in_memory", "configure in-memory",
+ C_BOOL | C_IGNORE, 0, 0, 1, V_GLOBAL_RUNS_IN_MEMORY},
- {"runs.ops", "operations per run", 0x0, 0, M(2), M(100), V_GLOBAL_RUNS_OPS},
+ {"runs.ops", "operations per run",
+ 0x0, 0, M(2), M(100), V_GLOBAL_RUNS_OPS},
- {"runs.rows", "number of rows", C_TABLE, 10, M(1), M(100), V_TABLE_RUNS_ROWS},
+ {"runs.rows", "number of rows",
+ C_TABLE, 10, M(1), M(100), V_TABLE_RUNS_ROWS},
- {"runs.source", "data source type (file | lsm | table)", C_IGNORE | C_STRING | C_TABLE, 0, 0, 0,
- V_TABLE_RUNS_SOURCE},
+ {"runs.source", "data source type (file | lsm | table)",
+ C_IGNORE | C_STRING | C_TABLE, 0, 0, 0, V_TABLE_RUNS_SOURCE},
- {"runs.tables", "number of tables", 0x0, 1, 32, V_MAX_TABLES_CONFIG, V_GLOBAL_RUNS_TABLES},
+ {"runs.tables", "number of tables",
+ 0x0, 1, 32, V_MAX_TABLES_CONFIG, V_GLOBAL_RUNS_TABLES},
- {"runs.threads", "number of worker threads", 0x0, 1, 32, 128, V_GLOBAL_RUNS_THREADS},
+ {"runs.threads", "number of worker threads",
+ 0x0, 1, 32, 128, V_GLOBAL_RUNS_THREADS},
- {"runs.timer", "run time (minutes)", C_IGNORE, 0, 0, UINT_MAX, V_GLOBAL_RUNS_TIMER},
+ {"runs.timer", "run time (minutes)",
+ C_IGNORE, 0, 0, UINT_MAX, V_GLOBAL_RUNS_TIMER},
- {"runs.type", "object type (fix | row | var)", C_IGNORE | C_STRING | C_TABLE, 0, 0, 0,
- V_TABLE_RUNS_TYPE},
+ {"runs.type", "object type (fix | row | var)",
+ C_IGNORE | C_STRING | C_TABLE, 0, 0, 0, V_TABLE_RUNS_TYPE},
- {"runs.verify_failure_dump", "configure page dump on repeatable read error", C_BOOL | C_IGNORE, 0,
- 0, 1, V_GLOBAL_RUNS_VERIFY_FAILURE_DUMP},
+ {"runs.verify_failure_dump", "configure page dump on repeatable read error",
+ C_BOOL | C_IGNORE, 0, 0, 1, V_GLOBAL_RUNS_VERIFY_FAILURE_DUMP},
- {"statistics", "configure statistics", C_BOOL, 20, 0, 0, V_GLOBAL_STATISTICS},
+ {"statistics", "configure statistics",
+ C_BOOL, 20, 0, 0, V_GLOBAL_STATISTICS},
- {"statistics.server", "configure statistics server thread", C_BOOL, 5, 0, 0,
- V_GLOBAL_STATISTICS_SERVER},
+ {"statistics.server", "configure statistics server thread",
+ C_BOOL, 5, 0, 0, V_GLOBAL_STATISTICS_SERVER},
- {"stress.aggressive_sweep", "stress aggressive sweep", C_BOOL, 2, 0, 0,
- V_GLOBAL_STRESS_AGGRESSIVE_SWEEP},
+ {"stress.aggressive_sweep", "stress aggressive sweep",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_AGGRESSIVE_SWEEP},
- {"stress.checkpoint", "stress checkpoints", C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_CHECKPOINT},
+ {"stress.checkpoint", "stress checkpoints",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_CHECKPOINT},
{"stress.checkpoint_reserved_txnid_delay", "stress checkpoint invisible transaction id delay",
C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_CHECKPOINT_RESERVED_TXNID_DELAY},
- {"stress.checkpoint_prepare", "stress checkpoint prepare", C_BOOL, 2, 0, 0,
- V_GLOBAL_STRESS_CHECKPOINT_PREPARE},
+ {"stress.checkpoint_prepare", "stress checkpoint prepare",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_CHECKPOINT_PREPARE},
+
+ {"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},
- {"stress.hs_checkpoint_delay", "stress history store checkpoint delay", C_BOOL, 2, 0, 0,
- V_GLOBAL_STRESS_HS_CHECKPOINT_DELAY},
+ {"stress.hs_checkpoint_delay", "stress history store checkpoint delay",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_HS_CHECKPOINT_DELAY},
- {"stress.hs_search", "stress history store search", C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_HS_SEARCH},
+ {"stress.hs_search", "stress history store search",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_HS_SEARCH},
- {"stress.hs_sweep", "stress history store sweep", C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_HS_SWEEP},
+ {"stress.hs_sweep", "stress history store sweep",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_HS_SWEEP},
- {"stress.split_1", "stress splits (#1)", C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_1},
+ {"stress.split_1", "stress splits (#1)",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_1},
- {"stress.split_2", "stress splits (#2)", C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_2},
+ {"stress.split_2", "stress splits (#2)",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_2},
- {"stress.split_3", "stress splits (#3)", C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_3},
+ {"stress.split_3", "stress splits (#3)",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_3},
- {"stress.split_4", "stress splits (#4)", C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_4},
+ {"stress.split_4", "stress splits (#4)",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_4},
- {"stress.split_5", "stress splits (#5)", C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_5},
+ {"stress.split_5", "stress splits (#5)",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_5},
- {"stress.split_6", "stress splits (#6)", C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_6},
+ {"stress.split_6", "stress splits (#6)",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_6},
- {"stress.split_7", "stress splits (#7)", C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_7},
+ {"stress.split_7", "stress splits (#7)",
+ C_BOOL, 2, 0, 0, V_GLOBAL_STRESS_SPLIT_7},
- {"transaction.implicit", "implicit, without timestamps, transactions (percentage)", 0, 0, 100,
- 100, V_GLOBAL_TRANSACTION_IMPLICIT},
+ {"transaction.implicit", "implicit, without timestamps, transactions (percentage)",
+ 0, 0, 100, 100, V_GLOBAL_TRANSACTION_IMPLICIT},
- {"transaction.timestamps", "all transactions (or none), have timestamps", C_BOOL, 80, 0, 0,
- V_GLOBAL_TRANSACTION_TIMESTAMPS},
+ {"transaction.timestamps", "all transactions (or none), have timestamps",
+ C_BOOL, 80, 0, 0, V_GLOBAL_TRANSACTION_TIMESTAMPS},
- {"wiredtiger.config", "wiredtiger_open API configuration string", C_IGNORE | C_STRING, 0, 0, 0,
- V_GLOBAL_WIREDTIGER_CONFIG},
+ {"wiredtiger.config", "wiredtiger_open API configuration string",
+ C_IGNORE | C_STRING, 0, 0, 0, V_GLOBAL_WIREDTIGER_CONFIG},
- {"wiredtiger.rwlock", "configure wiredtiger read/write mutexes", C_BOOL, 80, 0, 0,
- V_GLOBAL_WIREDTIGER_RWLOCK},
+ {"wiredtiger.rwlock", "configure wiredtiger read/write mutexes",
+ C_BOOL, 80, 0, 0, V_GLOBAL_WIREDTIGER_RWLOCK},
- {"wiredtiger.leak_memory", "leak memory on wiredtiger shutdown", C_BOOL, 0, 0, 0,
- V_GLOBAL_WIREDTIGER_LEAK_MEMORY},
+ {"wiredtiger.leak_memory", "leak memory on wiredtiger shutdown",
+ C_BOOL, 0, 0, 0, V_GLOBAL_WIREDTIGER_LEAK_MEMORY},
- {NULL, NULL, 0x0, 0, 0, 0, 0}};
+ {NULL, NULL, 0x0, 0, 0, 0, 0}
+};
diff --git a/src/third_party/wiredtiger/test/format/wts.c b/src/third_party/wiredtiger/test/format/wts.c
index dc91c759bf1..32f52a027e7 100644
--- a/src/third_party/wiredtiger/test/format/wts.c
+++ b/src/third_party/wiredtiger/test/format/wts.c
@@ -158,6 +158,8 @@ configure_timing_stress(char *p, size_t max)
CONFIG_APPEND(p, ",prepare_checkpoint_delay");
if (GV(STRESS_CHECKPOINT_RESERVED_TXNID_DELAY))
CONFIG_APPEND(p, ",checkpoint_reserved_txnid_delay");
+ 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()