Import wiredtiger: baf8c83f285bb15e4a230068aa23958a7817e9fa from branch mongodb-8.2 (#44541)

Co-authored-by: wt-vendoring-bot <wt-vendoring-bot@mongodb.com>
GitOrigin-RevId: a04b90d0107eb4283425d0f698b4f145d5a614c9
This commit is contained in:
wt-vendoring-bot[bot] 2025-12-01 11:34:04 +11:00 committed by MongoDB Bot
parent cb23179906
commit 13fc9420f4
18 changed files with 1465 additions and 1246 deletions

View File

@ -667,6 +667,10 @@ connection_runtime_config = [
The configured percentage will be taken in increments of 10 only,
by applying the floor to the given percentage value. ''',
min='0', max='100'),
Config('skip_update_obsolete_check', 'false',
r'''Skip checking for obsolete updates whenever an update operation is
performed.''',
type='boolean'),
]),
Config('eviction_checkpoint_target', '1', r'''
perform eviction at the beginning of checkpoints to bring the dirty content in cache
@ -762,7 +766,7 @@ connection_runtime_config = [
Config('obsolete_tw_btree_max', '100', r'''
maximum number of btrees that can be checked for obsolete time window cleanup in a
single checkpoint''',
min=0, max=500000),
min=0, max=500000)
]),
Config('history_store', '', r'''
history store configuration options''',

View File

@ -1104,6 +1104,7 @@ conn_dsrc_stats = [
CacheStat('cache_hs_write_squash', 'history store table writes requiring squashed modifies'),
CacheStat('cache_inmem_split', 'in-memory page splits'),
CacheStat('cache_inmem_splittable', 'in-memory page passed criteria to be split'),
CacheStat('cache_obsolete_updates_removed', 'obsolete updates removed'),
CacheStat('cache_pages_prefetch', 'pages requested from the cache due to pre-fetch'),
CacheStat('cache_pages_requested', 'pages requested from the cache'),
CacheStat('cache_pages_requested_hs', 'pages requested from the history store'),

View File

@ -2,5 +2,5 @@
"vendor": "wiredtiger",
"github": "wiredtiger/wiredtiger",
"branch": "mongodb-8.2",
"commit": "6d23f8b399935ca913c701ca6194ed3e2c0fd743"
"commit": "baf8c83f285bb15e4a230068aa23958a7817e9fa"
}

View File

@ -527,3 +527,39 @@ __wt_free_update_list(WT_SESSION_IMPL *session, WT_UPDATE **updp)
}
*updp = NULL;
}
/*
* __wt_free_obsolete_updates --
* Following a globally visible update, free any obsolete updates in the update chain. After a
* globally visible update, no reader finds any updates. It is the responsibility of the caller
* to lock the page before freeing the updates.
*/
void
__wt_free_obsolete_updates(WT_SESSION_IMPL *session, WT_PAGE *page, WT_UPDATE *visible_all_upd)
{
WT_UPDATE *next, *upd;
size_t size;
size = 0;
next = visible_all_upd->next;
/*
* No need to use a compare and swap because we have obtained a page lock. The page lock
* protects freeing the updates concurrently by other threads. Whereas the reader threads use
* transaction visibility to avoid traversing obsolete updates beyond the globally visible
* update.
*/
visible_all_upd->next = NULL;
/* There must be at least a single obsolete update. */
WT_ASSERT(session, next != NULL);
for (upd = next; upd != NULL; upd = next) {
next = upd->next;
size += WT_UPDATE_MEMSIZE(upd);
__wt_free(session, upd);
}
WT_ASSERT(session, size != 0);
__wt_cache_page_inmem_decr(session, page, size);
}

View File

@ -347,16 +347,13 @@ err:
* Check for obsolete updates and force evict the page if the update list is too long.
*/
void
__wt_update_obsolete_check(
WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd, bool update_accounting)
__wt_update_obsolete_check(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd)
{
WT_PAGE *page;
WT_TXN_GLOBAL *txn_global;
WT_UPDATE *first, *next;
size_t size;
WT_UPDATE *first;
u_int count;
next = NULL;
page = cbt->ref->page;
txn_global = &S2C(session)->txn_global;
@ -402,28 +399,16 @@ __wt_update_obsolete_check(
first = NULL;
}
/*
* We cannot discard this WT_UPDATE structure, we can only discard WT_UPDATE structures
* subsequent to it, other threads of control will terminate their walk in this element. Save a
* reference to the list we will discard, and terminate the list.
*/
if (first != NULL && (next = first->next) != NULL) {
if (first != NULL && first->next != NULL)
__wt_free_obsolete_updates(session, page, first);
else if (count > 20) {
/*
* No need to use a compare and swap because we have obtained a lock at the start of the
* function.
* If the list is long, don't retry checks on this page until the transaction state has
* moved forwards.
*/
first->next = NULL;
/*
* Decrement the dirty byte count while holding the page lock, else we can race with
* checkpoints cleaning a page.
*/
if (update_accounting) {
for (size = 0, upd = next; upd != NULL; upd = upd->next)
size += WT_UPDATE_MEMSIZE(upd);
if (size != 0)
__wt_cache_page_inmem_decr(session, page, size);
}
page->modify->obsolete_check_txn = __wt_atomic_loadv64(&txn_global->last_running);
if (txn_global->has_pinned_timestamp)
page->modify->obsolete_check_timestamp = txn_global->pinned_timestamp;
}
/*
@ -437,19 +422,5 @@ __wt_update_obsolete_check(
__wt_evict_page_soon(session, cbt->ref);
}
if (next != NULL)
__wt_free_update_list(session, &next);
else {
/*
* If the list is long, don't retry checks on this page until the transaction state has
* moved forwards.
*/
if (count > 20) {
page->modify->obsolete_check_txn = __wt_atomic_loadv64(&txn_global->last_running);
if (txn_global->has_pinned_timestamp)
page->modify->obsolete_check_timestamp = txn_global->pinned_timestamp;
}
}
WT_PAGE_UNLOCK(session, page);
}

File diff suppressed because it is too large Load Diff

View File

@ -258,6 +258,10 @@ __wt_evict_config(WT_SESSION_IMPL *session, const char *cfg[], bool reconfig)
__wt_atomic_store8(&cache->cache_eviction_controls.cache_tolerance_for_app_eviction,
(((uint8_t)cval.val / 10) * 10));
WT_RET(__wt_config_gets(session, cfg, "eviction.skip_update_obsolete_check", &cval));
if (cval.val != 0)
F_SET_ATOMIC_16(&(cache->cache_eviction_controls), WT_CACHE_SKIP_UPDATE_OBSOLETE_CHECK);
/*
* Resize the thread group if reconfiguring, otherwise the thread group will be initialized as
* part of creating the connection workers.

View File

@ -26,8 +26,10 @@ typedef enum __wt_cache_op {
*/
struct __wt_cache_eviction_controls {
wt_shared uint8_t cache_tolerance_for_app_eviction; /* cache tolerance for app eviction.*/
/* cache eviction controls bit positions */
/* cache eviction controls bit positions */
#define WT_CACHE_PREFER_SCRUB_EVICTION 0x1u
#define WT_CACHE_SKIP_UPDATE_OBSOLETE_CHECK 0x2u
wt_shared uint16_t flags_atomic;
};

View File

@ -142,7 +142,7 @@ WT_CONF_API_DECLARE(WT_CONNECTION, debug_info, 1, 7);
WT_CONF_API_DECLARE(WT_CONNECTION, load_extension, 1, 4);
WT_CONF_API_DECLARE(WT_CONNECTION, open_session, 3, 9);
WT_CONF_API_DECLARE(WT_CONNECTION, query_timestamp, 1, 1);
WT_CONF_API_DECLARE(WT_CONNECTION, reconfigure, 19, 109);
WT_CONF_API_DECLARE(WT_CONNECTION, reconfigure, 19, 110);
WT_CONF_API_DECLARE(WT_CONNECTION, rollback_to_stable, 1, 2);
WT_CONF_API_DECLARE(WT_CONNECTION, set_timestamp, 1, 4);
WT_CONF_API_DECLARE(WT_CURSOR, bound, 1, 3);
@ -171,10 +171,10 @@ WT_CONF_API_DECLARE(object, meta, 6, 67);
WT_CONF_API_DECLARE(table, meta, 2, 13);
WT_CONF_API_DECLARE(tier, meta, 6, 68);
WT_CONF_API_DECLARE(tiered, meta, 6, 70);
WT_CONF_API_DECLARE(GLOBAL, wiredtiger_open, 24, 179);
WT_CONF_API_DECLARE(GLOBAL, wiredtiger_open_all, 24, 180);
WT_CONF_API_DECLARE(GLOBAL, wiredtiger_open_basecfg, 24, 174);
WT_CONF_API_DECLARE(GLOBAL, wiredtiger_open_usercfg, 24, 173);
WT_CONF_API_DECLARE(GLOBAL, wiredtiger_open, 24, 180);
WT_CONF_API_DECLARE(GLOBAL, wiredtiger_open_all, 24, 181);
WT_CONF_API_DECLARE(GLOBAL, wiredtiger_open_basecfg, 24, 175);
WT_CONF_API_DECLARE(GLOBAL, wiredtiger_open_usercfg, 24, 174);
#define WT_CONF_API_ELEMENTS 53

View File

@ -26,38 +26,38 @@
#define WT_CONF_ID_Disaggregated 215ULL
#define WT_CONF_ID_Encryption 19ULL
#define WT_CONF_ID_Eviction 217ULL
#define WT_CONF_ID_File_manager 233ULL
#define WT_CONF_ID_File_manager 234ULL
#define WT_CONF_ID_Flush_tier 161ULL
#define WT_CONF_ID_Hash 296ULL
#define WT_CONF_ID_Heuristic_controls 238ULL
#define WT_CONF_ID_History_store 242ULL
#define WT_CONF_ID_Hash 297ULL
#define WT_CONF_ID_Heuristic_controls 239ULL
#define WT_CONF_ID_History_store 243ULL
#define WT_CONF_ID_Import 88ULL
#define WT_CONF_ID_Incremental 119ULL
#define WT_CONF_ID_Io_capacity 244ULL
#define WT_CONF_ID_Io_capacity 245ULL
#define WT_CONF_ID_Live_restore 60ULL
#define WT_CONF_ID_Log 36ULL
#define WT_CONF_ID_Lsm 94ULL
#define WT_CONF_ID_Operation_tracking 254ULL
#define WT_CONF_ID_Prefetch 276ULL
#define WT_CONF_ID_Rollback_to_stable 256ULL
#define WT_CONF_ID_Operation_tracking 255ULL
#define WT_CONF_ID_Prefetch 277ULL
#define WT_CONF_ID_Rollback_to_stable 257ULL
#define WT_CONF_ID_Roundup_timestamps 153ULL
#define WT_CONF_ID_Shared_cache 258ULL
#define WT_CONF_ID_Statistics_log 262ULL
#define WT_CONF_ID_Shared_cache 259ULL
#define WT_CONF_ID_Statistics_log 263ULL
#define WT_CONF_ID_Tiered_storage 47ULL
#define WT_CONF_ID_Transaction_sync 316ULL
#define WT_CONF_ID_Transaction_sync 317ULL
#define WT_CONF_ID_access_pattern_hint 12ULL
#define WT_CONF_ID_action 77ULL
#define WT_CONF_ID_allocation_size 13ULL
#define WT_CONF_ID_app_metadata 0ULL
#define WT_CONF_ID_append 74ULL
#define WT_CONF_ID_archive 248ULL
#define WT_CONF_ID_archive 249ULL
#define WT_CONF_ID_auth_token 48ULL
#define WT_CONF_ID_auto_throttle 95ULL
#define WT_CONF_ID_available 308ULL
#define WT_CONF_ID_available 309ULL
#define WT_CONF_ID_background 81ULL
#define WT_CONF_ID_background_compact 198ULL
#define WT_CONF_ID_backup 165ULL
#define WT_CONF_ID_backup_restore_target 278ULL
#define WT_CONF_ID_backup_restore_target 279ULL
#define WT_CONF_ID_bitmap 61ULL
#define WT_CONF_ID_blkcache_eviction_aggression 175ULL
#define WT_CONF_ID_block_allocation 14ULL
@ -70,12 +70,12 @@
#define WT_CONF_ID_bound 78ULL
#define WT_CONF_ID_bucket 49ULL
#define WT_CONF_ID_bucket_prefix 50ULL
#define WT_CONF_ID_buckets 297ULL
#define WT_CONF_ID_buffer_alignment 279ULL
#define WT_CONF_ID_builtin_extension_config 280ULL
#define WT_CONF_ID_buckets 298ULL
#define WT_CONF_ID_buffer_alignment 280ULL
#define WT_CONF_ID_builtin_extension_config 281ULL
#define WT_CONF_ID_bulk 112ULL
#define WT_CONF_ID_cache 166ULL
#define WT_CONF_ID_cache_cursors 272ULL
#define WT_CONF_ID_cache_cursors 273ULL
#define WT_CONF_ID_cache_directory 51ULL
#define WT_CONF_ID_cache_max_wait_ms 183ULL
#define WT_CONF_ID_cache_on_checkpoint 173ULL
@ -85,50 +85,50 @@
#define WT_CONF_ID_cache_size 185ULL
#define WT_CONF_ID_cache_stuck_timeout_ms 186ULL
#define WT_CONF_ID_cache_tolerance_for_app_eviction 224ULL
#define WT_CONF_ID_capacity 282ULL
#define WT_CONF_ID_capacity 283ULL
#define WT_CONF_ID_checkpoint 56ULL
#define WT_CONF_ID_checkpoint_backup_info 57ULL
#define WT_CONF_ID_checkpoint_cleanup 158ULL
#define WT_CONF_ID_checkpoint_cleanup_obsolete_tw_pages_dirty_max 239ULL
#define WT_CONF_ID_checkpoint_cleanup_obsolete_tw_pages_dirty_max 240ULL
#define WT_CONF_ID_checkpoint_crash_point 159ULL
#define WT_CONF_ID_checkpoint_fail_before_turtle_update 273ULL
#define WT_CONF_ID_checkpoint_fail_before_turtle_update 274ULL
#define WT_CONF_ID_checkpoint_lsn 58ULL
#define WT_CONF_ID_checkpoint_read_timestamp 115ULL
#define WT_CONF_ID_checkpoint_retention 200ULL
#define WT_CONF_ID_checkpoint_sync 281ULL
#define WT_CONF_ID_checkpoint_sync 282ULL
#define WT_CONF_ID_checkpoint_use_history 113ULL
#define WT_CONF_ID_checkpoint_wait 106ULL
#define WT_CONF_ID_checksum 17ULL
#define WT_CONF_ID_chunk 259ULL
#define WT_CONF_ID_chunk_cache 246ULL
#define WT_CONF_ID_chunk_cache_evict_trigger 283ULL
#define WT_CONF_ID_chunk 260ULL
#define WT_CONF_ID_chunk_cache 247ULL
#define WT_CONF_ID_chunk_cache_evict_trigger 284ULL
#define WT_CONF_ID_chunk_count_limit 101ULL
#define WT_CONF_ID_chunk_max 102ULL
#define WT_CONF_ID_chunk_size 103ULL
#define WT_CONF_ID_claim_prepared_id 147ULL
#define WT_CONF_ID_close_handle_minimum 234ULL
#define WT_CONF_ID_close_idle_time 235ULL
#define WT_CONF_ID_close_scan_interval 236ULL
#define WT_CONF_ID_close_handle_minimum 235ULL
#define WT_CONF_ID_close_idle_time 236ULL
#define WT_CONF_ID_close_scan_interval 237ULL
#define WT_CONF_ID_colgroups 70ULL
#define WT_CONF_ID_collator 6ULL
#define WT_CONF_ID_columns 7ULL
#define WT_CONF_ID_commit_timestamp 2ULL
#define WT_CONF_ID_compare_timestamp 89ULL
#define WT_CONF_ID_compile_configuration_count 288ULL
#define WT_CONF_ID_compressor 302ULL
#define WT_CONF_ID_config 268ULL
#define WT_CONF_ID_config_base 289ULL
#define WT_CONF_ID_compile_configuration_count 289ULL
#define WT_CONF_ID_compressor 303ULL
#define WT_CONF_ID_config 269ULL
#define WT_CONF_ID_config_base 290ULL
#define WT_CONF_ID_configuration 201ULL
#define WT_CONF_ID_consolidate 120ULL
#define WT_CONF_ID_corruption_abort 199ULL
#define WT_CONF_ID_create 290ULL
#define WT_CONF_ID_create 291ULL
#define WT_CONF_ID_cursor_copy 202ULL
#define WT_CONF_ID_cursor_reposition 203ULL
#define WT_CONF_ID_cursors 167ULL
#define WT_CONF_ID_default 309ULL
#define WT_CONF_ID_dhandle_buckets 298ULL
#define WT_CONF_ID_default 310ULL
#define WT_CONF_ID_dhandle_buckets 299ULL
#define WT_CONF_ID_dictionary 18ULL
#define WT_CONF_ID_direct_io 291ULL
#define WT_CONF_ID_direct_io 292ULL
#define WT_CONF_ID_do_not_clear_txn_id 135ULL
#define WT_CONF_ID_drop 160ULL
#define WT_CONF_ID_dryrun 82ULL
@ -143,66 +143,66 @@
#define WT_CONF_ID_dump_tree_shape 143ULL
#define WT_CONF_ID_dump_version 116ULL
#define WT_CONF_ID_durable_timestamp 3ULL
#define WT_CONF_ID_early_load 269ULL
#define WT_CONF_ID_early_load 270ULL
#define WT_CONF_ID_enabled 37ULL
#define WT_CONF_ID_entry 270ULL
#define WT_CONF_ID_entry 271ULL
#define WT_CONF_ID_error_prefix 216ULL
#define WT_CONF_ID_evict_sample_inmem 220ULL
#define WT_CONF_ID_evict_use_softptr 221ULL
#define WT_CONF_ID_eviction 204ULL
#define WT_CONF_ID_eviction_checkpoint_target 225ULL
#define WT_CONF_ID_eviction_checkpoint_target 226ULL
#define WT_CONF_ID_eviction_checkpoint_ts_ordering 214ULL
#define WT_CONF_ID_eviction_dirty_target 226ULL
#define WT_CONF_ID_eviction_dirty_trigger 227ULL
#define WT_CONF_ID_eviction_obsolete_tw_pages_dirty_max 240ULL
#define WT_CONF_ID_eviction_target 228ULL
#define WT_CONF_ID_eviction_trigger 229ULL
#define WT_CONF_ID_eviction_updates_target 230ULL
#define WT_CONF_ID_eviction_updates_trigger 231ULL
#define WT_CONF_ID_eviction_dirty_target 227ULL
#define WT_CONF_ID_eviction_dirty_trigger 228ULL
#define WT_CONF_ID_eviction_obsolete_tw_pages_dirty_max 241ULL
#define WT_CONF_ID_eviction_target 229ULL
#define WT_CONF_ID_eviction_trigger 230ULL
#define WT_CONF_ID_eviction_updates_target 231ULL
#define WT_CONF_ID_eviction_updates_trigger 232ULL
#define WT_CONF_ID_exclude 83ULL
#define WT_CONF_ID_exclusive 87ULL
#define WT_CONF_ID_exclusive_refreshed 80ULL
#define WT_CONF_ID_extensions 294ULL
#define WT_CONF_ID_extra_diagnostics 232ULL
#define WT_CONF_ID_extensions 295ULL
#define WT_CONF_ID_extra_diagnostics 233ULL
#define WT_CONF_ID_extractor 66ULL
#define WT_CONF_ID_file 121ULL
#define WT_CONF_ID_file_extend 295ULL
#define WT_CONF_ID_file_max 243ULL
#define WT_CONF_ID_file_extend 296ULL
#define WT_CONF_ID_file_max 244ULL
#define WT_CONF_ID_file_metadata 90ULL
#define WT_CONF_ID_file_wait_ms 192ULL
#define WT_CONF_ID_final_flush 163ULL
#define WT_CONF_ID_flush_time 68ULL
#define WT_CONF_ID_flush_timestamp 69ULL
#define WT_CONF_ID_flushed_data_cache_insertion 285ULL
#define WT_CONF_ID_flushed_data_cache_insertion 286ULL
#define WT_CONF_ID_force 107ULL
#define WT_CONF_ID_force_stop 122ULL
#define WT_CONF_ID_force_write_wait 303ULL
#define WT_CONF_ID_force_write_wait 304ULL
#define WT_CONF_ID_format 22ULL
#define WT_CONF_ID_free_space_target 84ULL
#define WT_CONF_ID_full_target 176ULL
#define WT_CONF_ID_generation_drain_timeout_ms 237ULL
#define WT_CONF_ID_generation_drain_timeout_ms 238ULL
#define WT_CONF_ID_get 134ULL
#define WT_CONF_ID_granularity 123ULL
#define WT_CONF_ID_handles 168ULL
#define WT_CONF_ID_hashsize 178ULL
#define WT_CONF_ID_hazard_max 299ULL
#define WT_CONF_ID_hazard_max 300ULL
#define WT_CONF_ID_huffman_key 23ULL
#define WT_CONF_ID_huffman_value 24ULL
#define WT_CONF_ID_id 59ULL
#define WT_CONF_ID_ignore_cache_size 275ULL
#define WT_CONF_ID_ignore_cache_size 276ULL
#define WT_CONF_ID_ignore_in_memory_cache_size 25ULL
#define WT_CONF_ID_ignore_prepare 148ULL
#define WT_CONF_ID_immutable 67ULL
#define WT_CONF_ID_in_memory 300ULL
#define WT_CONF_ID_in_memory 301ULL
#define WT_CONF_ID_inclusive 79ULL
#define WT_CONF_ID_internal_item_max 26ULL
#define WT_CONF_ID_internal_key_max 27ULL
#define WT_CONF_ID_internal_key_truncate 28ULL
#define WT_CONF_ID_internal_page_max 29ULL
#define WT_CONF_ID_interval 315ULL
#define WT_CONF_ID_interval 316ULL
#define WT_CONF_ID_isolation 149ULL
#define WT_CONF_ID_json 263ULL
#define WT_CONF_ID_json_output 247ULL
#define WT_CONF_ID_json 264ULL
#define WT_CONF_ID_json_output 248ULL
#define WT_CONF_ID_key_format 30ULL
#define WT_CONF_ID_key_gap 31ULL
#define WT_CONF_ID_keyid 21ULL
@ -225,9 +225,9 @@
#define WT_CONF_ID_merge_min 105ULL
#define WT_CONF_ID_metadata_file 91ULL
#define WT_CONF_ID_method 191ULL
#define WT_CONF_ID_mmap 305ULL
#define WT_CONF_ID_mmap_all 306ULL
#define WT_CONF_ID_multiprocess 307ULL
#define WT_CONF_ID_mmap 306ULL
#define WT_CONF_ID_mmap_all 307ULL
#define WT_CONF_ID_multiprocess 308ULL
#define WT_CONF_ID_name 20ULL
#define WT_CONF_ID_nbits 62ULL
#define WT_CONF_ID_next_random 126ULL
@ -236,22 +236,22 @@
#define WT_CONF_ID_no_timestamp 150ULL
#define WT_CONF_ID_nvram_path 180ULL
#define WT_CONF_ID_object_target_size 53ULL
#define WT_CONF_ID_obsolete_tw_btree_max 241ULL
#define WT_CONF_ID_obsolete_tw_btree_max 242ULL
#define WT_CONF_ID_oldest 72ULL
#define WT_CONF_ID_oldest_timestamp 277ULL
#define WT_CONF_ID_on_close 264ULL
#define WT_CONF_ID_oldest_timestamp 278ULL
#define WT_CONF_ID_on_close 265ULL
#define WT_CONF_ID_operation_timeout_ms 151ULL
#define WT_CONF_ID_os_cache_dirty_max 40ULL
#define WT_CONF_ID_os_cache_dirty_pct 249ULL
#define WT_CONF_ID_os_cache_dirty_pct 250ULL
#define WT_CONF_ID_os_cache_max 41ULL
#define WT_CONF_ID_overwrite 75ULL
#define WT_CONF_ID_page_log 292ULL
#define WT_CONF_ID_page_log 293ULL
#define WT_CONF_ID_panic_corrupt 92ULL
#define WT_CONF_ID_path 255ULL
#define WT_CONF_ID_path 256ULL
#define WT_CONF_ID_percent_file_in_dram 181ULL
#define WT_CONF_ID_pinned 194ULL
#define WT_CONF_ID_prealloc 250ULL
#define WT_CONF_ID_prealloc_init_count 251ULL
#define WT_CONF_ID_prealloc 251ULL
#define WT_CONF_ID_prealloc_init_count 252ULL
#define WT_CONF_ID_prefer_scrub_eviction 223ULL
#define WT_CONF_ID_prefix_compression 42ULL
#define WT_CONF_ID_prefix_compression_min 43ULL
@ -259,85 +259,86 @@
#define WT_CONF_ID_prepare_timestamp 156ULL
#define WT_CONF_ID_prepared 154ULL
#define WT_CONF_ID_prepared_id 157ULL
#define WT_CONF_ID_preserve_prepared 310ULL
#define WT_CONF_ID_preserve_prepared 311ULL
#define WT_CONF_ID_priority 152ULL
#define WT_CONF_ID_quota 260ULL
#define WT_CONF_ID_quota 261ULL
#define WT_CONF_ID_raw 129ULL
#define WT_CONF_ID_read 155ULL
#define WT_CONF_ID_read_corrupt 144ULL
#define WT_CONF_ID_read_once 130ULL
#define WT_CONF_ID_read_size 301ULL
#define WT_CONF_ID_read_size 302ULL
#define WT_CONF_ID_read_timestamp 4ULL
#define WT_CONF_ID_readonly 63ULL
#define WT_CONF_ID_realloc_exact 206ULL
#define WT_CONF_ID_realloc_malloc 207ULL
#define WT_CONF_ID_recover 304ULL
#define WT_CONF_ID_recover 305ULL
#define WT_CONF_ID_release 196ULL
#define WT_CONF_ID_release_evict 117ULL
#define WT_CONF_ID_release_evict_page 274ULL
#define WT_CONF_ID_remove 252ULL
#define WT_CONF_ID_release_evict_page 275ULL
#define WT_CONF_ID_remove 253ULL
#define WT_CONF_ID_remove_files 109ULL
#define WT_CONF_ID_remove_shared 110ULL
#define WT_CONF_ID_repair 93ULL
#define WT_CONF_ID_require_max 286ULL
#define WT_CONF_ID_require_min 287ULL
#define WT_CONF_ID_reserve 261ULL
#define WT_CONF_ID_require_max 287ULL
#define WT_CONF_ID_require_min 288ULL
#define WT_CONF_ID_reserve 262ULL
#define WT_CONF_ID_rollback_error 208ULL
#define WT_CONF_ID_run_once 85ULL
#define WT_CONF_ID_salvage 311ULL
#define WT_CONF_ID_secretkey 293ULL
#define WT_CONF_ID_session_max 312ULL
#define WT_CONF_ID_session_scratch_max 313ULL
#define WT_CONF_ID_session_table_cache 314ULL
#define WT_CONF_ID_salvage 312ULL
#define WT_CONF_ID_secretkey 294ULL
#define WT_CONF_ID_session_max 313ULL
#define WT_CONF_ID_session_scratch_max 314ULL
#define WT_CONF_ID_session_table_cache 315ULL
#define WT_CONF_ID_sessions 170ULL
#define WT_CONF_ID_shared 54ULL
#define WT_CONF_ID_size 177ULL
#define WT_CONF_ID_skip_sort_check 131ULL
#define WT_CONF_ID_skip_update_obsolete_check 225ULL
#define WT_CONF_ID_slow_checkpoint 209ULL
#define WT_CONF_ID_source 8ULL
#define WT_CONF_ID_sources 265ULL
#define WT_CONF_ID_sources 266ULL
#define WT_CONF_ID_split_deepen_min_child 44ULL
#define WT_CONF_ID_split_deepen_per_child 45ULL
#define WT_CONF_ID_split_pct 46ULL
#define WT_CONF_ID_src_id 124ULL
#define WT_CONF_ID_stable_timestamp 145ULL
#define WT_CONF_ID_statistics 132ULL
#define WT_CONF_ID_storage_path 284ULL
#define WT_CONF_ID_storage_path 285ULL
#define WT_CONF_ID_stress_skiplist 210ULL
#define WT_CONF_ID_strict 146ULL
#define WT_CONF_ID_sync 111ULL
#define WT_CONF_ID_system_ram 182ULL
#define WT_CONF_ID_table_logging 211ULL
#define WT_CONF_ID_target 133ULL
#define WT_CONF_ID_terminate 271ULL
#define WT_CONF_ID_terminate 272ULL
#define WT_CONF_ID_this_id 125ULL
#define WT_CONF_ID_threads 257ULL
#define WT_CONF_ID_threads 258ULL
#define WT_CONF_ID_threads_max 218ULL
#define WT_CONF_ID_threads_min 219ULL
#define WT_CONF_ID_tiered_flush_error_continue 212ULL
#define WT_CONF_ID_tiered_object 64ULL
#define WT_CONF_ID_tiers 73ULL
#define WT_CONF_ID_timeout 86ULL
#define WT_CONF_ID_timestamp 266ULL
#define WT_CONF_ID_timing_stress_for_test 267ULL
#define WT_CONF_ID_total 245ULL
#define WT_CONF_ID_timestamp 267ULL
#define WT_CONF_ID_timing_stress_for_test 268ULL
#define WT_CONF_ID_total 246ULL
#define WT_CONF_ID_txn 171ULL
#define WT_CONF_ID_type 9ULL
#define WT_CONF_ID_update_restore_evict 213ULL
#define WT_CONF_ID_use_environment 317ULL
#define WT_CONF_ID_use_environment_priv 318ULL
#define WT_CONF_ID_use_environment 318ULL
#define WT_CONF_ID_use_environment_priv 319ULL
#define WT_CONF_ID_use_timestamp 162ULL
#define WT_CONF_ID_value_format 55ULL
#define WT_CONF_ID_verbose 10ULL
#define WT_CONF_ID_verify_metadata 319ULL
#define WT_CONF_ID_verify_metadata 320ULL
#define WT_CONF_ID_version 65ULL
#define WT_CONF_ID_wait 189ULL
#define WT_CONF_ID_write_through 320ULL
#define WT_CONF_ID_write_through 321ULL
#define WT_CONF_ID_write_timestamp 5ULL
#define WT_CONF_ID_write_timestamp_usage 11ULL
#define WT_CONF_ID_zero_fill 253ULL
#define WT_CONF_ID_zero_fill 254ULL
#define WT_CONF_ID_COUNT 321
#define WT_CONF_ID_COUNT 322
/*
* API configuration keys: END
*/
@ -432,6 +433,7 @@ static const struct {
uint64_t evict_use_softptr;
uint64_t legacy_page_visit_strategy;
uint64_t prefer_scrub_eviction;
uint64_t skip_update_obsolete_check;
uint64_t threads_max;
uint64_t threads_min;
} Eviction;
@ -810,6 +812,7 @@ static const struct {
WT_CONF_ID_Eviction | (WT_CONF_ID_evict_use_softptr << 16),
WT_CONF_ID_Eviction | (WT_CONF_ID_legacy_page_visit_strategy << 16),
WT_CONF_ID_Eviction | (WT_CONF_ID_prefer_scrub_eviction << 16),
WT_CONF_ID_Eviction | (WT_CONF_ID_skip_update_obsolete_check << 16),
WT_CONF_ID_Eviction | (WT_CONF_ID_threads_max << 16),
WT_CONF_ID_Eviction | (WT_CONF_ID_threads_min << 16),
},

View File

@ -1625,6 +1625,8 @@ extern void __wt_fill_hex(
const uint8_t *src, size_t src_max, uint8_t *dest, size_t dest_max, size_t *lenp);
extern void __wt_free_int(WT_SESSION_IMPL *session, const void *p_arg)
WT_GCC_FUNC_DECL_ATTRIBUTE((visibility("default")));
extern void __wt_free_obsolete_updates(
WT_SESSION_IMPL *session, WT_PAGE *page, WT_UPDATE *visible_all_upd);
extern void __wt_free_update_list(WT_SESSION_IMPL *session, WT_UPDATE **updp);
extern void __wt_gen_init(WT_SESSION_IMPL *session);
extern void __wt_gen_next_drain(WT_SESSION_IMPL *session, int which);
@ -1705,7 +1707,7 @@ extern void __wt_txn_snapshot_release_and_restore(WT_SESSION_IMPL *session);
extern void __wt_txn_stats_update(WT_SESSION_IMPL *session);
extern void __wt_txn_truncate_end(WT_SESSION_IMPL *session);
extern void __wt_update_obsolete_check(
WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd, bool update_accounting);
WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd);
extern void __wt_update_vector_clear(WT_UPDATE_VECTOR *updates);
extern void __wt_update_vector_free(WT_UPDATE_VECTOR *updates);
extern void __wt_update_vector_init(WT_SESSION_IMPL *session, WT_UPDATE_VECTOR *updates);

View File

@ -286,6 +286,14 @@ __wt_update_serial(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_PAGE *page
/* Mark the page dirty after updating the footprint. */
__wt_page_modify_set(session, page);
/*
* If configured, skip checking for obsolete updates and they will be checked as part of the
* page reconciliation.
*/
if (F_ISSET_ATOMIC_16(
&S2C(session)->cache->cache_eviction_controls, WT_CACHE_SKIP_UPDATE_OBSOLETE_CHECK))
return (0);
/*
* Don't remove obsolete updates in the history store, due to having different visibility rules
* compared to normal tables. This visibility rule allows different readers to concurrently read
@ -325,7 +333,7 @@ __wt_update_serial(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_PAGE *page
page->modify->obsolete_check_txn = WT_TXN_NONE;
}
__wt_update_obsolete_check(session, cbt, upd->next, true);
__wt_update_obsolete_check(session, cbt, upd->next);
return (0);
}

View File

@ -640,6 +640,7 @@ struct __wt_connection_stats {
int64_t cache_eviction_trigger_dirty_reached;
int64_t cache_eviction_trigger_reached;
int64_t cache_eviction_trigger_updates_reached;
int64_t cache_obsolete_updates_removed;
int64_t eviction_timed_out_ops;
int64_t cache_eviction_blocked_overflow_keys;
int64_t cache_read_overflow;
@ -1326,6 +1327,7 @@ struct __wt_dsrc_stats {
int64_t cache_eviction_trigger_dirty_reached;
int64_t cache_eviction_trigger_reached;
int64_t cache_eviction_trigger_updates_reached;
int64_t cache_obsolete_updates_removed;
int64_t cache_eviction_blocked_overflow_keys;
int64_t cache_read_overflow;
int64_t cache_eviction_deepen;

File diff suppressed because it is too large Load Diff

View File

@ -237,16 +237,17 @@ err:
}
/*
* __rec_find_and_save_delete_hs_upd --
* Find and save the update that needs to be deleted from the history store later
* __rec_save_delete_hs_upd_and_free_obs_updates --
* Find and save the update that needs to be deleted from the history store later and also free
* the obsolete updates in the update chain.
*/
static int
__rec_find_and_save_delete_hs_upd(WT_SESSION_IMPL *session, WTI_RECONCILE *r, WT_INSERT *ins,
WT_ROW *rip, WTI_UPDATE_SELECT *upd_select)
__rec_save_delete_hs_upd_and_free_obs_updates(WT_SESSION_IMPL *session, WTI_RECONCILE *r,
WT_INSERT *ins, WT_ROW *rip, WTI_UPDATE_SELECT *upd_select)
{
WT_UPDATE *delete_tombstone, *delete_upd;
WT_UPDATE *delete_tombstone, *delete_upd, *visible_all_upd;
delete_tombstone = NULL;
delete_tombstone = visible_all_upd = NULL;
for (delete_upd = upd_select->tombstone != NULL ? upd_select->tombstone : upd_select->upd;
delete_upd != NULL; delete_upd = delete_upd->next) {
@ -263,9 +264,21 @@ __rec_find_and_save_delete_hs_upd(WT_SESSION_IMPL *session, WTI_RECONCILE *r, WT
else {
WT_RET(
__rec_delete_hs_upd_save(session, r, ins, rip, delete_upd, delete_tombstone));
visible_all_upd = NULL;
break;
}
}
/* Track the first self-contained value that is globally visible. */
if (F_ISSET(r, WT_REC_CHECKPOINT) && visible_all_upd == NULL && delete_upd->next != NULL &&
__wt_txn_upd_visible_all(session, delete_upd) && WT_UPDATE_DATA_VALUE(delete_upd))
visible_all_upd = delete_upd;
}
/* Free obsolete updates, excluding the on-page tombstone if exist. */
if (visible_all_upd != NULL && visible_all_upd != upd_select->tombstone) {
__wt_free_obsolete_updates(session, r->page, visible_all_upd);
WT_STAT_CONN_DSRC_INCR(session, cache_obsolete_updates_removed);
}
WT_ASSERT_ALWAYS(session, delete_tombstone == NULL || delete_upd != NULL,
@ -977,7 +990,8 @@ __wti_rec_upd_select(WT_SESSION_IMPL *session, WTI_RECONCILE *r, WT_INSERT *ins,
* chain but the same value is left in the history store. Save it to delete it from the history
* store later.
*/
WT_RET(__rec_find_and_save_delete_hs_upd(session, r, ins, rip, upd_select));
if (F_ISSET(r, WT_REC_HS))
WT_RET(__rec_save_delete_hs_upd_and_free_obs_updates(session, r, ins, rip, upd_select));
/* Check the update chain for conditions that could prevent it's eviction. */
WT_RET(__rec_validate_upd_chain(session, r, onpage_upd, &upd_select->tw, vpack));

View File

@ -120,6 +120,7 @@ static const char *const __stats_dsrc_desc[] = {
"cache: number of times dirty trigger was reached",
"cache: number of times eviction trigger was reached",
"cache: number of times updates trigger was reached",
"cache: obsolete updates removed",
"cache: overflow keys on a multiblock row-store page blocked its eviction",
"cache: overflow pages read into cache",
"cache: page split during eviction deepened the tree",
@ -478,6 +479,7 @@ __wt_stat_dsrc_clear_single(WT_DSRC_STATS *stats)
stats->cache_eviction_trigger_dirty_reached = 0;
stats->cache_eviction_trigger_reached = 0;
stats->cache_eviction_trigger_updates_reached = 0;
stats->cache_obsolete_updates_removed = 0;
stats->cache_eviction_blocked_overflow_keys = 0;
stats->cache_read_overflow = 0;
stats->cache_eviction_deepen = 0;
@ -823,6 +825,7 @@ __wt_stat_dsrc_aggregate_single(WT_DSRC_STATS *from, WT_DSRC_STATS *to)
to->cache_eviction_trigger_dirty_reached += from->cache_eviction_trigger_dirty_reached;
to->cache_eviction_trigger_reached += from->cache_eviction_trigger_reached;
to->cache_eviction_trigger_updates_reached += from->cache_eviction_trigger_updates_reached;
to->cache_obsolete_updates_removed += from->cache_obsolete_updates_removed;
to->cache_eviction_blocked_overflow_keys += from->cache_eviction_blocked_overflow_keys;
to->cache_read_overflow += from->cache_read_overflow;
to->cache_eviction_deepen += from->cache_eviction_deepen;
@ -1186,6 +1189,7 @@ __wt_stat_dsrc_aggregate(WT_DSRC_STATS **from, WT_DSRC_STATS *to)
to->cache_eviction_trigger_reached += WT_STAT_DSRC_READ(from, cache_eviction_trigger_reached);
to->cache_eviction_trigger_updates_reached +=
WT_STAT_DSRC_READ(from, cache_eviction_trigger_updates_reached);
to->cache_obsolete_updates_removed += WT_STAT_DSRC_READ(from, cache_obsolete_updates_removed);
to->cache_eviction_blocked_overflow_keys +=
WT_STAT_DSRC_READ(from, cache_eviction_blocked_overflow_keys);
to->cache_read_overflow += WT_STAT_DSRC_READ(from, cache_read_overflow);
@ -1661,6 +1665,7 @@ static const char *const __stats_connection_desc[] = {
"cache: number of times dirty trigger was reached",
"cache: number of times eviction trigger was reached",
"cache: number of times updates trigger was reached",
"cache: obsolete updates removed",
"cache: operations timed out waiting for space in cache",
"cache: overflow keys on a multiblock row-store page blocked its eviction",
"cache: overflow pages read into cache",
@ -2509,6 +2514,7 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats)
stats->cache_eviction_trigger_dirty_reached = 0;
stats->cache_eviction_trigger_reached = 0;
stats->cache_eviction_trigger_updates_reached = 0;
stats->cache_obsolete_updates_removed = 0;
stats->eviction_timed_out_ops = 0;
stats->cache_eviction_blocked_overflow_keys = 0;
stats->cache_read_overflow = 0;
@ -3383,6 +3389,7 @@ __wt_stat_connection_aggregate(WT_CONNECTION_STATS **from, WT_CONNECTION_STATS *
to->cache_eviction_trigger_reached += WT_STAT_CONN_READ(from, cache_eviction_trigger_reached);
to->cache_eviction_trigger_updates_reached +=
WT_STAT_CONN_READ(from, cache_eviction_trigger_updates_reached);
to->cache_obsolete_updates_removed += WT_STAT_CONN_READ(from, cache_obsolete_updates_removed);
to->eviction_timed_out_ops += WT_STAT_CONN_READ(from, eviction_timed_out_ops);
to->cache_eviction_blocked_overflow_keys +=
WT_STAT_CONN_READ(from, cache_eviction_blocked_overflow_keys);

View File

@ -46,10 +46,10 @@ class test_cache_evict_config01(wttest.WiredTigerTestCase):
# Try different eviction reconfigurations.
configs = [
"eviction=[prefer_scrub_eviction=true,cache_tolerance_for_app_eviction=0]",
"eviction=[prefer_scrub_eviction=false,cache_tolerance_for_app_eviction=100]",
"eviction=[prefer_scrub_eviction=false,cache_tolerance_for_app_eviction=25]",
"eviction=[prefer_scrub_eviction=true,cache_tolerance_for_app_eviction=20]",
"eviction=[skip_update_obsolete_check=false,prefer_scrub_eviction=true,cache_tolerance_for_app_eviction=0]",
"eviction=[skip_update_obsolete_check=true,prefer_scrub_eviction=false,cache_tolerance_for_app_eviction=100]",
"eviction=[skip_update_obsolete_check=false,prefer_scrub_eviction=false,cache_tolerance_for_app_eviction=25]",
"eviction=[skip_update_obsolete_check=true,prefer_scrub_eviction=true,cache_tolerance_for_app_eviction=20]",
]
# Try different eviction failure reconfigurations.

View File

@ -0,0 +1,153 @@
#!/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 threading, time
import wttest
import wiredtiger
from wtdataset import SimpleDataSet
from wtscenario import make_scenarios
from wiredtiger import stat
# test_checkpoint37.py
#
# Test that reconciliation removes obsolete updates on the page.
class test_checkpoint37(wttest.WiredTigerTestCase):
conn_config = 'eviction=[skip_update_obsolete_check=true]'
format_values = [
('column', dict(key_format='r', value_format='S', extraconfig='')),
('column_fix', dict(key_format='r', value_format='8t',
extraconfig=',allocation_size=512,leaf_page_max=512')),
('string_row', dict(key_format='S', value_format='S', extraconfig='')),
]
scenarios = make_scenarios(format_values)
def large_updates(self, uri, ds, nrows, value, ts):
cursor = self.session.open_cursor(uri)
self.session.begin_transaction()
for i in range(1, nrows + 1):
cursor[ds.key(i)] = value
if i % 101 == 0:
self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(ts))
self.session.begin_transaction()
self.session.commit_transaction('commit_timestamp=' + self.timestamp_str(ts))
cursor.close()
def check(self, ds, nrows, value):
cursor = self.session.open_cursor(ds.uri)
count = 0
for k, v in cursor:
self.assertEqual(v, value)
count += 1
self.assertEqual(count, nrows)
cursor.close()
def get_stat(self, stat):
stat_cursor = self.session.open_cursor('statistics:')
val = stat_cursor[stat][2]
stat_cursor.close()
return val
def test_checkpoint(self):
uri = 'table:checkpoint37'
nrows = 1000
# Create a table.
ds = SimpleDataSet(
self, uri, 0, key_format=self.key_format, value_format=self.value_format,
config=self.extraconfig)
ds.populate()
if self.value_format == '8t':
value_a = 97
value_b = 98
value_c = 99
value_d = 100
value_e = 101
else:
value_a = "aaaaa" * 10
value_b = "bbbbb" * 10
value_c = "ccccc" * 10
value_d = "ddddd" * 10
value_e = "eeeee" * 10
# Write some initial data.
self.large_updates(ds.uri, ds, nrows, value_a, 5)
# Pin oldest and stable timestamps to 5.
self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(5) +
',stable_timestamp=' + self.timestamp_str(5))
# Checkpoint and reopen the connection to read from the on-disk version.
self.session.checkpoint()
self.reopen_conn()
# Add updates to each key to check whether they free on reconciliation.
self.large_updates(ds.uri, ds, nrows, value_b, 10)
prev_bytes_in_use = self.get_stat(stat.conn.cache_bytes_inuse)
self.large_updates(ds.uri, ds, nrows, value_c, 20)
# Pin oldest and stable timestamps to 20.
self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(20) +
',stable_timestamp=' + self.timestamp_str(20))
# Checkpoint.
self.session.checkpoint()
bytes_in_use = self.get_stat(stat.conn.cache_bytes_inuse)
self.assertLess(bytes_in_use, prev_bytes_in_use * 2)
# Another set of updates.
self.large_updates(ds.uri, ds, nrows, value_d, 30)
# Pin oldest and stable timestamps to 30.
self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(30) +
',stable_timestamp=' + self.timestamp_str(30))
# Checkpoint.
self.session.checkpoint()
bytes_in_use = self.get_stat(stat.conn.cache_bytes_inuse)
self.assertLess(bytes_in_use, prev_bytes_in_use * 2)
# Another set of updates.
self.large_updates(ds.uri, ds, nrows, value_e, 40)
# Pin oldest and stable timestamps to 40.
self.conn.set_timestamp('oldest_timestamp=' + self.timestamp_str(40) +
',stable_timestamp=' + self.timestamp_str(40))
# Checkpoint.
self.session.breakpoint()
self.session.checkpoint()
bytes_in_use = self.get_stat(stat.conn.cache_bytes_inuse)
self.assertLess(bytes_in_use, prev_bytes_in_use * 2)
self.assertGreater(self.get_stat(stat.conn.cache_obsolete_updates_removed), 0)
if __name__ == '__main__':
wttest.run()