From e7ead1c8cfb9d3e9e6800b7e15ac8f1621c2fc1b Mon Sep 17 00:00:00 2001 From: "wt-vendoring-bot[bot]" <169275211+wt-vendoring-bot[bot]@users.noreply.github.com> Date: Tue, 26 May 2026 11:33:17 +1000 Subject: [PATCH] Import wiredtiger: 3c6ec61a01a4dbdb3351121c0a624d3996e28c03 from branch mongodb-master (#54418) Co-authored-by: wt-vendoring-bot GitOrigin-RevId: 0bbb8b1c0435ef423df293b6af6f4a39fdb390df --- src/third_party/wiredtiger/CMakePresets.json | 14 + .../wiredtiger/cmake/configs/auto.cmake | 186 ---- .../pthread_cond_monotonic_test.c | 40 - .../cmake/configs/wiredtiger_config.h.in | 107 +-- .../cmake/define_libwiredtiger.cmake | 18 +- .../wiredtiger/cmake/helpers.cmake | 335 +++----- .../wiredtiger/cmake/install/install.cmake | 15 +- .../wiredtiger/cmake/third_party/iaa.cmake | 31 +- .../wiredtiger/cmake/third_party/lz4.cmake | 32 +- .../cmake/third_party/memkind.cmake | 34 +- .../cmake/third_party/pthread.cmake | 17 + .../wiredtiger/cmake/third_party/snappy.cmake | 32 +- .../wiredtiger/cmake/third_party/sodium.cmake | 30 +- .../cmake/third_party/sqlite3.cmake | 9 +- .../wiredtiger/cmake/third_party/zlib.cmake | 32 +- .../wiredtiger/cmake/third_party/zstd.cmake | 32 +- src/third_party/wiredtiger/dist/docs_data.py | 5 + src/third_party/wiredtiger/dist/s_define.list | 2 - src/third_party/wiredtiger/dist/s_stat | 1 + src/third_party/wiredtiger/dist/stat_data.py | 1 + src/third_party/wiredtiger/import.data | 2 +- .../wiredtiger/src/block/block_ckpt.c | 392 +++++---- .../wiredtiger/src/conn/conn_layered_ingest.c | 27 +- .../wiredtiger/src/cursor/cur_ds.c | 15 + .../wiredtiger/src/cursor/cur_file.c | 32 + .../wiredtiger/src/cursor/cur_layered.c | 30 +- .../wiredtiger/src/cursor/cur_table.c | 22 + .../wiredtiger/src/docs/arch-index.dox | 2 + .../wiredtiger/src/docs/arch-page-delta.dox | 154 ++++ src/third_party/wiredtiger/src/docs/spell.ok | 4 + src/third_party/wiredtiger/src/include/api.h | 73 +- .../wiredtiger/src/include/extern.h | 4 + .../src/include/load_control_inline.h | 17 + .../wiredtiger/src/include/session.h | 11 +- .../wiredtiger/src/include/session_inline.h | 66 ++ src/third_party/wiredtiger/src/include/stat.h | 1 + .../wiredtiger/src/include/wiredtiger.h.in | 798 +++++++++--------- .../wiredtiger/src/include/wt_internal.h | 1 + .../wiredtiger/src/os_win/os_thread.c | 2 +- .../prepared_discover_walk.c | 4 + .../wiredtiger/src/session/session_api.c | 2 +- src/third_party/wiredtiger/src/support/stat.c | 3 + .../catch2/misc_tests/test_assertions.cpp | 2 +- .../misc_tests/test_single_thread_check.cpp | 50 ++ .../wiredtiger/test/csuite/config/main.c | 6 +- .../test/suite/test_layered_prepare02.py | 168 ++++ 46 files changed, 1504 insertions(+), 1357 deletions(-) delete mode 100644 src/third_party/wiredtiger/cmake/configs/auto.cmake delete mode 100644 src/third_party/wiredtiger/cmake/configs/compile_test/pthread_cond_monotonic_test.c create mode 100644 src/third_party/wiredtiger/cmake/third_party/pthread.cmake create mode 100644 src/third_party/wiredtiger/src/docs/arch-page-delta.dox create mode 100644 src/third_party/wiredtiger/src/include/session_inline.h create mode 100644 src/third_party/wiredtiger/test/catch2/misc_tests/test_single_thread_check.cpp create mode 100644 src/third_party/wiredtiger/test/suite/test_layered_prepare02.py diff --git a/src/third_party/wiredtiger/CMakePresets.json b/src/third_party/wiredtiger/CMakePresets.json index 1a3c8c84a2c..3e78ebe134f 100644 --- a/src/third_party/wiredtiger/CMakePresets.json +++ b/src/third_party/wiredtiger/CMakePresets.json @@ -1,8 +1,13 @@ { "version": 3, "configurePresets": [ + { + "name": "default", + "displayName": "Default" + }, { "name": "linux", + "inherits": "default", "hidden": true, "condition": { "type": "equals", @@ -15,6 +20,7 @@ }, { "name": "linux-v4", + "inherits": "default", "hidden": true, "condition": { "type": "equals", @@ -52,5 +58,13 @@ "CMAKE_CXX_COMPILER": "$env{MONGODBTOOLCHAIN_BIN}/g++" } } + ], + "buildPresets": [ + { + "name": "default", + "displayName": "Default", + "configurePreset": "default", + "jobs": 0 + } ] } diff --git a/src/third_party/wiredtiger/cmake/configs/auto.cmake b/src/third_party/wiredtiger/cmake/configs/auto.cmake deleted file mode 100644 index 36dd9259857..00000000000 --- a/src/third_party/wiredtiger/cmake/configs/auto.cmake +++ /dev/null @@ -1,186 +0,0 @@ -include(cmake/helpers.cmake) - -### Auto configure options and checks that we can infer from our toolchain environment. - -config_include( - HAVE_X86INTRIN_H - "Include header x86intrin.h exists." - FILE "x86intrin.h" -) - -config_include( - HAVE_ARM_NEON_INTRIN_H - "Include header arm_neon.h exists." - FILE "arm_neon.h" -) - -config_func( - HAVE_FALLOCATE - "Function fallocate exists." - FUNC "fallocate" - FILES "fcntl.h" -) - -config_func( - HAVE_FDATASYNC - "Function fdatasync exists." - FUNC "fdatasync" - FILES "unistd.h" - DEPENDS "NOT WT_DARWIN" -) - -config_func( - HAVE_CLOCK_GETTIME - "Function clock_gettime exists." - FUNC "clock_gettime" - FILES "time.h" -) - -config_func( - HAVE_GETTIMEOFDAY - "Function gettimeofday exists." - FUNC "gettimeofday" - FILES "sys/time.h" -) - -config_func( - HAVE_POSIX_FADVISE - "Function posix_fadvise exists." - FUNC "posix_fadvise" - FILES "fcntl.h" -) - -config_func( - HAVE_POSIX_FALLOCATE - "Function posix_fallocate exists." - FUNC "posix_fallocate" - FILES "fcntl.h" -) - -config_func( - HAVE_POSIX_MADVISE - "Function posix_madvise exists." - FUNC "posix_madvise" - FILES "sys/mman.h" -) - -config_func( - HAVE_POSIX_MEMALIGN - "Function posix_memalign exists." - FUNC "posix_memalign" - FILES "stdlib.h" -) - -config_func( - HAVE_SETRLIMIT - "Function setrlimit exists." - FUNC "setrlimit" - FILES "sys/time.h;sys/resource.h" -) - -config_func( - HAVE_SYNC_FILE_RANGE - "Function sync_file_range exists." - FUNC "sync_file_range" - FILES "fcntl.h" -) - -config_func( - HAVE_TIMER_CREATE - "Function timer_create exists." - FUNC "timer_create" - FILES "signal.h;time.h" - LIBS "rt" -) - -config_lib( - HAVE_LIBMEMKIND - "memkind library exists." - LIB "memkind" - HEADER "memkind.h" -) - -config_lib( - HAVE_LIBPTHREAD - "Pthread library exists." - LIB "pthread" -) - -config_lib( - HAVE_LIBRT - "rt library exists." - LIB "rt" -) - -config_lib( - HAVE_LIBDL - "dl library exists." - LIB "dl" -) - -config_lib( - HAVE_LIBCXX - "stdc++ library exists." - LIB "stdc++" -) - -config_lib( - HAVE_LIBACCEL_CONFIG - "accel-config library exists." - LIB "accel-config" -) - -config_lib( - HAVE_LIBLZ4 - "lz4 library exists." - LIB "lz4" - HEADER "lz4.h" -) - -config_lib( - HAVE_LIBSNAPPY - "snappy library exists." - LIB "snappy" - HEADER "snappy.h" -) - -config_lib( - HAVE_LIBZ - "zlib library exists." - LIB "z" - HEADER "zlib.h" -) - -config_lib( - HAVE_LIBZSTD - "zstd library exists." - LIB "zstd" - HEADER "zstd.h" -) - -config_lib( - HAVE_LIBQPL - "qpl library exists." - LIB "qpl" - HEADER "qpl/qpl.h" -) - -config_lib( - HAVE_LIBSODIUM - "sodium library exists." - LIB "sodium" - HEADER "sodium.h" -) - -config_compile( - HAVE_PTHREAD_COND_MONOTONIC - "If pthread condition variables support monotonic clocks." - SOURCE "${CMAKE_CURRENT_LIST_DIR}/compile_test/pthread_cond_monotonic_test.c" - LIBS "pthread" - DEPENDS "HAVE_LIBPTHREAD" -) - -set(WORDS_BIGENDIAN FALSE) -if(${CMAKE_C_BYTE_ORDER} STREQUAL "BIG_ENDIAN") - set(WORDS_BIGENDIAN TRUE) -endif() diff --git a/src/third_party/wiredtiger/cmake/configs/compile_test/pthread_cond_monotonic_test.c b/src/third_party/wiredtiger/cmake/configs/compile_test/pthread_cond_monotonic_test.c deleted file mode 100644 index 64645ec889f..00000000000 --- a/src/third_party/wiredtiger/cmake/configs/compile_test/pthread_cond_monotonic_test.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2014-present MongoDB, Inc. - * Copyright (c) 2008-2014 WiredTiger, Inc. - * All rights reserved. - * - * See the file LICENSE for redistribution information. - */ - -#include -#include -#include -#include - -int -main() -{ - int ret; - pthread_condattr_t condattr; - pthread_cond_t cond; - pthread_mutex_t mtx; - struct timespec ts; - - if ((ret = pthread_condattr_init(&condattr)) != 0) - exit(1); - if ((ret = pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC)) != 0) - exit(1); - if ((ret = pthread_cond_init(&cond, &condattr)) != 0) - exit(1); - if ((ret = pthread_mutex_init(&mtx, NULL)) != 0) - exit(1); - if ((ret = clock_gettime(CLOCK_MONOTONIC, &ts)) != 0) - exit(1); - ts.tv_sec += 1; - if ((ret = pthread_mutex_lock(&mtx)) != 0) - exit(1); - if ((ret = pthread_cond_timedwait(&cond, &mtx, &ts)) != 0 && ret != EINTR && ret != ETIMEDOUT) - exit(1); - - exit(0); -} diff --git a/src/third_party/wiredtiger/cmake/configs/wiredtiger_config.h.in b/src/third_party/wiredtiger/cmake/configs/wiredtiger_config.h.in index a82493af727..964fb0d7ecb 100644 --- a/src/third_party/wiredtiger/cmake/configs/wiredtiger_config.h.in +++ b/src/third_party/wiredtiger/cmake/configs/wiredtiger_config.h.in @@ -70,95 +70,54 @@ */ #cmakedefine HAVE_UNITTEST_ASSERTS 1 -/* Define to 1 if you have the `fallocate' function. */ -#cmakedefine HAVE_FALLOCATE 1 - -/* Define to 1 if you have the `fdatasync' function. */ -#cmakedefine HAVE_FDATASYNC 1 - -/* Define to 1 if you have the `clock_gettime' function. */ -#cmakedefine HAVE_CLOCK_GETTIME 1 - -/* Define to 1 if you have the `gettimeofday' function. */ -#cmakedefine HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the `dl' library (-ldl). */ -#cmakedefine HAVE_LIBDL 1 - -/* Define to 1 if you have the `stdc++' library (-lstdc++). */ -#cmakedefine HAVE_LIBCXX 1 - -/* Define to 1 if you have the `accel-config' library (-laccel-config). */ -#cmakedefine HAVE_LIBACCEL_CONFIG 1 - -/* Define to 1 if you have the `lz4' library (-llz4). */ -#cmakedefine HAVE_LIBLZ4 1 - -/* Define to 1 if you have the `memkind' library (-lmemkind). */ -#cmakedefine HAVE_LIBMEMKIND 1 - -/* Define to 1 if the user has explicitly enable memkind builds. */ +/* Define to 1 if the user has explicitly enabled memkind builds. */ #cmakedefine ENABLE_MEMKIND 1 -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#cmakedefine HAVE_LIBPTHREAD 1 - -/* Define to 1 if you have the `rt' library (-lrt). */ -#cmakedefine HAVE_LIBRT 1 - -/* Define to 1 if you have the `snappy' library (-lsnappy). */ -#cmakedefine HAVE_LIBSNAPPY 1 - /* Define to 1 if the user has set enable antithesis. */ #cmakedefine ENABLE_ANTITHESIS 1 -/* Define to 1 if you have the `z' library (-lz). */ -#cmakedefine HAVE_LIBZ 1 - -/* Define to 1 if you have the `zstd' library (-lzstd). */ -#cmakedefine HAVE_LIBZSTD 1 - -/* Define to 1 if you have the `qpl' library (-lqpl). */ -#cmakedefine HAVE_LIBQPL 1 - -/* Define to 1 if you have the `sodium' library (-lsodium). */ -#cmakedefine HAVE_LIBSODIUM 1 - /* Automatically set by the build system, turns on or off optional RCpc ARM instructions. */ #cmakedefine HAVE_RCPC 1 /* Define to 1 to disable any crc32 hardware support. */ -#cmakedefine HAVE_NO_CRC32_HARDWARE +#cmakedefine HAVE_NO_CRC32_HARDWARE 1 -/* Define to 1 if you have the `posix_fadvise' function. */ -#cmakedefine HAVE_POSIX_FADVISE 1 +/* + * Compile-time platform feature flags. + */ -/* Define to 1 if you have the `posix_fallocate' function. */ -#cmakedefine HAVE_POSIX_FALLOCATE 1 +/* POSIX.1-2001 functions available on every supported POSIX target. */ +#if defined(__linux__) || defined(__APPLE__) || defined(__NetBSD__) +#define HAVE_CLOCK_GETTIME 1 +#define HAVE_GETTIMEOFDAY 1 +#define HAVE_POSIX_MADVISE 1 +#define HAVE_POSIX_MEMALIGN 1 +#define HAVE_SETRLIMIT 1 +#endif -/* Define to 1 if you have the `posix_madvise' function. */ -#cmakedefine HAVE_POSIX_MADVISE 1 +/* POSIX functions macOS does not implement. */ +#if defined(__linux__) || defined(__NetBSD__) +#define HAVE_FDATASYNC 1 +#define HAVE_POSIX_FADVISE 1 +#define HAVE_POSIX_FALLOCATE 1 +#define HAVE_PTHREAD_COND_MONOTONIC 1 +#define HAVE_TIMER_CREATE 1 +#endif -/* Define to 1 if `posix_memalign' works. */ -#cmakedefine HAVE_POSIX_MEMALIGN 1 +/* Linux-specific syscalls and extensions. */ +#if defined(__linux__) +#define HAVE_FALLOCATE 1 +#define HAVE_SYNC_FILE_RANGE 1 +#endif -/* Define to 1 if pthread condition variables support monotonic clocks. */ -#cmakedefine HAVE_PTHREAD_COND_MONOTONIC 1; +/* Architecture-specific intrinsic headers. */ +#if defined(__x86_64__) || defined(_M_X64) +#define HAVE_X86INTRIN_H 1 +#endif -/* Define to 1 if you have the `setrlimit' function. */ -#cmakedefine HAVE_SETRLIMIT 1 - -/* Define to 1 if you have the `sync_file_range' function. */ -#cmakedefine HAVE_SYNC_FILE_RANGE 1 - -/* Define to 1 if you have the `timer_create' function. */ -#cmakedefine HAVE_TIMER_CREATE 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_X86INTRIN_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_ARM_NEON_INTRIN_H 1 +#if defined(__aarch64__) || defined(_M_ARM64) +#define HAVE_ARM_NEON_INTRIN_H 1 +#endif /* Spinlock type from mutex.h. */ #cmakedefine SPINLOCK_TYPE @SPINLOCK_TYPE_CONFIG_VAR@ diff --git a/src/third_party/wiredtiger/cmake/define_libwiredtiger.cmake b/src/third_party/wiredtiger/cmake/define_libwiredtiger.cmake index 0962864f2fc..753e9c589ca 100644 --- a/src/third_party/wiredtiger/cmake/define_libwiredtiger.cmake +++ b/src/third_party/wiredtiger/cmake/define_libwiredtiger.cmake @@ -50,15 +50,10 @@ macro(define_wiredtiger_library target type) C_STANDARD 11 ) - # Ensure we link any available library dependencies to our wiredtiger target. - if(HAVE_LIBPTHREAD) - target_link_libraries(${target} PUBLIC ${HAVE_LIBPTHREAD}) - endif() - if(HAVE_LIBRT) - target_link_libraries(${target} PUBLIC ${HAVE_LIBRT}) - endif() - if(HAVE_LIBDL) - target_link_libraries(${target} PUBLIC ${HAVE_LIBDL}) + # System library dependencies. + target_link_libraries(${target} PUBLIC Threads::Threads ${CMAKE_DL_LIBS}) + if(WT_LINUX) + target_link_libraries(${target} PUBLIC rt) endif() if(ENABLE_MEMKIND) target_link_libraries(${target} PRIVATE wt::memkind) @@ -88,11 +83,8 @@ macro(define_wiredtiger_library target type) if(HAVE_BUILTIN_EXTENSION_IAA) target_link_libraries(${target} PRIVATE iaacodec) - if(HAVE_LIBCXX) - target_link_libraries(${target} PRIVATE ${HAVE_LIBCXX}) - endif() if(HAVE_LIBACCEL_CONFIG) - target_link_libraries(${target} PRIVATE ${HAVE_LIBACCEL_CONFIG}) + target_link_libraries(${target} PRIVATE wt::accel_config) endif() endif() diff --git a/src/third_party/wiredtiger/cmake/helpers.cmake b/src/third_party/wiredtiger/cmake/helpers.cmake index 06aeafed3c2..a1594c4f2c8 100644 --- a/src/third_party/wiredtiger/cmake/helpers.cmake +++ b/src/third_party/wiredtiger/cmake/helpers.cmake @@ -1,8 +1,3 @@ -include(CheckIncludeFiles) -include(CheckSymbolExists) -include(CheckLibraryExists) -include(CheckTypeSize) - # Helper function for evaluating a list of dependencies. Mostly used by the # "config_X" helpers to evaluate the dependencies required to enable the config # option. @@ -244,248 +239,132 @@ function(config_bool config_name description) endif() endfunction() -# config_func(config_name description FUNC FILE [DEPENDS ] [LIBS ]) -# Defines a boolean (0/1) configuration option based on whether a given function symbol exists. -# The configuration option is stored in the cmake cache and can be exported to the wiredtiger config header. -# config_name - name of the configuration option. -# description - docstring to describe the configuration option (viewable in the cmake-gui). -# FUNC - function symbol we want to search for. -# FILE - header we expect the function symbol to be defined e.g a std header. -# DEPENDS - list of dependencies (semicolon separated) required for the configuration to be evaluated. -# If any of the dependencies aren't met the configuration value will be set to '0' (false). -# LIBS - a list of any additional library dependencies needed to successfully link with the function symbol. -function(config_func config_name description) +# wt_find_library(NAME +# [CMAKE_TARGET ] +# [PACKAGE TARGET ] +# [PKGCONFIG_MODULE ] +# [LIBRARY ] +# [HEADER ]) +# +# Discover a third-party library through CMake's canonical lookup chain: +# +# 1. find_package( QUIET) +# Tries MODULE mode (CMake-shipped Find.cmake) then CONFIG mode +# (library-shipped Config.cmake). +# 2. pkg_check_modules(... IMPORTED_TARGET ) +# Falls back to pkg-config metadata. +# 3. find_library() + find_path(
) +# Raw filesystem search; constructs an UNKNOWN IMPORTED target. +# +# Each step is attempted only if the relevant arguments are provided. The first +# successful step wins; the rest are skipped. +# +# On success: +# HAVE_LIB${upper(NAME)} cache variable set ON. +# wt::${CMAKE_TARGET or NAME} alias created from the discovered imported target. +# On failure: +# HAVE_LIB${upper(NAME)} cache variable set OFF. +# +# Examples: +# wt_find_library(NAME lz4 +# PACKAGE lz4 TARGET LZ4::lz4 +# PKGCONFIG_MODULE liblz4 +# HEADER lz4.h) +# +# wt_find_library(NAME z CMAKE_TARGET zlib +# PACKAGE ZLIB TARGET ZLIB::ZLIB +# PKGCONFIG_MODULE zlib +# HEADER zlib.h) +function(wt_find_library) cmake_parse_arguments( PARSE_ARGV - 2 - "CONFIG_FUNC" + 0 + "WTLIB" "" - "FUNC;DEPENDS;FILES;LIBS" + "NAME;CMAKE_TARGET;PACKAGE;TARGET;PKGCONFIG_MODULE;LIBRARY;HEADER" "" ) - if (NOT "${CONFIG_FUNC_UNPARSED_ARGUMENTS}" STREQUAL "") - message(FATAL_ERROR "Unknown arguments to config_func: ${CONFIG_FUNC_UNPARSED_ARGUMENTS}") + if(NOT WTLIB_NAME) + message(FATAL_ERROR "wt_find_library: NAME is required") endif() - # We require an include header (not optional). - if ("${CONFIG_FUNC_FILES}" STREQUAL "") - message(FATAL_ERROR "No file list passed") - endif() - # We require a function symbol (not optional). - if ("${CONFIG_FUNC_FUNC}" STREQUAL "") - message(FATAL_ERROR "No function passed") + if(WTLIB_PACKAGE AND NOT WTLIB_TARGET) + message(FATAL_ERROR "wt_find_library(${WTLIB_NAME}): PACKAGE requires TARGET") endif() - # Check that the configs dependencies are enabled before setting it to a visible enabled state. - eval_dependency("${CONFIG_FUNC_DEPENDS}" enabled) - if(enabled) - set(CMAKE_REQUIRED_LIBRARIES "${CONFIG_FUNC_LIBS}") - check_symbol_exists(${CONFIG_FUNC_FUNC} "${CONFIG_FUNC_FILES}" has_symbol_${config_name}) - set(CMAKE_REQUIRED_LIBRARIES) - set(has_symbol "0") - if(has_symbol_${config_name}) - set(has_symbol ${has_symbol_${config_name}}) - endif() - # Set an internal cache variable "${config_name}_DISABLED" to capture its enabled/disabled state. - # We want to ensure we capture a transition from a disabled to enabled state when dependencies are met. - if(${config_name}_DISABLED) - unset(${config_name}_DISABLED CACHE) - set(${config_name} ${has_symbol} CACHE BOOL "${description}" FORCE) - else() - set(${config_name} ${has_symbol} CACHE BOOL "${description}") - endif() - # 'check_symbol_exists' sets our given temp variable into the cache. Clear this so it doesn't persist between - # configuration runs. - unset(has_symbol_${config_name} CACHE) + string(TOUPPER "${WTLIB_NAME}" _name_upper) + set(_have_var "HAVE_LIB${_name_upper}") + + if(WTLIB_CMAKE_TARGET) + set(_alias "wt::${WTLIB_CMAKE_TARGET}") else() - # Config doesn't meet dependency requirements, set a disabled state. - set(${config_name} OFF CACHE INTERNAL "" FORCE) - set(${config_name}_DISABLED ON CACHE INTERNAL "" FORCE) - endif() -endfunction() - - -# config_include(config_name description FILE [DEPENDS ]) -# Defines a boolean (0/1) configuration option based on whether a given include header exists. -# The configuration option is stored in the cmake cache and can be exported to the wiredtiger config header. -# config_name - name of the configuration option. -# description - docstring to describe the configuration option (viewable in the cmake-gui). -# FILE - header we want to search for e.g a std header. -# DEPENDS - list of dependencies (semicolon separated) required for the configuration to be evaluated. -# If any of the dependencies aren't met the configuration value will be set to '0' (false). -function(config_include config_name description) - cmake_parse_arguments( - PARSE_ARGV - 2 - "CONFIG_INCLUDE" - "" - "FILE;DEPENDS" - "" - ) - - if (NOT "${CONFIG_INCLUDE_UNPARSED_ARGUMENTS}" STREQUAL "") - message(FATAL_ERROR "Unknown arguments to config_include: ${CONFIG_INCLUDE_UNPARSED_ARGUMENTS}") - endif() - # We require a include header (not optional). - if ("${CONFIG_INCLUDE_FILE}" STREQUAL "") - message(FATAL_ERROR "No include file passed") + set(_alias "wt::${WTLIB_NAME}") endif() - # Check that the configs dependencies are enabled before setting it to a visible enabled state. - eval_dependency("${CONFIG_INCLUDE_DEPENDS}" enabled) - if(enabled) - check_include_files(${CONFIG_INCLUDE_FILE} has_include_${config_name}) - set(has_include "0") - if(has_include_${config_name}) - set(has_include ${has_include_${config_name}}) - endif() - # Set an internal cache variable "${config_name}_DISABLED" to capture its enabled/disabled state. - # We want to ensure we capture a transition from a disabled to enabled state when dependencies are met. - if(${config_name}_DISABLED) - unset(${config_name}_DISABLED CACHE) - set(${config_name} ${has_include} CACHE BOOL "${description}" FORCE) - else() - set(${config_name} ${has_include} CACHE BOOL "${description}") - endif() - # 'check_include_files' sets our given temp variable into the cache. Clear this so it doesn't persist between - # configuration runs. - unset(has_include_${config_name} CACHE) + # Guard against repeated work. + if(TARGET ${_alias}) + return() + endif() + + if(WTLIB_LIBRARY) + set(_libname "${WTLIB_LIBRARY}") else() - set(${config_name} OFF CACHE INTERNAL "" FORCE) - set(${config_name}_DISABLED ON CACHE INTERNAL "" FORCE) - endif() -endfunction() - -# config_lib(config_name description LIB FUNC [DEPENDS ] [HEADER ]) -# Defines a boolean (0/1) configuration option based on whether a given library exists. -# The configuration option is stored in the cmake cache and can be exported to the wiredtiger config header. -# config_name - name of the configuration option. -# description - docstring to describe the configuration option (viewable in the cmake-gui). -# LIB - library we are searching for (defined as if we are linking against it e.g -lpthread). -# FUNC - function symbol we expect to be available to link against within the library. -# DEPENDS - list of dependencies (semicolon separated) required for the configuration to be evaluated. -# If any of the dependencies aren't met the configuration value will be set to '0' (false). -function(config_lib config_name description) - cmake_parse_arguments( - PARSE_ARGV - 2 - "CONFIG_LIB" - "" - "LIB;DEPENDS;HEADER" - "" - ) - - if (NOT "${CONFIG_LIB_UNPARSED_ARGUMENTS}" STREQUAL "") - message(FATAL_ERROR "Unknown arguments to config_lib: ${CONFIG_LIB_UNPARSED_ARGUMENTS}") - endif() - # We require a library (not optional). - if ("${CONFIG_LIB_LIB}" STREQUAL "") - message(FATAL_ERROR "No library passed") + set(_libname "${WTLIB_NAME}") endif() - # Check that the configs dependencies are enabled before setting it to a visible enabled state. - eval_dependency("${CONFIG_LIB_DEPENDS}" enabled) - if(enabled) - message(CHECK_START "Looking for library ${CONFIG_LIB_LIB}") - find_library(has_lib_${config_name} ${CONFIG_LIB_LIB}) - set(has_lib "0") - set(has_include "") - if(has_lib_${config_name}) - set(has_lib ${has_lib_${config_name}}) - if (CONFIG_LIB_HEADER) - find_path(include_path_${config_name} ${CONFIG_LIB_HEADER}) - if (include_path_${config_name}) - message(CHECK_PASS "found ${has_lib_${config_name}}, include path ${include_path_${config_name}}") - set(has_include ${include_path_${config_name}}) - else() - message(CHECK_PASS "found ${has_lib_${config_name}}") - endif() - unset(include_path_${config_name} CACHE) - else() - message(CHECK_PASS "found ${has_lib_${config_name}}") + message(CHECK_START "Looking for library ${_libname}") + + set(_imported "") + + # Step 1: find_package (MODULE then CONFIG by default). + if(WTLIB_PACKAGE) + find_package(${WTLIB_PACKAGE} QUIET) + if(${WTLIB_PACKAGE}_FOUND AND TARGET ${WTLIB_TARGET}) + set(_imported ${WTLIB_TARGET}) + endif() + endif() + + # Step 2: pkg-config. + if(NOT _imported AND WTLIB_PKGCONFIG_MODULE) + find_package(PkgConfig QUIET) + if(PkgConfig_FOUND) + pkg_check_modules(${_name_upper} QUIET IMPORTED_TARGET ${WTLIB_PKGCONFIG_MODULE}) + if(${_name_upper}_FOUND) + set(_imported "PkgConfig::${_name_upper}") endif() - else() - message(CHECK_FAIL "not found") endif() - # Set an internal cache variable "${config_name}_DISABLED" to capture its enabled/disabled state. - # We want to ensure we capture a transition from a disabled to enabled state when dependencies are met. - if(${config_name}_DISABLED) - unset(${config_name}_DISABLED CACHE) - set(${config_name} ${has_lib} CACHE STRING "${description}" FORCE) - set(${config_name}_INCLUDES ${has_include} CACHE STRING "Additional include paths for ${config_name}" FORCE) - else() - set(${config_name} ${has_lib} CACHE STRING "${description}") - set(${config_name}_INCLUDES ${has_include} CACHE STRING "Additional include paths for ${config_name}") + endif() + + # Step 3: raw find_library + find_path. + if(NOT _imported) + find_library(${_name_upper}_LIBRARY ${_libname}) + if(WTLIB_HEADER) + find_path(${_name_upper}_INCLUDE_DIR ${WTLIB_HEADER}) endif() - # 'check_library_exists' sets our given temp variable into the cache. Clear this so it doesn't persist between - # configuration runs. - unset(has_lib_${config_name} CACHE) + if(${_name_upper}_LIBRARY AND (NOT WTLIB_HEADER OR ${_name_upper}_INCLUDE_DIR)) + set(_raw "wt_imported_${WTLIB_NAME}") + if(NOT TARGET ${_raw}) + add_library(${_raw} UNKNOWN IMPORTED GLOBAL) + set_target_properties(${_raw} PROPERTIES + IMPORTED_LOCATION "${${_name_upper}_LIBRARY}") + if(WTLIB_HEADER) + set_target_properties(${_raw} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${${_name_upper}_INCLUDE_DIR}") + endif() + endif() + set(_imported ${_raw}) + endif() + endif() + + if(_imported) + set(${_have_var} ON CACHE INTERNAL "${WTLIB_NAME} available on system") + if(NOT TARGET ${_alias}) + add_library(${_alias} ALIAS ${_imported}) + endif() + message(CHECK_PASS "found") else() - message(STATUS "Not looking for library ${CONFIG_LIB_LIB}: disabled") - set(${config_name} 0 CACHE INTERNAL "" FORCE) - set(${config_name}_DISABLED ON CACHE INTERNAL "" FORCE) - endif() -endfunction() - -# config_compile(config_name description SOURCE [DEPENDS ] [LIBS ]) -# Defines a boolean (0/1) configuration option based on whether a source file can be successfully compiled and run. Used -# to determine if more fine grained functionality is supported on a given target environment (beyond what function -# symbols, libraries and headers are available). The configuration option is stored in the cmake cache and can be -# exported to the wiredtiger config header. -# config_name - name of the configuration option. -# description - docstring to describe the configuration option (viewable in the cmake-gui). -# SOURCE - specific source file we want to test compile. -# DEPENDS - list of dependencies (semicolon separated) required for the configuration to be evaluated. -# If any of the dependencies aren't met the configuration value will be set to '0' (false). -# LIBS - a list of any additional library dependencies needed to successfully compile the source. -function(config_compile config_name description) - cmake_parse_arguments( - PARSE_ARGV - 2 - "CONFIG_COMPILE" - "" - "SOURCE;DEPENDS;LIBS" - "" - ) - - if (NOT "${CONFIG_COMPILE_UNPARSED_ARGUMENTS}" STREQUAL "") - message(FATAL_ERROR "Unknown arguments to config_compile: ${CONFIG_COMPILE_UNPARSED_ARGUMENTS}") - endif() - # We require a source file (not optional). - if ("${CONFIG_COMPILE_SOURCE}" STREQUAL "") - message(FATAL_ERROR "No source passed") - endif() - - # Check that the configs dependencies are enabled before setting it to a visible enabled state. - eval_dependency("${CONFIG_COMPILE_DEPENDS}" enabled) - if(enabled) - # Test compile the source file. - try_run( - can_run_${config_name} can_compile_${config_name} - ${CMAKE_CURRENT_BINARY_DIR} - ${CONFIG_COMPILE_SOURCE} - LINK_LIBRARIES "${CONFIG_COMPILE_LIBS}" - ) - set(can_run "0") - if((NOT "${can_run_${config_name}}" STREQUAL "FAILED_TO_RUN") AND - ("${can_run_${config_name}}" STREQUAL "0")) - set(can_run "1") - endif() - # Set an internal cache variable "${config_name}_DISABLED" to capture its enabled/disabled state. - # We want to ensure we capture a transition from a disabled to enabled state when dependencies are met. - if(${config_name}_DISABLED) - unset(${config_name}_DISABLED CACHE) - set(${config_name} ${can_run} CACHE STRING "${description}" FORCE) - else() - set(${config_name} ${can_run} CACHE STRING "${description}") - endif() - # 'try_run' sets our given temp variable into the cache. Clear this so it doesn't persist between - # configuration runs. - unset(can_run_${config_name} CACHE) - unset(can_compile_${config_name} CACHE) - else() - set(${config_name} 0 CACHE INTERNAL "" FORCE) - set(${config_name}_DISABLED ON CACHE INTERNAL "" FORCE) + set(${_have_var} OFF CACHE INTERNAL "${WTLIB_NAME} available on system") + message(CHECK_FAIL "not found") endif() endfunction() diff --git a/src/third_party/wiredtiger/cmake/install/install.cmake b/src/third_party/wiredtiger/cmake/install/install.cmake index 2d6aeb68f9f..81f68148811 100644 --- a/src/third_party/wiredtiger/cmake/install/install.cmake +++ b/src/third_party/wiredtiger/cmake/install/install.cmake @@ -25,16 +25,10 @@ install(TARGETS ${wt_targets} if(WT_POSIX) # Established the link flags for private libraries used by this WiredTiger. 'Private' in this context refers # to libraries WT links against, but isn't exposed to using applications. - set(private_libs) - if(HAVE_LIBPTHREAD) - set(private_libs "${private_libs} -lpthread") - endif() - if(HAVE_LIBRT) + set(private_libs " -lpthread -ldl") + if(WT_LINUX) set(private_libs "${private_libs} -lrt") endif() - if(HAVE_LIBDL) - set(private_libs "${private_libs} -ldl") - endif() if(ENABLE_MEMKIND) set(private_libs "${private_libs} -lmemkind") endif() @@ -58,10 +52,7 @@ if(WT_POSIX) endif() if(HAVE_BUILTIN_EXTENSION_IAA) set(private_libs "${private_libs} -lqpl") - if(HAVE_LIBCXX) - set(private_libs "${private_libs} -lstdc++") - endif() - if(HAVE_LIBACCEL_CONFIG) + if(HAVE_LIBACCEL_CONFIG) set(private_libs "${private_libs} -laccel-config") endif() endif() diff --git a/src/third_party/wiredtiger/cmake/third_party/iaa.cmake b/src/third_party/wiredtiger/cmake/third_party/iaa.cmake index 958b1b6b5f1..96a9efc1fd2 100644 --- a/src/third_party/wiredtiger/cmake/third_party/iaa.cmake +++ b/src/third_party/wiredtiger/cmake/third_party/iaa.cmake @@ -1,22 +1,13 @@ -if(NOT HAVE_LIBQPL) - # We don't need to construct a iaa library target. - return() -endif() +# Intel IAA / QPL + libaccel-config: capability detection + imported targets. +# +# Layer 1 (capability): HAVE_LIBQPL, HAVE_LIBACCEL_CONFIG +# Layer 2 (default policy): cmake/configs/base.cmake +# Layer 3 (user toggle): ENABLE_IAA / HAVE_BUILTIN_EXTENSION_IAA -if(TARGET wt::qpl) - # Avoid redefining the imported library. - return() -endif() +# Produces target wt::qpl when the library is available. +wt_find_library(NAME qpl + HEADER qpl/qpl.h) -# Define the imported iaa library target that can be subsequently linked across the build system. -# We use the double colons (::) as a convention to tell CMake that the target name is associated -# with an IMPORTED target (which allows CMake to issue a diagnostic message if the library wasn't found). -add_library(wt::qpl STATIC IMPORTED GLOBAL) -set_target_properties(wt::qpl PROPERTIES - IMPORTED_LOCATION ${HAVE_LIBQPL} -) -if (HAVE_LIBQPL_INCLUDES) - set_target_properties(wt::qpl PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${HAVE_LIBQPL_INCLUDES} - ) -endif() +# Produces target wt::accel_config when the library is available. +wt_find_library(NAME accel_config + LIBRARY accel-config) diff --git a/src/third_party/wiredtiger/cmake/third_party/lz4.cmake b/src/third_party/wiredtiger/cmake/third_party/lz4.cmake index 4e39e2df348..5d4092af807 100644 --- a/src/third_party/wiredtiger/cmake/third_party/lz4.cmake +++ b/src/third_party/wiredtiger/cmake/third_party/lz4.cmake @@ -1,23 +1,11 @@ -if(NOT HAVE_LIBLZ4) - # We don't need to construct a lz4 library target. - return() -endif() +# lz4: capability detection + imported target. +# +# Layer 1 (capability): HAVE_LIBLZ4 +# Layer 2 (default policy): cmake/configs/base.cmake +# Layer 3 (user toggle): ENABLE_LZ4 / HAVE_BUILTIN_EXTENSION_LZ4 -if(TARGET wt::lz4) - # Avoid redefining the imported library, given this file can be used as an include. - return() -endif() - -# Define the imported lz4 library target that can be subsequently linked across the build system. -# We use the double colons (::) as a convention to tell CMake that the target name is associated -# with an IMPORTED target (which allows CMake to issue a diagnostic message if the library wasn't found). -add_library(wt::lz4 SHARED IMPORTED GLOBAL) -set_target_properties(wt::lz4 PROPERTIES - IMPORTED_LOCATION ${HAVE_LIBLZ4} - IMPORTED_IMPLIB ${HAVE_LIBLZ4} -) -if (HAVE_LIBLZ4_INCLUDES) - set_target_properties(wt::lz4 PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${HAVE_LIBLZ4_INCLUDES} - ) -endif() +# Produces target wt::lz4 when the library is available. +wt_find_library(NAME lz4 + PACKAGE lz4 TARGET LZ4::lz4 + PKGCONFIG_MODULE liblz4 + HEADER lz4.h) diff --git a/src/third_party/wiredtiger/cmake/third_party/memkind.cmake b/src/third_party/wiredtiger/cmake/third_party/memkind.cmake index d3c8dbec0a6..42012ab11f2 100644 --- a/src/third_party/wiredtiger/cmake/third_party/memkind.cmake +++ b/src/third_party/wiredtiger/cmake/third_party/memkind.cmake @@ -1,27 +1,9 @@ -if(NOT HAVE_LIBMEMKIND) - # We can't construct a memkind library target. - return() -endif() +# memkind: capability detection + imported target. +# +# Layer 1 (capability): HAVE_LIBMEMKIND +# Layer 2 (default policy): cmake/configs/base.cmake (DEFAULT OFF) +# Layer 3 (user toggle): ENABLE_MEMKIND -if (NOT ENABLE_MEMKIND) - # We don't want to construct a memkind library target. - return() -endif() - -if(TARGET wt::memkind) - # Avoid redefining the imported library. - return() -endif() - -# Define the imported memkind library target that can be subsequently linked across the build system. -# We use the double colons (::) as a convention to tell CMake that the target name is associated -# with an IMPORTED target (which allows CMake to issue a diagnostic message if the library wasn't found). -add_library(wt::memkind SHARED IMPORTED GLOBAL) -set_target_properties(wt::memkind PROPERTIES - IMPORTED_LOCATION ${HAVE_LIBMEMKIND} -) -if (HAVE_LIBMEMKIND_INCLUDES) - set_target_properties(wt::memkind PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${HAVE_LIBMEMKIND_INCLUDES} - ) -endif() +# Produces target wt::memkind when the library is available. +wt_find_library(NAME memkind + HEADER memkind.h) diff --git a/src/third_party/wiredtiger/cmake/third_party/pthread.cmake b/src/third_party/wiredtiger/cmake/third_party/pthread.cmake new file mode 100644 index 00000000000..40611c2916c --- /dev/null +++ b/src/third_party/wiredtiger/cmake/third_party/pthread.cmake @@ -0,0 +1,17 @@ +# pthread (POSIX threading): capability detection. +# +# Uses CMake's standard Threads module, which selects pthread on POSIX and +# Win32 threading on Windows. Consumers link the Threads::Threads imported +# target. +# +# Layer 1 (capability): HAVE_LIBPTHREAD — true when threading is available. +# pthread is non-optional on supported platforms; configure fails without it. + +if(TARGET Threads::Threads) + # Avoid redefining the imported library. + return() +endif() + +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) +set(HAVE_LIBPTHREAD ${Threads_FOUND} CACHE INTERNAL "pthread available on system") diff --git a/src/third_party/wiredtiger/cmake/third_party/snappy.cmake b/src/third_party/wiredtiger/cmake/third_party/snappy.cmake index e96fe9fa6bf..bf7bc64d327 100644 --- a/src/third_party/wiredtiger/cmake/third_party/snappy.cmake +++ b/src/third_party/wiredtiger/cmake/third_party/snappy.cmake @@ -1,23 +1,11 @@ -if(NOT HAVE_LIBSNAPPY) - # We don't need to construct a snappy library target. - return() -endif() +# snappy: capability detection + imported target. +# +# Layer 1 (capability): HAVE_LIBSNAPPY +# Layer 2 (default policy): cmake/configs/base.cmake +# Layer 3 (user toggle): ENABLE_SNAPPY / HAVE_BUILTIN_EXTENSION_SNAPPY -if(TARGET wt::snappy) - # Avoid redefining the imported library. - return() -endif() - -# Define the imported snappy library target that can be subsequently linked across the build system. -# We use the double colons (::) as a convention to tell CMake that the target name is associated -# with an IMPORTED target (which allows CMake to issue a diagnostic message if the library wasn't found). -add_library(wt::snappy SHARED IMPORTED GLOBAL) -set_target_properties(wt::snappy PROPERTIES - IMPORTED_LOCATION ${HAVE_LIBSNAPPY} - IMPORTED_IMPLIB ${HAVE_LIBSNAPPY} -) -if (HAVE_LIBSNAPPY_INCLUDES) - set_target_properties(wt::snappy PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${HAVE_LIBSNAPPY_INCLUDES} - ) -endif() +# Produces target wt::snappy when the library is available. +wt_find_library(NAME snappy + PACKAGE Snappy TARGET Snappy::snappy + PKGCONFIG_MODULE snappy + HEADER snappy.h) diff --git a/src/third_party/wiredtiger/cmake/third_party/sodium.cmake b/src/third_party/wiredtiger/cmake/third_party/sodium.cmake index ef8bf6e39c5..1a1dcfaa3ee 100644 --- a/src/third_party/wiredtiger/cmake/third_party/sodium.cmake +++ b/src/third_party/wiredtiger/cmake/third_party/sodium.cmake @@ -1,22 +1,10 @@ -if(NOT HAVE_LIBSODIUM) - # We don't need to construct a sodium library target. - return() -endif() +# libsodium: capability detection + imported target. +# +# Layer 1 (capability): HAVE_LIBSODIUM +# Layer 2 (default policy): cmake/configs/base.cmake (DEFAULT OFF) +# Layer 3 (user toggle): ENABLE_SODIUM / HAVE_BUILTIN_EXTENSION_SODIUM -if(TARGET wt::sodium) - # Avoid redefining the imported library. - return() -endif() - -# Define the imported sodium library target that can be subsequently linked across the build system. -# We use the double colons (::) as a convention to tell CMake that the target name is associated -# with an IMPORTED target (which allows CMake to issue a diagnostic message if the library wasn't found). -add_library(wt::sodium SHARED IMPORTED GLOBAL) -set_target_properties(wt::sodium PROPERTIES - IMPORTED_LOCATION ${HAVE_LIBSODIUM} -) -if (HAVE_LIBSODIUM_INCLUDES) - set_target_properties(wt::sodium PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${HAVE_LIBSODIUM_INCLUDES} - ) -endif() +# Produces target wt::sodium when the library is available. +wt_find_library(NAME sodium + PKGCONFIG_MODULE libsodium + HEADER sodium.h) diff --git a/src/third_party/wiredtiger/cmake/third_party/sqlite3.cmake b/src/third_party/wiredtiger/cmake/third_party/sqlite3.cmake index b126d519da4..3bf61f79395 100644 --- a/src/third_party/wiredtiger/cmake/third_party/sqlite3.cmake +++ b/src/third_party/wiredtiger/cmake/third_party/sqlite3.cmake @@ -2,6 +2,11 @@ if(NOT ENABLE_PALITE) return() # PALite is disabled, skip the rest of this file endif() +if(TARGET wt::sqlite3) + # Avoid redefining the imported library. + return() +endif() + if(USE_SYSTEM_SQLITE3) find_package(SQLite3 ${SQLITE3_REQUIRED_VERSION} REQUIRED) add_library(wt::sqlite3 ALIAS SQLite::SQLite3) @@ -66,8 +71,8 @@ endif() # Needed for SQLite3 on some platforms target_link_libraries(sqlite3_lib PUBLIC - $<$:${HAVE_LIBPTHREAD}> - $<$:${HAVE_LIBDL}> + $<$:Threads::Threads> + $<$:${CMAKE_DL_LIBS}> $<$:m> ) diff --git a/src/third_party/wiredtiger/cmake/third_party/zlib.cmake b/src/third_party/wiredtiger/cmake/third_party/zlib.cmake index 8ad33d71dca..927609bac74 100644 --- a/src/third_party/wiredtiger/cmake/third_party/zlib.cmake +++ b/src/third_party/wiredtiger/cmake/third_party/zlib.cmake @@ -1,23 +1,11 @@ -if(NOT HAVE_LIBZ) - # We don't need to construct a zlib library target. - return() -endif() +# zlib: capability detection + imported target. +# +# Layer 1 (capability): HAVE_LIBZ +# Layer 2 (default policy): cmake/configs/base.cmake +# Layer 3 (user toggle): ENABLE_ZLIB / HAVE_BUILTIN_EXTENSION_ZLIB -if(TARGET wt::zlib) - # Avoid redefining the imported library. - return() -endif() - -# Define the imported zlib library target that can be subsequently linked across the build system. -# We use the double colons (::) as a convention to tell CMake that the target name is associated -# with an IMPORTED target (which allows CMake to issue a diagnostic message if the library wasn't found). -add_library(wt::zlib SHARED IMPORTED GLOBAL) -set_target_properties(wt::zlib PROPERTIES - IMPORTED_LOCATION ${HAVE_LIBZ} - IMPORTED_IMPLIB ${HAVE_LIBZ} -) -if (HAVE_LIBZ_INCLUDES) - set_target_properties(wt::zlib PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${HAVE_LIBZ_INCLUDES} - ) -endif() +# Produces target wt::zlib when the library is available. +wt_find_library(NAME z CMAKE_TARGET zlib + PACKAGE ZLIB TARGET ZLIB::ZLIB + PKGCONFIG_MODULE zlib + HEADER zlib.h) diff --git a/src/third_party/wiredtiger/cmake/third_party/zstd.cmake b/src/third_party/wiredtiger/cmake/third_party/zstd.cmake index cc47f6f5dd6..a416ebeb563 100644 --- a/src/third_party/wiredtiger/cmake/third_party/zstd.cmake +++ b/src/third_party/wiredtiger/cmake/third_party/zstd.cmake @@ -1,23 +1,11 @@ -if(NOT HAVE_LIBZSTD) - # We don't need to construct a zstd library target. - return() -endif() +# zstd: capability detection + imported target. +# +# Layer 1 (capability): HAVE_LIBZSTD +# Layer 2 (default policy): cmake/configs/base.cmake +# Layer 3 (user toggle): ENABLE_ZSTD / HAVE_BUILTIN_EXTENSION_ZSTD -if(TARGET wt::zstd) - # Avoid redefining the imported library. - return() -endif() - -# Define the imported zstd library target that can be subsequently linked across the build system. -# We use the double colons (::) as a convention to tell CMake that the target name is associated -# with an IMPORTED target (which allows CMake to issue a diagnostic message if the library wasn't found). -add_library(wt::zstd SHARED IMPORTED GLOBAL) -set_target_properties(wt::zstd PROPERTIES - IMPORTED_LOCATION ${HAVE_LIBZSTD} - IMPORTED_IMPLIB ${HAVE_LIBZSTD} -) -if (HAVE_LIBZSTD_INCLUDES) - set_target_properties(wt::zstd PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES ${HAVE_LIBZSTD_INCLUDES} - ) -endif() +# Produces target wt::zstd when the library is available. +wt_find_library(NAME zstd + PACKAGE zstd TARGET zstd::libzstd_shared + PKGCONFIG_MODULE libzstd + HEADER zstd.h) diff --git a/src/third_party/wiredtiger/dist/docs_data.py b/src/third_party/wiredtiger/dist/docs_data.py index eb656dce180..120089b3544 100755 --- a/src/third_party/wiredtiger/dist/docs_data.py +++ b/src/third_party/wiredtiger/dist/docs_data.py @@ -108,6 +108,11 @@ arch_doc_pages = [ ArchDocPage('arch-metadata', [], ['src/include/meta.h', 'src/meta/']), + ArchDocPage('arch-page-delta', + ['WTI_DELTA_LEAF_MERGE_STATE', 'WT_PAGE_BLOCK_META', 'WT_PAGE_DELTA_CONFIG'], + ['src/include/btmem.h', 'src/include/btree.h', 'src/include/connection.h', + 'src/btree/bt_page.c', 'src/btree/bt_read.c', 'src/reconcile/rec_row.c', + 'src/reconcile/rec_write.c']), ArchDocPage('arch-prefetch', ['WT_PREFETCH', 'WT_PREFETCH_QUEUE_ENTRY', 'WT_REF'], ['src/btree/bt_prefetch.c', 'src/conn/conn_prefetch.c', diff --git a/src/third_party/wiredtiger/dist/s_define.list b/src/third_party/wiredtiger/dist/s_define.list index 6018f460108..129a6e3631b 100644 --- a/src/third_party/wiredtiger/dist/s_define.list +++ b/src/third_party/wiredtiger/dist/s_define.list @@ -104,8 +104,6 @@ WT_SESSION_LOCKED_LIVE_RESTORE_STATE WT_SESSION_LOCKED_TABLE_READ WT_SESSION_LOCKED_TABLE_WRITE WT_SESSION_LOCKED_TURTLE -WT_SINGLE_THREAD_CHECK_START -WT_SINGLE_THREAD_CHECK_STOP WT_SIZEOF_FIELD WT_SPLIT_SAVE_STATE_MAX WT_STATS_FIELD_TO_OFFSET diff --git a/src/third_party/wiredtiger/dist/s_stat b/src/third_party/wiredtiger/dist/s_stat index c7a3e5e50c9..6009c73fbd6 100755 --- a/src/third_party/wiredtiger/dist/s_stat +++ b/src/third_party/wiredtiger/dist/s_stat @@ -71,6 +71,7 @@ perf_hist_leaf_reconstruct_latency_total_usecs perf_hist_opread_latency_total_usecs perf_hist_opwrite_latency_total_usecs txn_rts_upd_aborted_dryrun +read_reject_count write_reject_count UNUSED_STAT_FIELDS diff --git a/src/third_party/wiredtiger/dist/stat_data.py b/src/third_party/wiredtiger/dist/stat_data.py index 854f23ea6d0..2d17e6f8d42 100644 --- a/src/third_party/wiredtiger/dist/stat_data.py +++ b/src/third_party/wiredtiger/dist/stat_data.py @@ -658,6 +658,7 @@ conn_stats = [ # Load Control statistics ########################################## LoadControlStat('read_load', 'read load at the system level'), + LoadControlStat('read_reject_count', 'number of read operations rejected due to load control'), LoadControlStat('write_load', 'write load at the system level'), LoadControlStat('write_reject_count', 'number of write operations rejected due to load control'), diff --git a/src/third_party/wiredtiger/import.data b/src/third_party/wiredtiger/import.data index b2e612a1e4d..3781b066ceb 100644 --- a/src/third_party/wiredtiger/import.data +++ b/src/third_party/wiredtiger/import.data @@ -2,5 +2,5 @@ "vendor": "wiredtiger", "github": "wiredtiger/wiredtiger", "branch": "mongodb-master", - "commit": "46bf841062af800d92786a96abe10c02c0d9f17f" + "commit": "3c6ec61a01a4dbdb3351121c0a624d3996e28c03" } diff --git a/src/third_party/wiredtiger/src/block/block_ckpt.c b/src/third_party/wiredtiger/src/block/block_ckpt.c index 61da1973f4e..e511183afb7 100644 --- a/src/third_party/wiredtiger/src/block/block_ckpt.c +++ b/src/third_party/wiredtiger/src/block/block_ckpt.c @@ -8,10 +8,12 @@ #include "wt_internal.h" +static int __ckpt_delete_and_merge(WT_SESSION_IMPL *, WT_BLOCK *, WT_CKPT *, WT_BLOCK_CKPT *); static int __ckpt_process(WT_SESSION_IMPL *, WT_BLOCK *, WT_CKPT *); static int __ckpt_read_deletion_extlists(WT_SESSION_IMPL *, WT_BLOCK *, WT_CKPT *, bool *); static int __ckpt_reinit_extlists(WT_SESSION_IMPL *, WT_BLOCK_CKPT *); static int __ckpt_update(WT_SESSION_IMPL *, WT_BLOCK *, WT_CKPT *, WT_CKPT *, WT_BLOCK_CKPT *); +static int __ckpt_update_live(WT_SESSION_IMPL *, WT_BLOCK *, WT_CKPT *, WT_BLOCK_CKPT *, uint64_t); static int __ckpt_validate_state(WT_SESSION_IMPL *, WT_BLOCK *); /* @@ -686,6 +688,227 @@ __ckpt_reinit_extlists(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci) return (0); } +/* + * __ckpt_update_live -- + * Update the live checkpoint: truncate the file, calculate the checkpoint size, and call + * __ckpt_update for the ADD checkpoint. Also resets the live system's alloc and discard extent + * lists so that extents freed by the checkpoint are reclaimed outside of the lock. + * + * The caller must hold block->live_lock. + */ +static int +__ckpt_update_live(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase, WT_BLOCK_CKPT *ci, + uint64_t ckpt_size) +{ + WT_CKPT *ckpt; + + WT_ASSERT_SPINLOCK_OWNED(session, &block->live_lock); + + /* Truncate the file if that's possible. */ + WT_RET(__wti_block_extlist_truncate(session, block, &ci->avail)); + + /* Update the final, added checkpoint based on the live system. */ + WT_CKPT_FOREACH (ckptbase, ckpt) + if (F_ISSET(ckpt, WT_CKPT_ADD)) { + /* + * !!! + * Our caller wants the final checkpoint size. Setting the size here violates layering, + * but the alternative is a call for the btree layer to crack the checkpoint cookie into + * its components, and that's a fair amount of work. + */ + ckpt->size = ckpt_size; + + /* + * Set the rolling checkpoint size for the live system. The current size includes the + * current checkpoint's root page size (root pages are on the checkpoint's block + * allocation list as root pages are allocated with the usual block allocation + * functions). That's correct, but we don't want to include it in the size for the next + * checkpoint. + */ + ckpt_size -= ci->root_size; + + /* + * Additionally, we had a bug for awhile where the live checkpoint size grew without + * bound. We can't sanity check the value, that would require walking the tree as part + * of the checkpoint. Bound any bug at the size of the file. It isn't practical to + * assert that the value is within bounds since databases created with older versions of + * WiredTiger (2.8.0) would likely see an error. + */ + ci->ckpt_size = WT_MIN(ckpt_size, (uint64_t)block->size); + + WT_RET_MSG_CHK(session, __ckpt_update(session, block, ckptbase, ckpt, ci), + "updating the live (ADD) checkpoint %s", ckpt->name); + } + + /* + * Reset the live system's alloc and discard extent lists, leave the avail list alone. This + * includes freeing a lot of extents, so do it outside of the system's lock by copying and + * resetting the original, then doing the work later. + */ + ci->ckpt_alloc = ci->alloc; + WT_RET_MSG_CHK(session, __wti_block_extlist_init(session, &ci->alloc, "live", "alloc", false), + "resetting the live alloc extent list after copying it to ckpt_alloc"); + ci->ckpt_discard = ci->discard; + WT_RET_MSG_CHK(session, + __wti_block_extlist_init(session, &ci->discard, "live", "discard", false), + "resetting the live discard extent list after copying it to ckpt_discard"); + +#ifdef HAVE_DIAGNOSTIC + /* + * The first checkpoint in the system should always have an empty discard list. If we've read + * that checkpoint and/or created it, check. + */ + WT_BLOCK_CKPT *a; + WT_CKPT_FOREACH (ckptbase, ckpt) + if (!F_ISSET(ckpt, WT_CKPT_DELETE)) + break; + if ((a = ckpt->bpriv) == NULL) + a = &block->live; + if (a->discard.entries != 0) + WT_RET_MSG( + session, WT_ERROR, "first checkpoint incorrectly has blocks on the discard list"); +#endif + + return (0); +} + +/* + * __ckpt_delete_and_merge -- + * Delete checkpoints no longer needed and merge their extent lists into the subsequent + * checkpoint. Handles freeing root pages, freeing extent list blocks, merging alloc and discard + * lists, finding overlapping blocks for reuse, updating checkpoints, and clearing block + * modification tracking. Must be called while the live lock is held. + */ +static int +__ckpt_delete_and_merge( + WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase, WT_BLOCK_CKPT *ci) +{ + WT_BLOCK_CKPT *a, *b; + WT_CKPT *ckpt, *next_ckpt; + const char *next_name; + + WT_ASSERT_SPINLOCK_OWNED(session, &block->live_lock); + + /* + * Delete any no-longer-needed checkpoints: we do this first as it frees blocks to the live + * lists, and the freed blocks will then be included when writing the live extent lists. + */ + WT_CKPT_FOREACH (ckptbase, ckpt) { + if (F_ISSET(ckpt, WT_CKPT_FAKE) || !F_ISSET(ckpt, WT_CKPT_DELETE)) + continue; + + /* + * Set the "from" checkpoint structure. If it applies to a previous object, there's nothing + * more to do. + */ + a = ckpt->bpriv; + if (a->root_objectid != block->objectid) + continue; + + if (WT_VERBOSE_LEVEL_ISSET(session, WT_VERB_CHECKPOINT, WT_VERBOSE_DEBUG_2)) + __wti_ckpt_verbose( + session, block, "delete", ckpt->name, ckpt->raw.data, ckpt->raw.size); + + /* + * Find the checkpoint into which we'll roll this checkpoint's blocks: it's the next real + * checkpoint in the list, and it better have been read in (if it's not the add slot). + */ + for (next_ckpt = ckpt + 1;; ++next_ckpt) + if (!F_ISSET(next_ckpt, WT_CKPT_FAKE)) + break; + + /* + * Set the "to" checkpoint structure, it may be the live tree. + */ + if (F_ISSET(next_ckpt, WT_CKPT_ADD)) + b = &block->live; + else + b = next_ckpt->bpriv; + next_name = next_ckpt->name != NULL ? next_ckpt->name : "live"; + + /* + * Free the root page: there's nothing special about this free, the root page is allocated + * using normal rules, that is, it may have been taken from the avail list, and was entered + * on the live system's alloc list at that time. We free it into the checkpoint's discard + * list, however, not the live system's list because it appears on the checkpoint's alloc + * list and so must be paired in the checkpoint. + */ + if (a->root_offset != WT_BLOCK_INVALID_OFFSET) + WT_RET_MSG_CHK(session, + __wti_block_insert_ext(session, block, &a->discard, a->root_offset, a->root_size), + "inserting root page into discard list for deleted checkpoint %s", ckpt->name); + + /* + * Free the blocks used to hold the "from" checkpoint's extent lists, including the avail + * list. + */ + WT_RET_MSG_CHK(session, __ckpt_extlist_fblocks(session, block, &a->alloc), + "freeing alloc extent list blocks for deleted checkpoint %s", ckpt->name); + WT_RET_MSG_CHK(session, __ckpt_extlist_fblocks(session, block, &a->avail), + "freeing avail extent list blocks for deleted checkpoint %s", ckpt->name); + WT_RET_MSG_CHK(session, __ckpt_extlist_fblocks(session, block, &a->discard), + "freeing discard extent list blocks for deleted checkpoint %s", ckpt->name); + + /* + * Roll the "from" alloc and discard extent lists into the "to" checkpoint's lists. + */ + if (a->alloc.entries != 0) + WT_RET_MSG_CHK(session, __wti_block_extlist_merge(session, block, &a->alloc, &b->alloc), + "merging alloc extent list from deleted checkpoint %s", ckpt->name); + if (a->discard.entries != 0) + WT_RET_MSG_CHK(session, + __wti_block_extlist_merge(session, block, &a->discard, &b->discard), + "merging discard extent list from deleted checkpoint %s", ckpt->name); + + /* + * If the "to" checkpoint is also being deleted, we're done with it, it's merged into some + * other checkpoint in the next loop. This means the extent lists may aggregate over a + * number of checkpoints, but that's OK, they're disjoint sets of ranges. + */ + if (F_ISSET(next_ckpt, WT_CKPT_DELETE)) + continue; + + /* + * Find blocks for re-use: wherever the "to" checkpoint's allocate and discard lists + * overlap, move the range to the live system's checkpoint available list. + */ + WT_RET_MSG_CHK(session, __wti_block_extlist_overlap(session, block, b), + "finding reusable blocks in checkpoint %s", next_name); + + /* + * If we're updating the live system's information, we're done. + */ + if (F_ISSET(next_ckpt, WT_CKPT_ADD)) { + /* Clear any possible blocks that are now available after merging. */ + WT_RET_MSG_CHK(session, __ckpt_live_blkmods(session, ckptbase, ci, block, false), + "clearing live block modifications after merging into %s", next_name); + continue; + } + + /* + * We have to write the "to" checkpoint's extent lists out in new blocks, and update its + * cookie. + * + * Free the blocks used to hold the "to" checkpoint's extent lists; don't include the avail + * list, it's not changing. + */ + WT_RET_MSG_CHK(session, __ckpt_extlist_fblocks(session, block, &b->alloc), + "freeing alloc extent list blocks for updated checkpoint %s", next_name); + WT_RET_MSG_CHK(session, __ckpt_extlist_fblocks(session, block, &b->discard), + "freeing discard extent list blocks for updated checkpoint %s", next_name); + + F_SET(next_ckpt, WT_CKPT_UPDATE); + } + + /* Update checkpoints marked for update. */ + WT_CKPT_FOREACH (ckptbase, ckpt) + if (F_ISSET(ckpt, WT_CKPT_UPDATE)) + WT_RET_MSG_CHK(session, __ckpt_update(session, block, ckptbase, ckpt, ckpt->bpriv), + "updating checkpoint %s after deletion merge", ckpt->name); + + return (0); +} + /* * __ckpt_process -- * Process the list of checkpoints. @@ -693,8 +916,8 @@ __ckpt_reinit_extlists(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci) static int __ckpt_process(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase) { - WT_BLOCK_CKPT *a, *b, *ci; - WT_CKPT *ckpt, *next_ckpt; + WT_BLOCK_CKPT *ci; + WT_CKPT *ckpt; WT_DECL_RET; uint64_t ckpt_size; bool deleting, fatal; @@ -779,170 +1002,11 @@ __ckpt_process(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase) if (!deleting) goto live_update; - /* - * Delete any no-longer-needed checkpoints: we do this first as it frees blocks to the live - * lists, and the freed blocks will then be included when writing the live extent lists. - */ - WT_CKPT_FOREACH (ckptbase, ckpt) { - if (F_ISSET(ckpt, WT_CKPT_FAKE) || !F_ISSET(ckpt, WT_CKPT_DELETE)) - continue; - - /* - * Set the "from" checkpoint structure. If it applies to a previous object, there's nothing - * more to do. - */ - a = ckpt->bpriv; - if (a->root_objectid != block->objectid) - continue; - - if (WT_VERBOSE_LEVEL_ISSET(session, WT_VERB_CHECKPOINT, WT_VERBOSE_DEBUG_2)) - __wti_ckpt_verbose( - session, block, "delete", ckpt->name, ckpt->raw.data, ckpt->raw.size); - - /* - * Find the checkpoint into which we'll roll this checkpoint's blocks: it's the next real - * checkpoint in the list, and it better have been read in (if it's not the add slot). - */ - for (next_ckpt = ckpt + 1;; ++next_ckpt) - if (!F_ISSET(next_ckpt, WT_CKPT_FAKE)) - break; - - /* - * Set the "to" checkpoint structure, it may be the live tree. - */ - if (F_ISSET(next_ckpt, WT_CKPT_ADD)) - b = &block->live; - else - b = next_ckpt->bpriv; - - /* - * Free the root page: there's nothing special about this free, the root page is allocated - * using normal rules, that is, it may have been taken from the avail list, and was entered - * on the live system's alloc list at that time. We free it into the checkpoint's discard - * list, however, not the live system's list because it appears on the checkpoint's alloc - * list and so must be paired in the checkpoint. - */ - if (a->root_offset != WT_BLOCK_INVALID_OFFSET) - WT_ERR( - __wti_block_insert_ext(session, block, &a->discard, a->root_offset, a->root_size)); - - /* - * Free the blocks used to hold the "from" checkpoint's extent lists, including the avail - * list. - */ - WT_ERR(__ckpt_extlist_fblocks(session, block, &a->alloc)); - WT_ERR(__ckpt_extlist_fblocks(session, block, &a->avail)); - WT_ERR(__ckpt_extlist_fblocks(session, block, &a->discard)); - - /* - * Roll the "from" alloc and discard extent lists into the "to" checkpoint's lists. - */ - if (a->alloc.entries != 0) - WT_ERR(__wti_block_extlist_merge(session, block, &a->alloc, &b->alloc)); - if (a->discard.entries != 0) - WT_ERR(__wti_block_extlist_merge(session, block, &a->discard, &b->discard)); - - /* - * If the "to" checkpoint is also being deleted, we're done with it, it's merged into some - * other checkpoint in the next loop. This means the extent lists may aggregate over a - * number of checkpoints, but that's OK, they're disjoint sets of ranges. - */ - if (F_ISSET(next_ckpt, WT_CKPT_DELETE)) - continue; - - /* - * Find blocks for re-use: wherever the "to" checkpoint's allocate and discard lists - * overlap, move the range to the live system's checkpoint available list. - */ - WT_ERR(__wti_block_extlist_overlap(session, block, b)); - - /* - * If we're updating the live system's information, we're done. - */ - if (F_ISSET(next_ckpt, WT_CKPT_ADD)) { - /* Clear any possible blocks that are now available after merging. */ - WT_ERR(__ckpt_live_blkmods(session, ckptbase, ci, block, false)); - continue; - } - - /* - * We have to write the "to" checkpoint's extent lists out in new blocks, and update its - * cookie. - * - * Free the blocks used to hold the "to" checkpoint's extent lists; don't include the avail - * list, it's not changing. - */ - WT_ERR(__ckpt_extlist_fblocks(session, block, &b->alloc)); - WT_ERR(__ckpt_extlist_fblocks(session, block, &b->discard)); - - F_SET(next_ckpt, WT_CKPT_UPDATE); - } - - /* Update checkpoints marked for update. */ - WT_CKPT_FOREACH (ckptbase, ckpt) - if (F_ISSET(ckpt, WT_CKPT_UPDATE)) - WT_ERR(__ckpt_update(session, block, ckptbase, ckpt, ckpt->bpriv)); + /* Delete checkpoints no longer needed and merge their extent lists into subsequent ones. */ + WT_ERR(__ckpt_delete_and_merge(session, block, ckptbase, ci)); live_update: - /* Truncate the file if that's possible. */ - WT_ERR(__wti_block_extlist_truncate(session, block, &ci->avail)); - - /* Update the final, added checkpoint based on the live system. */ - WT_CKPT_FOREACH (ckptbase, ckpt) - if (F_ISSET(ckpt, WT_CKPT_ADD)) { - /* - * !!! - * Our caller wants the final checkpoint size. Setting the size here violates layering, - * but the alternative is a call for the btree layer to crack the checkpoint cookie into - * its components, and that's a fair amount of work. - */ - ckpt->size = ckpt_size; - - /* - * Set the rolling checkpoint size for the live system. The current size includes the - * current checkpoint's root page size (root pages are on the checkpoint's block - * allocation list as root pages are allocated with the usual block allocation - * functions). That's correct, but we don't want to include it in the size for the next - * checkpoint. - */ - ckpt_size -= ci->root_size; - - /* - * Additionally, we had a bug for awhile where the live checkpoint size grew without - * bound. We can't sanity check the value, that would require walking the tree as part - * of the checkpoint. Bound any bug at the size of the file. It isn't practical to - * assert that the value is within bounds since databases created with older versions of - * WiredTiger (2.8.0) would likely see an error. - */ - ci->ckpt_size = WT_MIN(ckpt_size, (uint64_t)block->size); - - WT_ERR(__ckpt_update(session, block, ckptbase, ckpt, ci)); - } - - /* - * Reset the live system's alloc and discard extent lists, leave the avail list alone. This - * includes freeing a lot of extents, so do it outside of the system's lock by copying and - * resetting the original, then doing the work later. - */ - ci->ckpt_alloc = ci->alloc; - WT_ERR(__wti_block_extlist_init(session, &ci->alloc, "live", "alloc", false)); - ci->ckpt_discard = ci->discard; - WT_ERR(__wti_block_extlist_init(session, &ci->discard, "live", "discard", false)); - -#ifdef HAVE_DIAGNOSTIC - /* - * The first checkpoint in the system should always have an empty discard list. If we've read - * that checkpoint and/or created it, check. - */ - WT_CKPT_FOREACH (ckptbase, ckpt) - if (!F_ISSET(ckpt, WT_CKPT_DELETE)) - break; - if ((a = ckpt->bpriv) == NULL) - a = &block->live; - if (a->discard.entries != 0) - WT_ERR_MSG( - session, WT_ERROR, "first checkpoint incorrectly has blocks on the discard list"); -#endif + WT_ERR(__ckpt_update_live(session, block, ckptbase, ci, ckpt_size)); err: if (ret != 0 && fatal) { diff --git a/src/third_party/wiredtiger/src/conn/conn_layered_ingest.c b/src/third_party/wiredtiger/src/conn/conn_layered_ingest.c index ee8c8421008..2fe0017db16 100644 --- a/src/third_party/wiredtiger/src/conn/conn_layered_ingest.c +++ b/src/third_party/wiredtiger/src/conn/conn_layered_ingest.c @@ -169,12 +169,11 @@ __layered_reset_ingest_table_prune_timestamp(WT_SESSION_IMPL *session, const cha WT_DECL_RET; wt_timestamp_t btree_prune_timestamp; - WT_ERR_NOTFOUND_OK(__wt_session_get_dhandle(session, ingest_uri, NULL, NULL, 0), true); - if (ret == WT_NOTFOUND) { + WT_RET_ERROR_OK(ret = __wt_session_get_dhandle(session, ingest_uri, NULL, NULL, 0), ENOENT); + if (ret == ENOENT) { __wt_verbose_level(session, WT_VERB_LAYERED, WT_VERBOSE_DEBUG_5, "Handle not found for ingest table uri: %s", ingest_uri); - ret = 0; - goto err; + return (0); } btree = (WT_BTREE *)session->dhandle->handle; @@ -186,9 +185,8 @@ __layered_reset_ingest_table_prune_timestamp(WT_SESSION_IMPL *session, const cha __wt_atomic_store_uint64_relaxed(&btree->prune_timestamp, WT_TS_NONE); - WT_ERR(__wt_session_release_dhandle(session)); + WT_RET(__wt_session_release_dhandle(session)); -err: return (ret); } @@ -746,9 +744,9 @@ __layered_drain_ingest_table_and_truncate_list(WT_SESSION_IMPL *session, const c WT_RET(__wt_scr_alloc(session, 0, &layered_uri_buf)); WT_ERR(__layered_derive_layered_uri(session, ingest_uri, layered_uri_buf)); - WT_ERR_NOTFOUND_OK( - __wt_session_get_dhandle(session, layered_uri_buf->data, NULL, NULL, 0), true); - if (ret == WT_NOTFOUND) { + WT_ERR_ERROR_OK( + __wt_session_get_dhandle(session, layered_uri_buf->data, NULL, NULL, 0), ENOENT, true); + if (ret == ENOENT) { __wt_verbose_level(session, WT_VERB_LAYERED, WT_VERBOSE_DEBUG_5, "No layered handle found for ingest table \"%s\", only performing ingest drain", ingest_uri); @@ -1017,13 +1015,12 @@ __layered_update_ingest_table_prune_timestamp(WT_SESSION_IMPL *session, const ch layered_table = NULL; prune_timestamp = WT_TS_NONE; - /* * Get the layered table from the provided URI. We don't hold any global locks so that's * possible that it was already removed. */ - WT_ERR_NOTFOUND_OK(__wt_session_get_dhandle(session, layered_uri, NULL, NULL, 0), true); - if (ret == WT_NOTFOUND) { + WT_RET_ERROR_OK(ret = __wt_session_get_dhandle(session, layered_uri, NULL, NULL, 0), ENOENT); + if (ret == ENOENT) { __wt_verbose_level(session, WT_VERB_LAYERED, WT_VERBOSE_DEBUG_5, "GC %s: Layered table was not found.", layered_uri); return (0); @@ -1106,9 +1103,9 @@ __layered_update_ingest_table_prune_timestamp(WT_SESSION_IMPL *session, const ch * that it hasn't been opened yet. In that case, we need to skip updating its timestamp for * pruning, and we'll get another chance to update the prune timestamp at the next checkpoint. */ - WT_ERR_NOTFOUND_OK( - __wt_session_get_dhandle(session, layered_table->ingest_uri, NULL, NULL, 0), true); - if (ret == WT_NOTFOUND) { + WT_ERR_ERROR_OK( + __wt_session_get_dhandle(session, layered_table->ingest_uri, NULL, NULL, 0), ENOENT, true); + if (ret == ENOENT) { __wt_verbose_level(session, WT_VERB_LAYERED, WT_VERBOSE_DEBUG_5, "GC %s: Handle not found for ingest table uri: %s", layered_table->iface.name, layered_table->ingest_uri); diff --git a/src/third_party/wiredtiger/src/cursor/cur_ds.c b/src/third_party/wiredtiger/src/cursor/cur_ds.c index 1dfd26f473f..5121d16232a 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_ds.c +++ b/src/third_party/wiredtiger/src/cursor/cur_ds.c @@ -174,6 +174,8 @@ __curds_next(WT_CURSOR *cursor) CURSOR_API_CALL(cursor, session, ret, next, NULL); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_STAT_CONN_DSRC_INCR(session, cursor_next); F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET); @@ -197,6 +199,7 @@ __curds_prev(WT_CURSOR *cursor) source = ((WT_CURSOR_DATA_SOURCE *)cursor)->source; CURSOR_API_CALL(cursor, session, ret, prev, NULL); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); WT_STAT_CONN_DSRC_INCR(session, cursor_prev); @@ -247,6 +250,8 @@ __curds_search(WT_CURSOR *cursor) CURSOR_API_CALL(cursor, session, ret, search, NULL); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_STAT_CONN_DSRC_INCR(session, cursor_search); WT_ERR(__curds_key_set(cursor)); @@ -271,6 +276,8 @@ __curds_search_near(WT_CURSOR *cursor, int *exact) CURSOR_API_CALL(cursor, session, ret, search_near, NULL); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_STAT_CONN_DSRC_INCR(session, cursor_search_near); WT_ERR(__curds_key_set(cursor)); @@ -295,6 +302,8 @@ __curds_insert(WT_CURSOR *cursor) CURSOR_UPDATE_API_CALL(cursor, session, ret, insert, NULL); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_STAT_CONN_DSRC_INCR(session, cursor_insert); WT_STAT_DSRC_INCRV(session, cursor_insert_bytes, cursor->key.size + cursor->value.size); @@ -323,6 +332,8 @@ __curds_update(WT_CURSOR *cursor) CURSOR_UPDATE_API_CALL(cursor, session, ret, update, NULL); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_STAT_CONN_DSRC_INCR(session, cursor_update); WT_STAT_CONN_DSRC_INCRV(session, cursor_update_bytes, cursor->value.size); @@ -350,6 +361,8 @@ __curds_remove(WT_CURSOR *cursor) CURSOR_REMOVE_API_CALL(cursor, session, ret, NULL); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_STAT_CONN_DSRC_INCR(session, cursor_remove); WT_STAT_CONN_DSRC_INCRV(session, cursor_remove_bytes, cursor->key.size); @@ -376,6 +389,8 @@ __curds_reserve(WT_CURSOR *cursor) CURSOR_UPDATE_API_CALL(cursor, session, ret, reserve, NULL); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_STAT_CONN_DSRC_INCR(session, cursor_reserve); WT_ERR(__curds_key_set(cursor)); diff --git a/src/third_party/wiredtiger/src/cursor/cur_file.c b/src/third_party/wiredtiger/src/cursor/cur_file.c index 3a31ff5bb89..ce8137ba177 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_file.c +++ b/src/third_party/wiredtiger/src/cursor/cur_file.c @@ -178,6 +178,12 @@ __curfile_next(WT_CURSOR *cursor) cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, ret, next, cbt->dhandle); CURSOR_REPOSITION_ENTER(cursor, session); + + /* + * If this is a user cursor call, check for system overload before doing any work. + */ + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__cursor_copy_release(cursor)); WT_ERR(__curfile_check_cbt_txn(session, cbt)); @@ -238,6 +244,8 @@ __curfile_prev(WT_CURSOR *cursor) cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_API_CALL(cursor, session, ret, prev, cbt->dhandle); CURSOR_REPOSITION_ENTER(cursor, session); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__cursor_copy_release(cursor)); WT_ERR(__curfile_check_cbt_txn(session, cbt)); @@ -305,6 +313,9 @@ __curfile_search(WT_CURSOR *cursor) CURSOR_API_CALL(cursor, session, ret, search, cbt->dhandle); API_RETRYABLE(session); CURSOR_REPOSITION_ENTER(cursor, session); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__cursor_copy_release(cursor)); WT_ERR(__cursor_checkkey(cursor)); @@ -343,6 +354,9 @@ __curfile_search_near(WT_CURSOR *cursor, int *exact) CURSOR_API_CALL(cursor, session, ret, search_near, cbt->dhandle); API_RETRYABLE(session); CURSOR_REPOSITION_ENTER(cursor, session); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__cursor_copy_release(cursor)); WT_ERR(__cursor_checkkey(cursor)); @@ -379,6 +393,9 @@ __curfile_insert(WT_CURSOR *cursor) cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_UPDATE_API_CALL_BTREE(cursor, session, ret, insert); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__cursor_copy_release(cursor)); if (!F_ISSET(cursor, WT_CURSTD_APPEND)) @@ -421,6 +438,9 @@ __wt_curfile_insert_check(WT_CURSOR *cursor) cbt = (WT_CURSOR_BTREE *)cursor; tret = 0; CURSOR_UPDATE_API_CALL_BTREE(cursor, session, ret, insert_check); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__cursor_copy_release(cursor)); WT_ERR(__cursor_checkkey(cursor)); @@ -449,6 +469,9 @@ __curfile_modify(WT_CURSOR *cursor, WT_MODIFY *entries, int nentries) cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_UPDATE_API_CALL_BTREE(cursor, session, ret, modify); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__cursor_copy_release(cursor)); WT_ERR(__cursor_checkkey(cursor)); @@ -487,6 +510,9 @@ __curfile_update(WT_CURSOR *cursor) cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_UPDATE_API_CALL_BTREE(cursor, session, ret, update); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__cursor_copy_release(cursor)); WT_ERR(__cursor_checkkey(cursor)); WT_ERR(__cursor_checkvalue(cursor)); @@ -530,6 +556,9 @@ __curfile_remove(WT_CURSOR *cursor) cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_REMOVE_API_CALL(cursor, session, ret, cbt->dhandle); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__cursor_copy_release(cursor)); WT_ERR(__cursor_checkkey(cursor)); @@ -572,6 +601,9 @@ __curfile_reserve(WT_CURSOR *cursor) cbt = (WT_CURSOR_BTREE *)cursor; CURSOR_UPDATE_API_CALL_BTREE(cursor, session, ret, reserve); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__cursor_copy_release(cursor)); WT_ERR(__cursor_checkkey(cursor)); diff --git a/src/third_party/wiredtiger/src/cursor/cur_layered.c b/src/third_party/wiredtiger/src/cursor/cur_layered.c index a00f2f742b4..b2cfca1fefe 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_layered.c +++ b/src/third_party/wiredtiger/src/cursor/cur_layered.c @@ -1323,6 +1323,9 @@ __clayered_next(WT_CURSOR *cursor) clayered = (WT_CURSOR_LAYERED *)cursor; CURSOR_API_CALL(cursor, session, ret, next, clayered->dhandle); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + __cursor_novalue(cursor); WT_ERR(__cursor_copy_release(cursor)); @@ -1354,6 +1357,9 @@ __clayered_prev(WT_CURSOR *cursor) clayered = (WT_CURSOR_LAYERED *)cursor; CURSOR_API_CALL(cursor, session, ret, prev, clayered->dhandle); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + __cursor_novalue(cursor); WT_ERR(__cursor_copy_release(cursor)); @@ -1718,7 +1724,7 @@ __clayered_lookup(WT_SESSION_IMPL *session, WT_CURSOR_LAYERED *clayered, WT_ITEM __clayered_lookup_constituent(clayered->stable_cursor, clayered, value), true); err: - if (ret != 0 && ret != WT_PREPARE_CONFLICT) { + if (ret != 0) { WT_TRET(__clayered_reset_cursors(clayered, false)); /* Reset the buffer if the key was deleted on the ingest table. */ value->data = NULL; @@ -1748,6 +1754,8 @@ __clayered_search(WT_CURSOR *cursor) __cursor_novalue(cursor); WT_ERR(__clayered_enter(clayered, true, true, false)); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_STAT_CONN_DSRC_INCR(session, layered_curs_search); WT_ERR(__clayered_lookup(session, clayered, &cursor->value)); WT_ITEM_SET(cursor->key, clayered->current_cursor->key); @@ -2008,7 +2016,7 @@ done: } err: - if (ret != 0 && ret != WT_PREPARE_CONFLICT) + if (ret != 0) WT_TRET(__clayered_reset_cursors(clayered, false)); return (ret); @@ -2034,6 +2042,8 @@ __clayered_search_near(WT_CURSOR *cursor, int *exactp) __cursor_novalue(cursor); WT_ERR(__clayered_enter(clayered, true, true, false)); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__clayered_search_near_int(session, cursor, exactp)); WT_ITEM_SET(cursor->key, clayered->current_cursor->key); @@ -2067,6 +2077,8 @@ __clayered_reserve_constituent(WT_SESSION_IMPL *session, WT_CURSOR *constituent) WT_DECL_RET; CURSOR_UPDATE_API_CALL_BTREE(constituent, session, ret, reserve); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + /* * Pass overwrite=true for followers: a follower's ingest table may not contain the key yet (it * lives only in the stable table), so we need overwrite mode to allow the reserve to succeed @@ -2270,6 +2282,9 @@ __clayered_insert(WT_CURSOR *cursor) clayered = (WT_CURSOR_LAYERED *)cursor; CURSOR_UPDATE_API_CALL(cursor, session, ret, insert, clayered->dhandle); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + /* Insert doesn't keep the cursor positioned. Always clear the iteration flags. */ F_CLR(clayered, WT_CLAYERED_ITERATE_NEXT | WT_CLAYERED_ITERATE_PREV); WT_ERR(__cursor_copy_release(cursor)); @@ -2328,6 +2343,9 @@ __clayered_update(WT_CURSOR *cursor) clayered = (WT_CURSOR_LAYERED *)cursor; CURSOR_UPDATE_API_CALL(cursor, session, ret, update, clayered->dhandle); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + /* * Update keeps the cursor positioned. Retain the iteration flags if we are in the middle of a * cursor traversal. @@ -2400,6 +2418,9 @@ __clayered_remove(WT_CURSOR *cursor) __cursor_novalue(cursor); WT_ERR(__clayered_enter(clayered, false, true, false)); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + /* * Copy the key out, since the insert resets non-primary chunk cursors which our lookup may have * landed on. @@ -2442,6 +2463,8 @@ __clayered_reserve(WT_CURSOR *cursor) CURSOR_UPDATE_API_CALL(cursor, session, ret, reserve, clayered->dhandle); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + /* * Since a search will be performed afterward that clears the iteration flags, no point to * retain the flags. @@ -2834,6 +2857,9 @@ __clayered_modify(WT_CURSOR *cursor, WT_MODIFY *entries, int nentries) WT_CURSOR_LAYERED *clayered = (WT_CURSOR_LAYERED *)cursor; CURSOR_UPDATE_API_CALL(cursor, session, ret, modify, clayered->dhandle); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + /* * Modify keeps the cursor positioned. Retain the iteration flags if we are in the middle of a * cursor traversal. diff --git a/src/third_party/wiredtiger/src/cursor/cur_table.c b/src/third_party/wiredtiger/src/cursor/cur_table.c index ea10eb1ab18..77ea9cc2f65 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_table.c +++ b/src/third_party/wiredtiger/src/cursor/cur_table.c @@ -266,6 +266,9 @@ __curtable_next(WT_CURSOR *cursor) ctable = (WT_CURSOR_TABLE *)cursor; CURSOR_API_CALL(cursor, session, ret, next, NULL); CURSOR_REPOSITION_ENTER(cursor, session); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + APPLY_CG(ctable, next); err: @@ -321,6 +324,9 @@ __curtable_prev(WT_CURSOR *cursor) ctable = (WT_CURSOR_TABLE *)cursor; CURSOR_API_CALL(cursor, session, ret, prev, NULL); CURSOR_REPOSITION_ENTER(cursor, session); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + APPLY_CG(ctable, prev); err: @@ -377,6 +383,9 @@ __curtable_search(WT_CURSOR *cursor) CURSOR_API_CALL(cursor, session, ret, search, NULL); API_RETRYABLE(session); CURSOR_REPOSITION_ENTER(cursor, session); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + APPLY_CG(ctable, search); err: @@ -403,6 +412,8 @@ __curtable_search_near(WT_CURSOR *cursor, int *exact) API_RETRYABLE(session); CURSOR_REPOSITION_ENTER(cursor, session); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + cp = ctable->cg_cursors; primary = *cp; WT_ERR(primary->search_near(primary, exact)); @@ -437,6 +448,9 @@ __curtable_insert(WT_CURSOR *cursor) ctable = (WT_CURSOR_TABLE *)cursor; CURSOR_UPDATE_API_CALL(cursor, session, ret, insert, NULL); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__curtable_open_indices(ctable)); cp = ctable->cg_cursors; @@ -515,6 +529,9 @@ __curtable_update(WT_CURSOR *cursor) ctable = (WT_CURSOR_TABLE *)cursor; CURSOR_UPDATE_API_CALL(cursor, session, ret, update, NULL); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__curtable_open_indices(ctable)); /* @@ -567,6 +584,9 @@ __curtable_remove(WT_CURSOR *cursor) ctable = (WT_CURSOR_TABLE *)cursor; CURSOR_REMOVE_API_CALL(cursor, session, ret, NULL); + + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + WT_ERR(__curtable_open_indices(ctable)); /* Check if the cursor was positioned. */ @@ -613,6 +633,8 @@ __curtable_reserve(WT_CURSOR *cursor) ctable = (WT_CURSOR_TABLE *)cursor; CURSOR_UPDATE_API_CALL(cursor, session, ret, reserve, NULL); + CURSOR_API_CHECK_SYSTEM_OVERLOAD(session, ret); + /* * We don't have to open the indices here, but it makes the code similar to other cursor * functions, and it's odd for a reserve call to succeed but the subsequent update fail opening diff --git a/src/third_party/wiredtiger/src/docs/arch-index.dox b/src/third_party/wiredtiger/src/docs/arch-index.dox index b9f3fa8ee24..d357eca5308 100644 --- a/src/third_party/wiredtiger/src/docs/arch-index.dox +++ b/src/third_party/wiredtiger/src/docs/arch-index.dox @@ -199,6 +199,7 @@ of the documentation. - @ref arch-fs-os - @subpage arch-toc-disaggregated-storage + - @ref arch-page-delta - @ref arch-disagg-layered - @ref arch-disagg-layered-cursor - @ref arch-disagg-key-provider @@ -380,6 +381,7 @@ operation. /*! @page arch-toc-disaggregated-storage Disaggregated Storage +@subpage arch-page-delta @subpage arch-disagg-layered @subpage arch-disagg-layered-cursor @subpage arch-disagg-key-provider diff --git a/src/third_party/wiredtiger/src/docs/arch-page-delta.dox b/src/third_party/wiredtiger/src/docs/arch-page-delta.dox new file mode 100644 index 00000000000..bdcef26fdea --- /dev/null +++ b/src/third_party/wiredtiger/src/docs/arch-page-delta.dox @@ -0,0 +1,154 @@ +/*! @arch_page arch-page-delta Page Deltas + +WiredTiger's page delta feature reduces write amplification and I/O by writing +only the changed entries for a page (a delta) rather than always +rewriting the full page image during reconciliation. This feature is used +exclusively with disaggregated (layered) row-store btrees. + +@section pd_goals Goals and high-level model + +Instead of always writing a full page image on reconciliation, WiredTiger can write: +- A base page image (full page), and +- A bounded chain of deltas on top of that base. + +On disk the block for a page therefore contains either: +- Only a full page image, or +- A full page image plus one or more delta images. + +A delta chain is the sequence of deltas that must be applied to the most +recent full page image (the "base image") to reconstruct the latest page state. Its +maximum length is bounded by the \c page_delta.max_consecutive_delta configuration +option. + +Page deltas only apply to row-store pages (\c WT_PAGE_ROW_LEAF and +\c WT_PAGE_ROW_INT). Column-store pages do not participate in this framework. +Deltas are also never written for non-disaggregated tables the btree must have +the \c WT_BTREE_DISAGGREGATED flag set (set automatically for layered btrees). + +@section pd_config Configuration + +Page delta behavior is controlled via the \c page_delta sub-config at +\c wiredtiger_open or \c reconfigure time: + +- \c page_delta.leaf_page_delta (bool): enable leaf page deltas. +- \c page_delta.internal_page_delta (bool): enable internal page deltas. +- \c page_delta.delta_pct (int): maximum allowed size of a delta as a percentage + of the full page size. Candidates that exceed this threshold fall back to a + full page write. +- \c page_delta.max_consecutive_delta (int): maximum number of deltas in a chain + for a single page. When this limit would be exceeded, reconciliation writes a + full page image and resets the chain. + +These settings are stored at the connection level in \c WT_PAGE_DELTA_CONFIG +(see \c src/include/connection.h). The flags \c WT_LEAF_PAGE_DELTA and +\c WT_INTERNAL_PAGE_DELTA are derived from them at startup or reconfig time. + +Whether a given btree and page type actually use deltas is controlled by the +macros \c WT_DELTA_LEAF_ENABLED and \c WT_DELTA_INT_ENABLED, both of which +additionally require the btree to have the \c WT_BTREE_DISAGGREGATED flag set. + +@section pd_generation Generating deltas (reconciliation) + +Deltas are generated during reconciliation (\c __wt_reconcile). The two page +types follow different paths: + +- For a leaf page: after the full disk image is built, the delta build function + is called if the page has not undergone an in-memory split and the reconciliation + produced a single block result. +- For an internal page: the delta decision and entry packing happen concurrently + with building the full page image. Modified children are packed into the delta buffer + as the child-walk proceeds. Once the full page image is complete, the write generation + field is updated onto the already-populated delta buffer. + +After a candidate delta is built, the write path validates whether the delta can +be written or whether a full page image is required, and takes the decision accordingly: + +1. If \c block_meta->delta_count has reached \c max_consecutive_delta, the delta + is rejected and a full page image is written instead, resetting the chain. +2. If the built delta's size exceeds \c delta_pct percent of the full page image, it + is also rejected. +3. Several structural reasons can also prevent a delta from being used: the + reconcile produced multiple blocks, the page has no stable LSN yet, the + result is not a single page, the leaf delta is empty, or the delta build + returned no entries. + +When a delta is accepted, it is written by \c __rec_write_delta and +\c block_meta->delta_count is incremented. + +@subsection pd_leaf Leaf page deltas + +\c __rec_build_delta_leaf iterates over the saved-updates list (\c supd) for the +page. For each key whose selected on-page value has changed since the last +reconciliation (\c __rec_selected_key_changed), it packs a key/value entry into +the delta buffer via \c __wti_rec_pack_delta_row_leaf. Only keys that actually +changed are included, making the delta compact for workloads with sparse updates. +Each packed entry carries full MVCC time-window metadata so reconstruction can +respect visibility rules identically to a full page image. + +@subsection pd_internal Internal page deltas + +Internal page deltas are built during the row-store internal reconcile pass in +\c src/reconcile/rec_row.c. Each child-address change (insert, update, or delete +of a sub-tree pointer) is packed into \c r->delta. + +@section pd_key_files Key files + +| File | Role | +|------|------| +| \c src/reconcile/rec_write.c | Delta creation decision and writing (\c __rec_build_delta, \c __rec_split_write, \c __rec_write_delta) | +| \c src/reconcile/rec_row.c | Delta packing per row for internal pages (\c __rec_pack_delta_row_int, \c __rec_build_delta_int) and leaf pages (\c __rec_build_delta_leaf entry helpers) | +| \c src/reconcile/rec_visibility.c | Update selection and time-window handling used by leaf delta packing | +| \c src/btree/bt_page.c | Merge helpers on read (\c __wti_page_merge_deltas_with_base_image_leaf, \c __wti_page_merge_deltas_with_base_image_int) | +| \c src/btree/bt_read.c | Page fault-in and delta reconstruction (\c __page_read_build_full_disk_image) | +| \c src/include/btmem.h | Chain-tracking structures (\c WT_PAGE_BLOCK_META, \c WT_PAGE_DISAGG_INFO) | +| \c src/include/connection.h | Connection-level delta config (\c WT_PAGE_DELTA_CONFIG) | +| \c src/include/btree.h | Enable macros (\c WT_DELTA_LEAF_ENABLED, \c WT_DELTA_INT_ENABLED) | +| \c src/reconcile/reconcile_private.h | Reconcile-time macros (\c WT_BUILD_DELTA_LEAF, \c WT_BUILD_DELTA_INT, \c WT_REC_RESULT_SINGLE_PAGE) | + +@section pd_on_disk On-disk layout and chain tracking + +The per-page delta chain state is kept in \c WT_PAGE_BLOCK_META +(see \c src/include/btmem.h): + +- \c delta_count: number of deltas written on top of the current base image + (a \c uint8_t, so the theoretical maximum is 255; keep + \c max_consecutive_delta well below this in practice). +- \c base_lsn: LSN of the base full-image block in the page log. +- \c backlink_lsn: LSN of the previous delta (or base) in the chain. +- \c cumulative_size: total byte size of the base image plus all deltas. + +\c WT_PAGE_BLOCK_META lives inside \c WT_PAGE_DISAGG_INFO, which is attached to +the in-memory page via \c page->disagg_info. + +@section pd_reconstruction Reconstruction on read + +When a page is read from storage and has \c delta_count > 0, the read path in +\c __page_read_build_full_disk_image (see \c src/btree/bt_read.c) merges the +base image with all delta images into a single complete disk image before +building the in-memory page. The rest of the read path then proceeds identically +to the non-delta case. + +The merge helpers live in \c src/btree/bt_page.c: + +- \c __wti_page_merge_deltas_with_base_image_leaf: merges base leaf image and + all leaf deltas in key order. For each key the newest delta entry wins; + delta deletes remove the key. The result is a valid leaf page disk image + reflecting the latest logical state. +- \c __wti_page_merge_deltas_with_base_image_int: merges base internal image + and all internal deltas. Each child address is either kept from the base or + replaced/removed according to the newest delta entry. + +@section pd_tuning Tuning + +The primary tuning levers are: + +- \c page_delta.delta_pct: raise to allow larger deltas, lower to keep them compact. +- \c page_delta.max_consecutive_delta: raise to extend chains and maximize write + savings, lower to bound read reconstruction cost. + +The right balance depends on the read/write ratio and how many keys are updated +per page per checkpoint cycle. Write-heavy workloads with sparse updates benefit +most. Read-heavy workloads or workloads that touch every key on a page should +use short chains (\c max_consecutive_delta of 48). + +*/ diff --git a/src/third_party/wiredtiger/src/docs/spell.ok b/src/third_party/wiredtiger/src/docs/spell.ok index 4af4aa32b84..4b9da43e2ae 100644 --- a/src/third_party/wiredtiger/src/docs/spell.ok +++ b/src/third_party/wiredtiger/src/docs/spell.ok @@ -127,6 +127,7 @@ NUMA NoSQL OOP OPTYPE +Observability PALI PALite PMU @@ -220,6 +221,7 @@ autoconf autogen automake backend +backlink basecfg basho benchmarking @@ -544,6 +546,7 @@ msec msg msgs multi +multiblock multiprocess multithreaded multithreading @@ -720,6 +723,7 @@ subpage substring subsubsection sudo +supd superset svg sys diff --git a/src/third_party/wiredtiger/src/include/api.h b/src/third_party/wiredtiger/src/include/api.h index 6c9d18d1e48..f9cc577511d 100644 --- a/src/third_party/wiredtiger/src/include/api.h +++ b/src/third_party/wiredtiger/src/include/api.h @@ -8,54 +8,6 @@ #pragma once -#ifdef HAVE_DIAGNOSTIC -/* - * Capture cases where a single session handle is used by multiple threads in parallel. The check - * isn't trivial because some API calls re-enter via public API entry points and the session with ID - * 0 is the default session in the connection handle which can be used across multiple threads. - */ -#define WT_SINGLE_THREAD_CHECK_START(s) \ - { \ - uintmax_t __tmp_api_tid; \ - __wt_thread_id(&__tmp_api_tid); \ - \ - /* \ - * Only a single thread should use this session at a time. It's ok \ - * (but unexpected) if different threads use the session consecutively, \ - * but concurrent access is not allowed. Verify this by having the thread \ - * take a lock on first API access. Failing to take the lock implies \ - * another thread holds it and we're attempting concurrent access of the \ - * session. \ - * \ - * The default session (ID == 0) is an exception where concurrent access \ - * is allowed. We can also skip taking the lock if we're re-entrant and \ - * already hold it. \ - */ \ - if (!WT_SESSION_IS_DEFAULT(s) && (s)->thread_check.owning_thread != __tmp_api_tid) { \ - bool lock_success = __wt_spin_trylock((s), &(s)->thread_check.lock); \ - WT_ASSERT((s), lock_success == 0); \ - (s)->thread_check.owning_thread = __tmp_api_tid; \ - } \ - \ - ++(s)->thread_check.entry_count; \ - } - -#define WT_SINGLE_THREAD_CHECK_STOP(s) \ - { \ - uintmax_t __tmp_api_tid; \ - __wt_thread_id(&__tmp_api_tid); \ - if (--((s)->thread_check.entry_count) == 0) { \ - if ((s)->id != 0) { \ - (s)->thread_check.owning_thread = 0; \ - __wt_spin_unlock((s), &(s)->thread_check.lock); \ - } \ - } \ - } -#else -#define WT_SINGLE_THREAD_CHECK_START(s) -#define WT_SINGLE_THREAD_CHECK_STOP(s) -#endif - #define API_SESSION_PUSH(s, struct_name, func_name, dh) \ WT_DATA_HANDLE *__olddh = (s)->dhandle; \ const char *__oldname; \ @@ -80,7 +32,7 @@ * correct. \ */ \ WT_ERR(WT_SESSION_CHECK_PANIC(s)); \ - WT_SINGLE_THREAD_CHECK_START(s); \ + __wt_single_thread_check_start(s); \ WT_TRACK_OP_INIT(s); \ if ((s)->api_call_counter == 1 && !F_ISSET(s, WT_SESSION_INTERNAL)) \ __wt_op_timer_start(s); \ @@ -128,7 +80,7 @@ #define API_END(s, ret) \ if ((s) != NULL) { \ WT_TRACK_OP_END(s); \ - WT_SINGLE_THREAD_CHECK_STOP(s); \ + __wt_single_thread_check_stop(s); \ if ((ret) != 0 && __set_err) \ __wt_txn_err_set(s, (ret)); \ if ((s)->api_call_counter == 1) { \ @@ -316,6 +268,19 @@ TXN_API_CALL(s, WT_SESSION, func_name, NULL, config, cfg); \ SESSION_API_PREPARE_CHECK(s, ret, WT_SESSION, func_name) +#define CURSOR_API_CHECK_SYSTEM_OVERLOAD(s, ret) \ + do { \ + if (API_USER_ENTRY(s) && \ + (!F_ISSET( \ + s, WT_SESSION_INTERNAL | WT_SESSION_CHECKPOINT | WT_SESSION_IGNORE_CACHE_SIZE))) { \ + if (__wt_conn_load_control_read_overload(s)) { \ + WT_STAT_CONN_INCR(s, read_reject_count); \ + (ret) = WT_ROLLBACK; \ + goto err; \ + } \ + } \ + } while (0) + #define CURSOR_API_CALL(cur, s, ret, func_name, dh) \ (s) = CUR2S(cur); \ API_CALL_NOCONF(s, WT_CURSOR, func_name, dh, true); \ @@ -337,10 +302,10 @@ WT_ERR(__wt_cursor_cached(cur)) /* - * API_RETRYABLE and API_RETRYABLE_END are used to wrap API calls so that they are silently - * retried on rollback errors. Generally, these only need to be used with readonly APIs, as - * writable APIs have their own retry code via TXN_API_CALL. These macros may be used with - * *API_CALL and API_END* provided they are ordered in a balanced way. + * API_RETRYABLE and API_RETRYABLE_END are used to wrap API calls so that they are silently retried + * on rollback errors. Generally, these only need to be used with readonly APIs, as writable APIs + * have their own retry code via TXN_API_CALL. These macros may be used with *API_CALL and API_END* + * provided they are ordered in a balanced way. */ #define API_RETRYABLE(s) do { diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h index 910592ddf37..5fd600b7422 100644 --- a/src/third_party/wiredtiger/src/include/extern.h +++ b/src/third_party/wiredtiger/src/include/extern.h @@ -2000,6 +2000,8 @@ static WT_INLINE bool __wt_conf_get_compiled(WT_CONNECTION_IMPL *conn, const cha WT_CONF **confp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); static WT_INLINE bool __wt_conf_is_compiled(WT_CONNECTION_IMPL *conn, const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +static WT_INLINE bool __wt_conn_load_control_read_overload(WT_SESSION_IMPL *session) + WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); static WT_INLINE bool __wt_conn_load_control_write_overload(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); static WT_INLINE bool __wt_cursor_has_cached_memory(WT_CURSOR *cursor) @@ -2580,6 +2582,8 @@ static WT_INLINE void __wt_row_leaf_value_set(WT_ROW *rip, WT_CELL_UNPACK_KV *un static WT_INLINE void __wt_scr_free(WT_SESSION_IMPL *session, WT_ITEM **bufp); static WT_INLINE void __wt_seconds(WT_SESSION_IMPL *session, uint64_t *secondsp); static WT_INLINE void __wt_seconds32(WT_SESSION_IMPL *session, uint32_t *secondsp); +static WT_INLINE void __wt_single_thread_check_start(WT_SESSION_IMPL *s); +static WT_INLINE void __wt_single_thread_check_stop(WT_SESSION_IMPL *s); static WT_INLINE void __wt_spin_backoff(uint64_t *yield_count, uint64_t *sleep_usecs); static WT_INLINE void __wt_spin_destroy(WT_SESSION_IMPL *session, WT_SPINLOCK *t); static WT_INLINE void __wt_spin_lock(WT_SESSION_IMPL *session, WT_SPINLOCK *t); diff --git a/src/third_party/wiredtiger/src/include/load_control_inline.h b/src/third_party/wiredtiger/src/include/load_control_inline.h index 1a8a3c4bd96..37eb12ada8e 100644 --- a/src/third_party/wiredtiger/src/include/load_control_inline.h +++ b/src/third_party/wiredtiger/src/include/load_control_inline.h @@ -12,6 +12,23 @@ extern "C" { #endif +/* + * __wt_conn_load_control_read_overload -- + * check if the system is read overloaded. + */ +static WT_INLINE bool +__wt_conn_load_control_read_overload(WT_SESSION_IMPL *session) +{ + WT_CONNECTION_LOAD_CONTROL *load_control = &S2C(session)->load_control; + + /* If load control is enabled, check if the read load crossed the control threshold. */ + if (F_ISSET(load_control, WT_CONN_LOAD_CONTROL)) + return (load_control->control_threshold <= + __wt_atomic_load_uint8_relaxed(&load_control->read_load)); + + return (false); +} + /* * __wt_conn_load_control_write_overload -- * check if the system is write overloaded. diff --git a/src/third_party/wiredtiger/src/include/session.h b/src/third_party/wiredtiger/src/include/session.h index 34b597b3bec..5650fde2bdc 100644 --- a/src/third_party/wiredtiger/src/include/session.h +++ b/src/third_party/wiredtiger/src/include/session.h @@ -292,13 +292,12 @@ struct __wt_session_impl { #endif #ifdef HAVE_UNITTEST_ASSERTS -/* - * Unit testing assertions requires overriding abort logic and instead capturing this information to - * be checked by the unit test. - */ -#define WT_SESSION_UNITTEST_BUF_LEN 100 + /* + * Unit testing assertions requires overriding abort logic and instead capturing this + * information to be checked by the unit test. + */ bool unittest_assert_hit; - char unittest_assert_msg[WT_SESSION_UNITTEST_BUF_LEN]; + char unittest_assert_msg[WT_ERR_MSG_BUF_LEN]; #endif /* AUTOMATIC FLAG VALUE GENERATION START 0 */ diff --git a/src/third_party/wiredtiger/src/include/session_inline.h b/src/third_party/wiredtiger/src/include/session_inline.h new file mode 100644 index 00000000000..8061b6dd8d9 --- /dev/null +++ b/src/third_party/wiredtiger/src/include/session_inline.h @@ -0,0 +1,66 @@ +/*- + * Copyright (c) 2014-present MongoDB, Inc. + * Copyright (c) 2008-2014 WiredTiger, Inc. + * All rights reserved. + * + * See the file LICENSE for redistribution information. + */ + +#pragma once + +/* + * __wt_single_thread_check_start -- + * Only a single thread should use this session at a time. It's ok (but unexpected) if different + * threads use the session consecutively, but concurrent access is not allowed. Verify this by + * having the thread take a lock on first API access. Failing to take the lock implies another + * thread holds it and we're attempting concurrent access of the session. + * + * The default session (ID == 0) is an exception where concurrent access is allowed. We can also + * skip taking the lock if we're re-entrant and already hold it. + */ +static WT_INLINE void +__wt_single_thread_check_start(WT_SESSION_IMPL *s) +{ +#if !defined(HAVE_DIAGNOSTIC) + WT_UNUSED(s); + return; +#else + uintmax_t current_tid; + WT_DECL_RET; + + __wt_thread_id(¤t_tid); + if (!WT_SESSION_IS_DEFAULT(s) && s->thread_check.owning_thread != current_tid) { + ret = __wt_spin_trylock(s, &s->thread_check.lock); + + WT_ASSERT_ALWAYS(s, ret == 0, + "Session %" PRIu32 + " is accessed concurrently by multiple threads: " + "current thread %" PRIuMAX ", owning thread %" PRIuMAX + " (active op: %s, last op: %s, api depth: %u, dhandle: %s)", + s->id, current_tid, s->thread_check.owning_thread, s->name != NULL ? s->name : "none", + s->lastop != NULL ? s->lastop : "none", s->api_call_counter, + s->dhandle != NULL ? s->dhandle->name : "none"); + + s->thread_check.owning_thread = current_tid; + } + ++s->thread_check.entry_count; +#endif +} + +/* + * __wt_single_thread_check_stop -- + * Release the single-thread ownership of this session. + */ +static WT_INLINE void +__wt_single_thread_check_stop(WT_SESSION_IMPL *s) +{ +#if !defined(HAVE_DIAGNOSTIC) + WT_UNUSED(s); + return; +#else + if (--s->thread_check.entry_count == 0 && !WT_SESSION_IS_DEFAULT(s)) { + s->thread_check.owning_thread = 0; + __wt_spin_unlock(s, &s->thread_check.lock); + } +#endif +} diff --git a/src/third_party/wiredtiger/src/include/stat.h b/src/third_party/wiredtiger/src/include/stat.h index e0a0695b7e4..654b41d0f27 100644 --- a/src/third_party/wiredtiger/src/include/stat.h +++ b/src/third_party/wiredtiger/src/include/stat.h @@ -1036,6 +1036,7 @@ struct __wt_connection_stats { int64_t live_restore_hist_source_read_latency_gt1000; int64_t live_restore_hist_source_read_latency_total_msecs; int64_t live_restore_state; + int64_t read_reject_count; int64_t write_reject_count; int64_t read_load; int64_t write_load; diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.h.in b/src/third_party/wiredtiger/src/include/wiredtiger.h.in index 7b3ab29b1fa..483a7335fb4 100644 --- a/src/third_party/wiredtiger/src/include/wiredtiger.h.in +++ b/src/third_party/wiredtiger/src/include/wiredtiger.h.in @@ -7877,1078 +7877,1080 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection); #define WT_STAT_CONN_LIVE_RESTORE_HIST_SOURCE_READ_LATENCY_TOTAL_MSECS 1608 /*! live-restore: state */ #define WT_STAT_CONN_LIVE_RESTORE_STATE 1609 +/*! load-control: number of read operations rejected due to load control */ +#define WT_STAT_CONN_READ_REJECT_COUNT 1610 /*! load-control: number of write operations rejected due to load control */ -#define WT_STAT_CONN_WRITE_REJECT_COUNT 1610 +#define WT_STAT_CONN_WRITE_REJECT_COUNT 1611 /*! load-control: read load at the system level */ -#define WT_STAT_CONN_READ_LOAD 1611 +#define WT_STAT_CONN_READ_LOAD 1612 /*! load-control: write load at the system level */ -#define WT_STAT_CONN_WRITE_LOAD 1612 +#define WT_STAT_CONN_WRITE_LOAD 1613 /*! lock: btree page lock acquisitions */ -#define WT_STAT_CONN_LOCK_BTREE_PAGE_COUNT 1613 +#define WT_STAT_CONN_LOCK_BTREE_PAGE_COUNT 1614 /*! lock: btree page lock application thread wait time (usecs) */ -#define WT_STAT_CONN_LOCK_BTREE_PAGE_WAIT_APPLICATION 1614 +#define WT_STAT_CONN_LOCK_BTREE_PAGE_WAIT_APPLICATION 1615 /*! lock: btree page lock internal thread wait time (usecs) */ -#define WT_STAT_CONN_LOCK_BTREE_PAGE_WAIT_INTERNAL 1615 +#define WT_STAT_CONN_LOCK_BTREE_PAGE_WAIT_INTERNAL 1616 /*! lock: checkpoint lock acquisitions */ -#define WT_STAT_CONN_LOCK_CHECKPOINT_COUNT 1616 +#define WT_STAT_CONN_LOCK_CHECKPOINT_COUNT 1617 /*! lock: checkpoint lock application thread wait time (usecs) */ -#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_APPLICATION 1617 +#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_APPLICATION 1618 /*! lock: checkpoint lock internal thread wait time (usecs) */ -#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_INTERNAL 1618 +#define WT_STAT_CONN_LOCK_CHECKPOINT_WAIT_INTERNAL 1619 /*! lock: dhandle lock application thread time waiting (usecs) */ -#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_APPLICATION 1619 +#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_APPLICATION 1620 /*! lock: dhandle lock internal thread time waiting (usecs) */ -#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_INTERNAL 1620 +#define WT_STAT_CONN_LOCK_DHANDLE_WAIT_INTERNAL 1621 /*! lock: dhandle read lock acquisitions */ -#define WT_STAT_CONN_LOCK_DHANDLE_READ_COUNT 1621 +#define WT_STAT_CONN_LOCK_DHANDLE_READ_COUNT 1622 /*! lock: dhandle write lock acquisitions */ -#define WT_STAT_CONN_LOCK_DHANDLE_WRITE_COUNT 1622 +#define WT_STAT_CONN_LOCK_DHANDLE_WRITE_COUNT 1623 /*! lock: metadata lock acquisitions */ -#define WT_STAT_CONN_LOCK_METADATA_COUNT 1623 +#define WT_STAT_CONN_LOCK_METADATA_COUNT 1624 /*! lock: metadata lock application thread wait time (usecs) */ -#define WT_STAT_CONN_LOCK_METADATA_WAIT_APPLICATION 1624 +#define WT_STAT_CONN_LOCK_METADATA_WAIT_APPLICATION 1625 /*! lock: metadata lock internal thread wait time (usecs) */ -#define WT_STAT_CONN_LOCK_METADATA_WAIT_INTERNAL 1625 +#define WT_STAT_CONN_LOCK_METADATA_WAIT_INTERNAL 1626 /*! lock: schema lock acquisitions */ -#define WT_STAT_CONN_LOCK_SCHEMA_COUNT 1626 +#define WT_STAT_CONN_LOCK_SCHEMA_COUNT 1627 /*! lock: schema lock application thread wait time (usecs) */ -#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_APPLICATION 1627 +#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_APPLICATION 1628 /*! lock: schema lock internal thread wait time (usecs) */ -#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_INTERNAL 1628 +#define WT_STAT_CONN_LOCK_SCHEMA_WAIT_INTERNAL 1629 /*! * lock: table lock application thread time waiting for the table lock * (usecs) */ -#define WT_STAT_CONN_LOCK_TABLE_WAIT_APPLICATION 1629 +#define WT_STAT_CONN_LOCK_TABLE_WAIT_APPLICATION 1630 /*! * lock: table lock internal thread time waiting for the table lock * (usecs) */ -#define WT_STAT_CONN_LOCK_TABLE_WAIT_INTERNAL 1630 +#define WT_STAT_CONN_LOCK_TABLE_WAIT_INTERNAL 1631 /*! lock: table read lock acquisitions */ -#define WT_STAT_CONN_LOCK_TABLE_READ_COUNT 1631 +#define WT_STAT_CONN_LOCK_TABLE_READ_COUNT 1632 /*! lock: table write lock acquisitions */ -#define WT_STAT_CONN_LOCK_TABLE_WRITE_COUNT 1632 +#define WT_STAT_CONN_LOCK_TABLE_WRITE_COUNT 1633 /*! lock: txn global lock application thread time waiting (usecs) */ -#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_APPLICATION 1633 +#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_APPLICATION 1634 /*! lock: txn global lock internal thread time waiting (usecs) */ -#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_INTERNAL 1634 +#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WAIT_INTERNAL 1635 /*! lock: txn global read lock acquisitions */ -#define WT_STAT_CONN_LOCK_TXN_GLOBAL_READ_COUNT 1635 +#define WT_STAT_CONN_LOCK_TXN_GLOBAL_READ_COUNT 1636 /*! lock: txn global write lock acquisitions */ -#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WRITE_COUNT 1636 +#define WT_STAT_CONN_LOCK_TXN_GLOBAL_WRITE_COUNT 1637 /*! log: busy returns attempting to switch slots */ -#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1637 +#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1638 /*! log: force log remove time sleeping (usecs) */ -#define WT_STAT_CONN_LOG_FORCE_REMOVE_SLEEP 1638 +#define WT_STAT_CONN_LOG_FORCE_REMOVE_SLEEP 1639 /*! log: log bytes of payload data */ -#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1639 +#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1640 /*! log: log bytes written */ -#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1640 +#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1641 /*! log: log files manually zero-filled */ -#define WT_STAT_CONN_LOG_ZERO_FILLS 1641 +#define WT_STAT_CONN_LOG_ZERO_FILLS 1642 /*! log: log flush operations */ -#define WT_STAT_CONN_LOG_FLUSH 1642 +#define WT_STAT_CONN_LOG_FLUSH 1643 /*! log: log force write operations */ -#define WT_STAT_CONN_LOG_FORCE_WRITE 1643 +#define WT_STAT_CONN_LOG_FORCE_WRITE 1644 /*! log: log force write operations skipped */ -#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1644 +#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1645 /*! log: log records compressed */ -#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1645 +#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1646 /*! log: log records not compressed */ -#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1646 +#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1647 /*! log: log records too small to compress */ -#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1647 +#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1648 /*! log: log release advances write LSN */ -#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1648 +#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1649 /*! log: log scan operations */ -#define WT_STAT_CONN_LOG_SCANS 1649 +#define WT_STAT_CONN_LOG_SCANS 1650 /*! log: log scan records requiring two reads */ -#define WT_STAT_CONN_LOG_SCAN_REREADS 1650 +#define WT_STAT_CONN_LOG_SCAN_REREADS 1651 /*! log: log server thread advances write LSN */ -#define WT_STAT_CONN_LOG_WRITE_LSN 1651 +#define WT_STAT_CONN_LOG_WRITE_LSN 1652 /*! log: log server thread write LSN walk skipped */ -#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1652 +#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1653 /*! log: log sync operations */ -#define WT_STAT_CONN_LOG_SYNC 1653 +#define WT_STAT_CONN_LOG_SYNC 1654 /*! log: log sync time duration (usecs) */ -#define WT_STAT_CONN_LOG_SYNC_DURATION 1654 +#define WT_STAT_CONN_LOG_SYNC_DURATION 1655 /*! log: log sync_dir operations */ -#define WT_STAT_CONN_LOG_SYNC_DIR 1655 +#define WT_STAT_CONN_LOG_SYNC_DIR 1656 /*! log: log sync_dir time duration (usecs) */ -#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1656 +#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1657 /*! log: log write operations */ -#define WT_STAT_CONN_LOG_WRITES 1657 +#define WT_STAT_CONN_LOG_WRITES 1658 /*! log: logging bytes consolidated */ -#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1658 +#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1659 /*! log: maximum log file size */ -#define WT_STAT_CONN_LOG_MAX_FILESIZE 1659 +#define WT_STAT_CONN_LOG_MAX_FILESIZE 1660 /*! log: number of pre-allocated log files to create */ -#define WT_STAT_CONN_LOG_PREALLOC_MAX 1660 +#define WT_STAT_CONN_LOG_PREALLOC_MAX 1661 /*! log: pre-allocated log files not ready and missed */ -#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1661 +#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1662 /*! log: pre-allocated log files prepared */ -#define WT_STAT_CONN_LOG_PREALLOC_FILES 1662 +#define WT_STAT_CONN_LOG_PREALLOC_FILES 1663 /*! log: pre-allocated log files used */ -#define WT_STAT_CONN_LOG_PREALLOC_USED 1663 +#define WT_STAT_CONN_LOG_PREALLOC_USED 1664 /*! log: records processed by log scan */ -#define WT_STAT_CONN_LOG_SCAN_RECORDS 1664 +#define WT_STAT_CONN_LOG_SCAN_RECORDS 1665 /*! log: slot close lost race */ -#define WT_STAT_CONN_LOG_SLOT_CLOSE_RACE 1665 +#define WT_STAT_CONN_LOG_SLOT_CLOSE_RACE 1666 /*! log: slot close unbuffered waits */ -#define WT_STAT_CONN_LOG_SLOT_CLOSE_UNBUF 1666 +#define WT_STAT_CONN_LOG_SLOT_CLOSE_UNBUF 1667 /*! log: slot closures */ -#define WT_STAT_CONN_LOG_SLOT_CLOSES 1667 +#define WT_STAT_CONN_LOG_SLOT_CLOSES 1668 /*! log: slot join atomic update races */ -#define WT_STAT_CONN_LOG_SLOT_RACES 1668 +#define WT_STAT_CONN_LOG_SLOT_RACES 1669 /*! log: slot join calls atomic updates raced */ -#define WT_STAT_CONN_LOG_SLOT_YIELD_RACE 1669 +#define WT_STAT_CONN_LOG_SLOT_YIELD_RACE 1670 /*! log: slot join calls did not yield */ -#define WT_STAT_CONN_LOG_SLOT_IMMEDIATE 1670 +#define WT_STAT_CONN_LOG_SLOT_IMMEDIATE 1671 /*! log: slot join calls found active slot closed */ -#define WT_STAT_CONN_LOG_SLOT_YIELD_CLOSE 1671 +#define WT_STAT_CONN_LOG_SLOT_YIELD_CLOSE 1672 /*! log: slot join calls slept */ -#define WT_STAT_CONN_LOG_SLOT_YIELD_SLEEP 1672 +#define WT_STAT_CONN_LOG_SLOT_YIELD_SLEEP 1673 /*! log: slot join calls yielded */ -#define WT_STAT_CONN_LOG_SLOT_YIELD 1673 +#define WT_STAT_CONN_LOG_SLOT_YIELD 1674 /*! log: slot join found active slot closed */ -#define WT_STAT_CONN_LOG_SLOT_ACTIVE_CLOSED 1674 +#define WT_STAT_CONN_LOG_SLOT_ACTIVE_CLOSED 1675 /*! log: slot joins yield time (usecs) */ -#define WT_STAT_CONN_LOG_SLOT_YIELD_DURATION 1675 +#define WT_STAT_CONN_LOG_SLOT_YIELD_DURATION 1676 /*! log: slot transitions unable to find free slot */ -#define WT_STAT_CONN_LOG_SLOT_NO_FREE_SLOTS 1676 +#define WT_STAT_CONN_LOG_SLOT_NO_FREE_SLOTS 1677 /*! log: slot unbuffered writes */ -#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1677 +#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1678 /*! log: total in-memory size of compressed records */ -#define WT_STAT_CONN_LOG_COMPRESS_MEM 1678 +#define WT_STAT_CONN_LOG_COMPRESS_MEM 1679 /*! log: total log buffer size */ -#define WT_STAT_CONN_LOG_BUFFER_SIZE 1679 +#define WT_STAT_CONN_LOG_BUFFER_SIZE 1680 /*! log: total size of compressed records */ -#define WT_STAT_CONN_LOG_COMPRESS_LEN 1680 +#define WT_STAT_CONN_LOG_COMPRESS_LEN 1681 /*! log: written slots coalesced */ -#define WT_STAT_CONN_LOG_SLOT_COALESCED 1681 +#define WT_STAT_CONN_LOG_SLOT_COALESCED 1682 /*! log: yields waiting for previous log file close */ -#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1682 +#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1683 /*! perf: block manager read latency histogram (bucket 1) - 0-1ms */ -#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT2 1683 +#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT2 1684 /*! perf: block manager read latency histogram (bucket 2) - 2-4ms */ -#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT5 1684 +#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT5 1685 /*! perf: block manager read latency histogram (bucket 3) - 5-9ms */ -#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT10 1685 +#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT10 1686 /*! perf: block manager read latency histogram (bucket 4) - 10-49ms */ -#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT50 1686 +#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT50 1687 /*! perf: block manager read latency histogram (bucket 5) - 50-99ms */ -#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT100 1687 +#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT100 1688 /*! perf: block manager read latency histogram (bucket 6) - 100-249ms */ -#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT250 1688 +#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT250 1689 /*! perf: block manager read latency histogram (bucket 7) - 250-499ms */ -#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT500 1689 +#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT500 1690 /*! perf: block manager read latency histogram (bucket 8) - 500-999ms */ -#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT1000 1690 +#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_LT1000 1691 /*! perf: block manager read latency histogram (bucket 9) - 1000ms+ */ -#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_GT1000 1691 +#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_GT1000 1692 /*! perf: block manager read latency histogram total (msecs) */ -#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_TOTAL_MSECS 1692 +#define WT_STAT_CONN_PERF_HIST_BMREAD_LATENCY_TOTAL_MSECS 1693 /*! perf: block manager write latency histogram (bucket 1) - 0-1ms */ -#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT2 1693 +#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT2 1694 /*! perf: block manager write latency histogram (bucket 2) - 2-4ms */ -#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT5 1694 +#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT5 1695 /*! perf: block manager write latency histogram (bucket 3) - 5-9ms */ -#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT10 1695 +#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT10 1696 /*! perf: block manager write latency histogram (bucket 4) - 10-49ms */ -#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT50 1696 +#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT50 1697 /*! perf: block manager write latency histogram (bucket 5) - 50-99ms */ -#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT100 1697 +#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT100 1698 /*! perf: block manager write latency histogram (bucket 6) - 100-249ms */ -#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT250 1698 +#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT250 1699 /*! perf: block manager write latency histogram (bucket 7) - 250-499ms */ -#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT500 1699 +#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT500 1700 /*! perf: block manager write latency histogram (bucket 8) - 500-999ms */ -#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT1000 1700 +#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_LT1000 1701 /*! perf: block manager write latency histogram (bucket 9) - 1000ms+ */ -#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_GT1000 1701 +#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_GT1000 1702 /*! perf: block manager write latency histogram total (msecs) */ -#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_TOTAL_MSECS 1702 +#define WT_STAT_CONN_PERF_HIST_BMWRITE_LATENCY_TOTAL_MSECS 1703 /*! perf: disagg block manager read latency histogram (bucket 1) - 50-99us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT100 1703 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT100 1704 /*! * perf: disagg block manager read latency histogram (bucket 2) - * 100-249us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT250 1704 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT250 1705 /*! * perf: disagg block manager read latency histogram (bucket 3) - * 250-499us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT500 1705 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT500 1706 /*! * perf: disagg block manager read latency histogram (bucket 4) - * 500-999us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT1000 1706 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT1000 1707 /*! * perf: disagg block manager read latency histogram (bucket 5) - * 1000-2499us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT2500 1707 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT2500 1708 /*! * perf: disagg block manager read latency histogram (bucket 6) - * 2500-4999us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT5000 1708 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT5000 1709 /*! * perf: disagg block manager read latency histogram (bucket 7) - * 5000-9999us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT10000 1709 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_LT10000 1710 /*! * perf: disagg block manager read latency histogram (bucket 8) - * 10000us+ */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_GT10000 1710 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_GT10000 1711 /*! perf: disagg block manager read latency histogram total (usecs) */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_TOTAL_USECS 1711 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMREAD_LATENCY_TOTAL_USECS 1712 /*! * perf: disagg block manager write latency histogram (bucket 1) - * 50-99us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT100 1712 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT100 1713 /*! * perf: disagg block manager write latency histogram (bucket 2) - * 100-249us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT250 1713 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT250 1714 /*! * perf: disagg block manager write latency histogram (bucket 3) - * 250-499us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT500 1714 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT500 1715 /*! * perf: disagg block manager write latency histogram (bucket 4) - * 500-999us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT1000 1715 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT1000 1716 /*! * perf: disagg block manager write latency histogram (bucket 5) - * 1000-2499us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT2500 1716 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT2500 1717 /*! * perf: disagg block manager write latency histogram (bucket 6) - * 2500-4999us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT5000 1717 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT5000 1718 /*! * perf: disagg block manager write latency histogram (bucket 7) - * 5000-9999us */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT10000 1718 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_LT10000 1719 /*! * perf: disagg block manager write latency histogram (bucket 8) - * 10000us+ */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_GT10000 1719 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_GT10000 1720 /*! perf: disagg block manager write latency histogram total (usecs) */ -#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_TOTAL_USECS 1720 +#define WT_STAT_CONN_PERF_HIST_DISAGGBMWRITE_LATENCY_TOTAL_USECS 1721 /*! perf: file system read latency histogram (bucket 1) - 0-1ms */ -#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT2 1721 +#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT2 1722 /*! perf: file system read latency histogram (bucket 2) - 2-4ms */ -#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT5 1722 +#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT5 1723 /*! perf: file system read latency histogram (bucket 3) - 5-9ms */ -#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT10 1723 +#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT10 1724 /*! perf: file system read latency histogram (bucket 4) - 10-49ms */ -#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT50 1724 +#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT50 1725 /*! perf: file system read latency histogram (bucket 5) - 50-99ms */ -#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT100 1725 +#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT100 1726 /*! perf: file system read latency histogram (bucket 6) - 100-249ms */ -#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT250 1726 +#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT250 1727 /*! perf: file system read latency histogram (bucket 7) - 250-499ms */ -#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT500 1727 +#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT500 1728 /*! perf: file system read latency histogram (bucket 8) - 500-999ms */ -#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT1000 1728 +#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_LT1000 1729 /*! perf: file system read latency histogram (bucket 9) - 1000ms+ */ -#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_GT1000 1729 +#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_GT1000 1730 /*! perf: file system read latency histogram total (msecs) */ -#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_TOTAL_MSECS 1730 +#define WT_STAT_CONN_PERF_HIST_FSREAD_LATENCY_TOTAL_MSECS 1731 /*! perf: file system write latency histogram (bucket 1) - 0-1ms */ -#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT2 1731 +#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT2 1732 /*! perf: file system write latency histogram (bucket 2) - 2-4ms */ -#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT5 1732 +#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT5 1733 /*! perf: file system write latency histogram (bucket 3) - 5-9ms */ -#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT10 1733 +#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT10 1734 /*! perf: file system write latency histogram (bucket 4) - 10-49ms */ -#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT50 1734 +#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT50 1735 /*! perf: file system write latency histogram (bucket 5) - 50-99ms */ -#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT100 1735 +#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT100 1736 /*! perf: file system write latency histogram (bucket 6) - 100-249ms */ -#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT250 1736 +#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT250 1737 /*! perf: file system write latency histogram (bucket 7) - 250-499ms */ -#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT500 1737 +#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT500 1738 /*! perf: file system write latency histogram (bucket 8) - 500-999ms */ -#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT1000 1738 +#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_LT1000 1739 /*! perf: file system write latency histogram (bucket 9) - 1000ms+ */ -#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_GT1000 1739 +#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_GT1000 1740 /*! perf: file system write latency histogram total (msecs) */ -#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_TOTAL_MSECS 1740 +#define WT_STAT_CONN_PERF_HIST_FSWRITE_LATENCY_TOTAL_MSECS 1741 /*! * perf: internal page deltas reconstruct latency histogram (bucket 1) - * 0-100us */ -#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT100 1741 +#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT100 1742 /*! * perf: internal page deltas reconstruct latency histogram (bucket 2) - * 100-249us */ -#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT250 1742 +#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT250 1743 /*! * perf: internal page deltas reconstruct latency histogram (bucket 3) - * 250-499us */ -#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT500 1743 +#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT500 1744 /*! * perf: internal page deltas reconstruct latency histogram (bucket 4) - * 500-999us */ -#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT1000 1744 +#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT1000 1745 /*! * perf: internal page deltas reconstruct latency histogram (bucket 5) - * 1000-2499us */ -#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT2500 1745 +#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT2500 1746 /*! * perf: internal page deltas reconstruct latency histogram (bucket 6) - * 2500-4999us */ -#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT5000 1746 +#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT5000 1747 /*! * perf: internal page deltas reconstruct latency histogram (bucket 7) - * 5000-9999us */ -#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT10000 1747 +#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_LT10000 1748 /*! * perf: internal page deltas reconstruct latency histogram (bucket 8) - * 10000us+ */ -#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_GT10000 1748 +#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_GT10000 1749 /*! perf: internal page deltas reconstruct latency histogram total (usecs) */ -#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_TOTAL_USECS 1749 +#define WT_STAT_CONN_PERF_HIST_INTERNAL_RECONSTRUCT_LATENCY_TOTAL_USECS 1750 /*! * perf: leaf page deltas reconstruct latency histogram (bucket 1) - * 0-100us */ -#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT100 1750 +#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT100 1751 /*! * perf: leaf page deltas reconstruct latency histogram (bucket 2) - * 100-249us */ -#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT250 1751 +#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT250 1752 /*! * perf: leaf page deltas reconstruct latency histogram (bucket 3) - * 250-499us */ -#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT500 1752 +#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT500 1753 /*! * perf: leaf page deltas reconstruct latency histogram (bucket 4) - * 500-999us */ -#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT1000 1753 +#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT1000 1754 /*! * perf: leaf page deltas reconstruct latency histogram (bucket 5) - * 1000-2499us */ -#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT2500 1754 +#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT2500 1755 /*! * perf: leaf page deltas reconstruct latency histogram (bucket 6) - * 2500-4999us */ -#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT5000 1755 +#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT5000 1756 /*! * perf: leaf page deltas reconstruct latency histogram (bucket 7) - * 5000-9999us */ -#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT10000 1756 +#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_LT10000 1757 /*! * perf: leaf page deltas reconstruct latency histogram (bucket 8) - * 10000us+ */ -#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_GT10000 1757 +#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_GT10000 1758 /*! perf: leaf page deltas reconstruct latency histogram total (usecs) */ -#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_TOTAL_USECS 1758 +#define WT_STAT_CONN_PERF_HIST_LEAF_RECONSTRUCT_LATENCY_TOTAL_USECS 1759 /*! perf: operation read latency histogram (bucket 1) - 0-100us */ -#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT100 1759 +#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT100 1760 /*! perf: operation read latency histogram (bucket 2) - 100-249us */ -#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT250 1760 +#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT250 1761 /*! perf: operation read latency histogram (bucket 3) - 250-499us */ -#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT500 1761 +#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT500 1762 /*! perf: operation read latency histogram (bucket 4) - 500-999us */ -#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT1000 1762 +#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT1000 1763 /*! perf: operation read latency histogram (bucket 5) - 1000-2499us */ -#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT2500 1763 +#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT2500 1764 /*! perf: operation read latency histogram (bucket 6) - 2500-4999us */ -#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT5000 1764 +#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT5000 1765 /*! perf: operation read latency histogram (bucket 7) - 5000-9999us */ -#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT10000 1765 +#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_LT10000 1766 /*! perf: operation read latency histogram (bucket 8) - 10000us+ */ -#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_GT10000 1766 +#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_GT10000 1767 /*! perf: operation read latency histogram total (usecs) */ -#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_TOTAL_USECS 1767 +#define WT_STAT_CONN_PERF_HIST_OPREAD_LATENCY_TOTAL_USECS 1768 /*! perf: operation write latency histogram (bucket 1) - 0-100us */ -#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT100 1768 +#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT100 1769 /*! perf: operation write latency histogram (bucket 2) - 100-249us */ -#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT250 1769 +#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT250 1770 /*! perf: operation write latency histogram (bucket 3) - 250-499us */ -#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT500 1770 +#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT500 1771 /*! perf: operation write latency histogram (bucket 4) - 500-999us */ -#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT1000 1771 +#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT1000 1772 /*! perf: operation write latency histogram (bucket 5) - 1000-2499us */ -#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT2500 1772 +#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT2500 1773 /*! perf: operation write latency histogram (bucket 6) - 2500-4999us */ -#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT5000 1773 +#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT5000 1774 /*! perf: operation write latency histogram (bucket 7) - 5000-9999us */ -#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT10000 1774 +#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_LT10000 1775 /*! perf: operation write latency histogram (bucket 8) - 10000us+ */ -#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_GT10000 1775 +#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_GT10000 1776 /*! perf: operation write latency histogram total (usecs) */ -#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_TOTAL_USECS 1776 +#define WT_STAT_CONN_PERF_HIST_OPWRITE_LATENCY_TOTAL_USECS 1777 /*! prefetch: could not perform pre-fetch on internal page */ -#define WT_STAT_CONN_PREFETCH_SKIPPED_INTERNAL_PAGE 1777 +#define WT_STAT_CONN_PREFETCH_SKIPPED_INTERNAL_PAGE 1778 /*! * prefetch: could not perform pre-fetch on ref without the pre-fetch * flag set */ -#define WT_STAT_CONN_PREFETCH_SKIPPED_NO_FLAG_SET 1778 +#define WT_STAT_CONN_PREFETCH_SKIPPED_NO_FLAG_SET 1779 /*! prefetch: pre-fetch attempted, session has pre-fetching enabled */ -#define WT_STAT_CONN_PREFETCH_ATTEMPTS 1779 +#define WT_STAT_CONN_PREFETCH_ATTEMPTS 1780 /*! prefetch: pre-fetch not repeating for recently pre-fetched ref */ -#define WT_STAT_CONN_PREFETCH_SKIPPED_SAME_REF 1780 +#define WT_STAT_CONN_PREFETCH_SKIPPED_SAME_REF 1781 /*! prefetch: pre-fetch not triggered after single disk read */ -#define WT_STAT_CONN_PREFETCH_DISK_ONE 1781 +#define WT_STAT_CONN_PREFETCH_DISK_ONE 1782 /*! prefetch: pre-fetch not triggered as there is no valid dhandle */ -#define WT_STAT_CONN_PREFETCH_SKIPPED_NO_VALID_DHANDLE 1782 +#define WT_STAT_CONN_PREFETCH_SKIPPED_NO_VALID_DHANDLE 1783 /*! prefetch: pre-fetch not triggered due to disk read count */ -#define WT_STAT_CONN_PREFETCH_SKIPPED_DISK_READ_COUNT 1783 +#define WT_STAT_CONN_PREFETCH_SKIPPED_DISK_READ_COUNT 1784 /*! prefetch: pre-fetch not triggered due to internal session */ -#define WT_STAT_CONN_PREFETCH_SKIPPED_INTERNAL_SESSION 1784 +#define WT_STAT_CONN_PREFETCH_SKIPPED_INTERNAL_SESSION 1785 /*! prefetch: pre-fetch not triggered due to special btree handle */ -#define WT_STAT_CONN_PREFETCH_SKIPPED_SPECIAL_HANDLE 1785 +#define WT_STAT_CONN_PREFETCH_SKIPPED_SPECIAL_HANDLE 1786 /*! prefetch: pre-fetch not triggered, pre-fetch queue is full */ -#define WT_STAT_CONN_PREFETCH_SKIPPED_QUEUE_FULL 1786 +#define WT_STAT_CONN_PREFETCH_SKIPPED_QUEUE_FULL 1787 /*! prefetch: pre-fetch page not on disk when reading */ -#define WT_STAT_CONN_PREFETCH_PAGES_FAIL 1787 +#define WT_STAT_CONN_PREFETCH_PAGES_FAIL 1788 /*! prefetch: pre-fetch pages queued */ -#define WT_STAT_CONN_PREFETCH_PAGES_QUEUED 1788 +#define WT_STAT_CONN_PREFETCH_PAGES_QUEUED 1789 /*! prefetch: pre-fetch pages read in background */ -#define WT_STAT_CONN_PREFETCH_PAGES_READ 1789 +#define WT_STAT_CONN_PREFETCH_PAGES_READ 1790 /*! * prefetch: pre-fetch session check passed, pre-fetch work issued to * btree */ -#define WT_STAT_CONN_PREFETCH_ATTEMPTS_SUCCEEDED 1790 +#define WT_STAT_CONN_PREFETCH_ATTEMPTS_SUCCEEDED 1791 /*! prefetch: pre-fetch skipped reading in a page due to harmless error */ -#define WT_STAT_CONN_PREFETCH_SKIPPED_ERROR_OK 1791 +#define WT_STAT_CONN_PREFETCH_SKIPPED_ERROR_OK 1792 /*! * prefetch: pre-fetch skipped traversal of internal page due to active * split generation */ -#define WT_STAT_CONN_PREFETCH_SKIPPED_INTERNAL_SPLIT_GEN 1792 +#define WT_STAT_CONN_PREFETCH_SKIPPED_INTERNAL_SPLIT_GEN 1793 /*! reconciliation: VLCS pages explicitly reconciled as empty */ -#define WT_STAT_CONN_REC_VLCS_EMPTIED_PAGES 1793 +#define WT_STAT_CONN_REC_VLCS_EMPTIED_PAGES 1794 /*! reconciliation: approximate byte size of timestamps in pages written */ -#define WT_STAT_CONN_REC_TIME_WINDOW_BYTES_TS 1794 +#define WT_STAT_CONN_REC_TIME_WINDOW_BYTES_TS 1795 /*! * reconciliation: approximate byte size of transaction IDs in pages * written */ -#define WT_STAT_CONN_REC_TIME_WINDOW_BYTES_TXN 1795 +#define WT_STAT_CONN_REC_TIME_WINDOW_BYTES_TXN 1796 /*! * reconciliation: average length of delta chain on internal page with * deltas */ -#define WT_STAT_CONN_REC_AVERAGE_INTERNAL_PAGE_DELTA_CHAIN_LENGTH 1796 +#define WT_STAT_CONN_REC_AVERAGE_INTERNAL_PAGE_DELTA_CHAIN_LENGTH 1797 /*! reconciliation: average length of delta chain on leaf page with deltas */ -#define WT_STAT_CONN_REC_AVERAGE_LEAF_PAGE_DELTA_CHAIN_LENGTH 1797 +#define WT_STAT_CONN_REC_AVERAGE_LEAF_PAGE_DELTA_CHAIN_LENGTH 1798 /*! * reconciliation: changes since prior reconciliation (bucket 1) between * 1 and 5 */ -#define WT_STAT_CONN_REC_PAGE_MODS_LE5 1798 +#define WT_STAT_CONN_REC_PAGE_MODS_LE5 1799 /*! * reconciliation: changes since prior reconciliation (bucket 2) between * 6 and 10 */ -#define WT_STAT_CONN_REC_PAGE_MODS_LE10 1799 +#define WT_STAT_CONN_REC_PAGE_MODS_LE10 1800 /*! * reconciliation: changes since prior reconciliation (bucket 3) between * 11 and 20 */ -#define WT_STAT_CONN_REC_PAGE_MODS_LE20 1800 +#define WT_STAT_CONN_REC_PAGE_MODS_LE20 1801 /*! * reconciliation: changes since prior reconciliation (bucket 4) between * 21 and 50 */ -#define WT_STAT_CONN_REC_PAGE_MODS_LE50 1801 +#define WT_STAT_CONN_REC_PAGE_MODS_LE50 1802 /*! * reconciliation: changes since prior reconciliation (bucket 5) between * 51 and 100 */ -#define WT_STAT_CONN_REC_PAGE_MODS_LE100 1802 +#define WT_STAT_CONN_REC_PAGE_MODS_LE100 1803 /*! * reconciliation: changes since prior reconciliation (bucket 6) between * 101 and 200 */ -#define WT_STAT_CONN_REC_PAGE_MODS_LE200 1803 +#define WT_STAT_CONN_REC_PAGE_MODS_LE200 1804 /*! * reconciliation: changes since prior reconciliation (bucket 7) between * 201 and 500 */ -#define WT_STAT_CONN_REC_PAGE_MODS_LE500 1804 +#define WT_STAT_CONN_REC_PAGE_MODS_LE500 1805 /*! * reconciliation: changes since prior reconciliation (bucket 8) greater * than 500 */ -#define WT_STAT_CONN_REC_PAGE_MODS_GT500 1805 +#define WT_STAT_CONN_REC_PAGE_MODS_GT500 1806 /*! reconciliation: cursor next/prev calls during HS wrapup search_near */ -#define WT_STAT_CONN_REC_HS_WRAPUP_NEXT_PREV_CALLS 1806 +#define WT_STAT_CONN_REC_HS_WRAPUP_NEXT_PREV_CALLS 1807 /*! reconciliation: fast-path pages deleted */ -#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1807 +#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1808 /*! * reconciliation: free page ID due to failed page replacement * reconciliation in disagg */ -#define WT_STAT_CONN_REC_FREE_PAGE_ID_DUE_TO_FAILED_REPLACEMENT_RECONCILIATION 1808 +#define WT_STAT_CONN_REC_FREE_PAGE_ID_DUE_TO_FAILED_REPLACEMENT_RECONCILIATION 1809 /*! reconciliation: full internal pages written instead of a page delta */ -#define WT_STAT_CONN_REC_PAGE_FULL_IMAGE_INTERNAL 1809 +#define WT_STAT_CONN_REC_PAGE_FULL_IMAGE_INTERNAL 1810 /*! reconciliation: full leaf pages written instead of a page delta */ -#define WT_STAT_CONN_REC_PAGE_FULL_IMAGE_LEAF 1810 +#define WT_STAT_CONN_REC_PAGE_FULL_IMAGE_LEAF 1811 /*! * reconciliation: ingest btree reconciliation keeps the aborted prepare * updates */ -#define WT_STAT_CONN_REC_INGEST_KEEP_PREPARE_ROLLBACK 1811 +#define WT_STAT_CONN_REC_INGEST_KEEP_PREPARE_ROLLBACK 1812 /*! reconciliation: internal page delta keys deleted */ -#define WT_STAT_CONN_REC_PAGE_DELTA_INTERNAL_KEY_DELETED 1812 +#define WT_STAT_CONN_REC_PAGE_DELTA_INTERNAL_KEY_DELETED 1813 /*! reconciliation: internal page delta keys updated/inserted */ -#define WT_STAT_CONN_REC_PAGE_DELTA_INTERNAL_KEY_UPDATED 1813 +#define WT_STAT_CONN_REC_PAGE_DELTA_INTERNAL_KEY_UPDATED 1814 /*! reconciliation: internal page deltas written */ -#define WT_STAT_CONN_REC_PAGE_DELTA_INTERNAL 1814 +#define WT_STAT_CONN_REC_PAGE_DELTA_INTERNAL 1815 /*! reconciliation: internal page multi-block writes */ -#define WT_STAT_CONN_REC_MULTIBLOCK_INTERNAL 1815 +#define WT_STAT_CONN_REC_MULTIBLOCK_INTERNAL 1816 /*! reconciliation: leaf page deltas written */ -#define WT_STAT_CONN_REC_PAGE_DELTA_LEAF 1816 +#define WT_STAT_CONN_REC_PAGE_DELTA_LEAF 1817 /*! reconciliation: leaf page multi-block writes */ -#define WT_STAT_CONN_REC_MULTIBLOCK_LEAF 1817 +#define WT_STAT_CONN_REC_MULTIBLOCK_LEAF 1818 /*! reconciliation: leaf-page overflow keys */ -#define WT_STAT_CONN_REC_OVERFLOW_KEY_LEAF 1818 +#define WT_STAT_CONN_REC_OVERFLOW_KEY_LEAF 1819 /*! reconciliation: max deltas seen on internal page during reconciliation */ -#define WT_STAT_CONN_REC_MAX_INTERNAL_PAGE_DELTAS 1819 +#define WT_STAT_CONN_REC_MAX_INTERNAL_PAGE_DELTAS 1820 /*! reconciliation: max deltas seen on leaf page during reconciliation */ -#define WT_STAT_CONN_REC_MAX_LEAF_PAGE_DELTAS 1820 +#define WT_STAT_CONN_REC_MAX_LEAF_PAGE_DELTAS 1821 /*! reconciliation: maximum milliseconds spent in a reconciliation call */ -#define WT_STAT_CONN_REC_MAXIMUM_MILLISECONDS 1821 +#define WT_STAT_CONN_REC_MAXIMUM_MILLISECONDS 1822 /*! * reconciliation: maximum milliseconds spent in building a disk image in * a reconciliation */ -#define WT_STAT_CONN_REC_MAXIMUM_IMAGE_BUILD_MILLISECONDS 1822 +#define WT_STAT_CONN_REC_MAXIMUM_IMAGE_BUILD_MILLISECONDS 1823 /*! * reconciliation: maximum milliseconds spent in moving updates to the * history store in a reconciliation */ -#define WT_STAT_CONN_REC_MAXIMUM_HS_WRAPUP_MILLISECONDS 1823 +#define WT_STAT_CONN_REC_MAXIMUM_HS_WRAPUP_MILLISECONDS 1824 /*! * reconciliation: number of keys that are garbage collected from the * disk images in the ingest btrees for disaggregated storage */ -#define WT_STAT_CONN_REC_INGEST_GARBAGE_COLLECTION_KEYS_DISK_IMAGE 1824 +#define WT_STAT_CONN_REC_INGEST_GARBAGE_COLLECTION_KEYS_DISK_IMAGE 1825 /*! * reconciliation: number of keys that are garbage collected from the * update chains in the ingest btrees for disaggregated storage */ -#define WT_STAT_CONN_REC_INGEST_GARBAGE_COLLECTION_KEYS_UPDATE_CHAIN 1825 +#define WT_STAT_CONN_REC_INGEST_GARBAGE_COLLECTION_KEYS_UPDATE_CHAIN 1826 /*! reconciliation: overflow values written */ -#define WT_STAT_CONN_REC_OVERFLOW_VALUE 1826 +#define WT_STAT_CONN_REC_OVERFLOW_VALUE 1827 /*! reconciliation: page deltas rejected due to invalid page ID */ -#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_INVALID_PAGE_ID 1827 +#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_INVALID_PAGE_ID 1828 /*! reconciliation: page deltas rejected due to max consecutive limit */ -#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_MAX_CONSECUTIVE_EXCEEDED 1828 +#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_MAX_CONSECUTIVE_EXCEEDED 1829 /*! reconciliation: page deltas rejected due to multiblock reconciliation */ -#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_MULTIBLOCK 1829 +#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_MULTIBLOCK 1830 /*! * reconciliation: page deltas rejected due to non-single page in * previous reconciliation */ -#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_NON_SINGLE_PAGE 1830 +#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_NON_SINGLE_PAGE 1831 /*! reconciliation: page deltas rejected due to size threshold */ -#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_SIZE_THRESHOLD 1831 +#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_SIZE_THRESHOLD 1832 /*! reconciliation: page deltas rejected due to zero entries */ -#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_ZERO_ENTRIES 1832 +#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_ZERO_ENTRIES 1833 /*! * reconciliation: page deltas rejected: build function returned false * (disabled, in-memory split, or internal page constraints not met) */ -#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_BUILD_FAILED 1833 +#define WT_STAT_CONN_REC_PAGE_DELTA_REJECTED_BUILD_FAILED 1834 /*! reconciliation: page reconciliation calls */ -#define WT_STAT_CONN_REC_PAGES 1834 +#define WT_STAT_CONN_REC_PAGES 1835 /*! reconciliation: page reconciliation calls for eviction */ -#define WT_STAT_CONN_REC_PAGES_EVICTION 1835 +#define WT_STAT_CONN_REC_PAGES_EVICTION 1836 /*! reconciliation: page reconciliation calls for pages between 1 and 10MB */ -#define WT_STAT_CONN_REC_PAGES_SIZE_1MB_TO_10MB 1836 +#define WT_STAT_CONN_REC_PAGES_SIZE_1MB_TO_10MB 1837 /*! * reconciliation: page reconciliation calls for pages between 10 and * 100MB */ -#define WT_STAT_CONN_REC_PAGES_SIZE_10MB_TO_100MB 1837 +#define WT_STAT_CONN_REC_PAGES_SIZE_10MB_TO_100MB 1838 /*! * reconciliation: page reconciliation calls for pages between 100MB and * 1GB */ -#define WT_STAT_CONN_REC_PAGES_SIZE_100MB_TO_1GB 1838 +#define WT_STAT_CONN_REC_PAGES_SIZE_100MB_TO_1GB 1839 /*! reconciliation: page reconciliation calls for pages over 1GB */ -#define WT_STAT_CONN_REC_PAGES_SIZE_1GB_PLUS 1839 +#define WT_STAT_CONN_REC_PAGES_SIZE_1GB_PLUS 1840 /*! * reconciliation: page reconciliation calls that resulted in values with * prepared transaction metadata */ -#define WT_STAT_CONN_REC_PAGES_WITH_PREPARE 1840 +#define WT_STAT_CONN_REC_PAGES_WITH_PREPARE 1841 /*! * reconciliation: page reconciliation calls that resulted in values with * timestamps */ -#define WT_STAT_CONN_REC_PAGES_WITH_TS 1841 +#define WT_STAT_CONN_REC_PAGES_WITH_TS 1842 /*! * reconciliation: page reconciliation calls that resulted in values with * transaction ids */ -#define WT_STAT_CONN_REC_PAGES_WITH_TXN 1842 +#define WT_STAT_CONN_REC_PAGES_WITH_TXN 1843 /*! reconciliation: pages deleted */ -#define WT_STAT_CONN_REC_PAGE_DELETE 1843 +#define WT_STAT_CONN_REC_PAGE_DELETE 1844 /*! reconciliation: pages eligible for delta generation */ -#define WT_STAT_CONN_REC_PAGE_DELTA_ELIGIBLE 1844 +#define WT_STAT_CONN_REC_PAGE_DELTA_ELIGIBLE 1845 /*! * reconciliation: pages written including an aggregated newest start * durable timestamp */ -#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_START_DURABLE_TS 1845 +#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_START_DURABLE_TS 1846 /*! * reconciliation: pages written including an aggregated newest stop * durable timestamp */ -#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_DURABLE_TS 1846 +#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_DURABLE_TS 1847 /*! * reconciliation: pages written including an aggregated newest stop * timestamp */ -#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_TS 1847 +#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_TS 1848 /*! * reconciliation: pages written including an aggregated newest stop * transaction ID */ -#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_TXN 1848 +#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_STOP_TXN 1849 /*! * reconciliation: pages written including an aggregated newest * transaction ID */ -#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_TXN 1849 +#define WT_STAT_CONN_REC_TIME_AGGR_NEWEST_TXN 1850 /*! * reconciliation: pages written including an aggregated oldest start * timestamp */ -#define WT_STAT_CONN_REC_TIME_AGGR_OLDEST_START_TS 1850 +#define WT_STAT_CONN_REC_TIME_AGGR_OLDEST_START_TS 1851 /*! reconciliation: pages written including an aggregated prepare */ -#define WT_STAT_CONN_REC_TIME_AGGR_PREPARED 1851 +#define WT_STAT_CONN_REC_TIME_AGGR_PREPARED 1852 /*! reconciliation: pages written including at least one prepare state */ -#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_PREPARED 1852 +#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_PREPARED 1853 /*! * reconciliation: pages written including at least one start durable * timestamp */ -#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_DURABLE_START_TS 1853 +#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_DURABLE_START_TS 1854 /*! reconciliation: pages written including at least one start timestamp */ -#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_START_TS 1854 +#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_START_TS 1855 /*! * reconciliation: pages written including at least one start transaction * ID */ -#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_START_TXN 1855 +#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_START_TXN 1856 /*! * reconciliation: pages written including at least one stop durable * timestamp */ -#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_DURABLE_STOP_TS 1856 +#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_DURABLE_STOP_TS 1857 /*! reconciliation: pages written including at least one stop timestamp */ -#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_STOP_TS 1857 +#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_STOP_TS 1858 /*! * reconciliation: pages written including at least one stop transaction * ID */ -#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_STOP_TXN 1858 +#define WT_STAT_CONN_REC_TIME_WINDOW_PAGES_STOP_TXN 1859 /*! reconciliation: pages written with at least one internal page delta */ -#define WT_STAT_CONN_REC_PAGES_WITH_INTERNAL_DELTAS 1859 +#define WT_STAT_CONN_REC_PAGES_WITH_INTERNAL_DELTAS 1860 /*! reconciliation: pages written with at least one leaf page delta */ -#define WT_STAT_CONN_REC_PAGES_WITH_LEAF_DELTAS 1860 +#define WT_STAT_CONN_REC_PAGES_WITH_LEAF_DELTAS 1861 /*! reconciliation: records written including a prepare state */ -#define WT_STAT_CONN_REC_TIME_WINDOW_PREPARED 1861 +#define WT_STAT_CONN_REC_TIME_WINDOW_PREPARED 1862 /*! reconciliation: records written including a start durable timestamp */ -#define WT_STAT_CONN_REC_TIME_WINDOW_DURABLE_START_TS 1862 +#define WT_STAT_CONN_REC_TIME_WINDOW_DURABLE_START_TS 1863 /*! reconciliation: records written including a start timestamp */ -#define WT_STAT_CONN_REC_TIME_WINDOW_START_TS 1863 +#define WT_STAT_CONN_REC_TIME_WINDOW_START_TS 1864 /*! reconciliation: records written including a start transaction ID */ -#define WT_STAT_CONN_REC_TIME_WINDOW_START_TXN 1864 +#define WT_STAT_CONN_REC_TIME_WINDOW_START_TXN 1865 /*! reconciliation: records written including a stop durable timestamp */ -#define WT_STAT_CONN_REC_TIME_WINDOW_DURABLE_STOP_TS 1865 +#define WT_STAT_CONN_REC_TIME_WINDOW_DURABLE_STOP_TS 1866 /*! reconciliation: records written including a stop timestamp */ -#define WT_STAT_CONN_REC_TIME_WINDOW_STOP_TS 1866 +#define WT_STAT_CONN_REC_TIME_WINDOW_STOP_TS 1867 /*! reconciliation: records written including a stop transaction ID */ -#define WT_STAT_CONN_REC_TIME_WINDOW_STOP_TXN 1867 +#define WT_STAT_CONN_REC_TIME_WINDOW_STOP_TXN 1868 /*! reconciliation: split bytes currently awaiting free */ -#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1868 +#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1869 /*! reconciliation: split objects currently awaiting free */ -#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1869 +#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1870 /*! reconciliation: writes skipped in disaggregated storage */ -#define WT_STAT_CONN_REC_SKIP_WRITE 1870 +#define WT_STAT_CONN_REC_SKIP_WRITE 1871 /*! session: open session count */ -#define WT_STAT_CONN_SESSION_OPEN 1871 +#define WT_STAT_CONN_SESSION_OPEN 1872 /*! session: session query timestamp calls */ -#define WT_STAT_CONN_SESSION_QUERY_TS 1872 +#define WT_STAT_CONN_SESSION_QUERY_TS 1873 /*! session: table alter failed calls */ -#define WT_STAT_CONN_SESSION_TABLE_ALTER_FAIL 1873 +#define WT_STAT_CONN_SESSION_TABLE_ALTER_FAIL 1874 /*! session: table alter successful calls */ -#define WT_STAT_CONN_SESSION_TABLE_ALTER_SUCCESS 1874 +#define WT_STAT_CONN_SESSION_TABLE_ALTER_SUCCESS 1875 /*! session: table alter triggering checkpoint calls */ -#define WT_STAT_CONN_SESSION_TABLE_ALTER_TRIGGER_CHECKPOINT 1875 +#define WT_STAT_CONN_SESSION_TABLE_ALTER_TRIGGER_CHECKPOINT 1876 /*! session: table alter unchanged and skipped */ -#define WT_STAT_CONN_SESSION_TABLE_ALTER_SKIP 1876 +#define WT_STAT_CONN_SESSION_TABLE_ALTER_SKIP 1877 /*! session: table compact conflicted with checkpoint */ -#define WT_STAT_CONN_SESSION_TABLE_COMPACT_CONFLICTING_CHECKPOINT 1877 +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_CONFLICTING_CHECKPOINT 1878 /*! session: table compact dhandle successful calls */ -#define WT_STAT_CONN_SESSION_TABLE_COMPACT_DHANDLE_SUCCESS 1878 +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_DHANDLE_SUCCESS 1879 /*! session: table compact failed calls */ -#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1879 +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1880 /*! session: table compact failed calls due to cache pressure */ -#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL_CACHE_PRESSURE 1880 +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL_CACHE_PRESSURE 1881 /*! * session: table compact in-memory page footprint rewritten by * compaction */ -#define WT_STAT_CONN_SESSION_TABLE_COMPACT_BYTES_REWRITE_INMEM 1881 +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_BYTES_REWRITE_INMEM 1882 /*! session: table compact passes */ -#define WT_STAT_CONN_SESSION_TABLE_COMPACT_PASSES 1882 +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_PASSES 1883 /*! session: table compact pulled into eviction */ -#define WT_STAT_CONN_SESSION_TABLE_COMPACT_EVICTION 1883 +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_EVICTION 1884 /*! session: table compact running */ -#define WT_STAT_CONN_SESSION_TABLE_COMPACT_RUNNING 1884 +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_RUNNING 1885 /*! session: table compact skipped as process would not reduce file size */ -#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SKIPPED 1885 +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SKIPPED 1886 /*! session: table compact successful calls */ -#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1886 +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1887 /*! session: table compact timeout */ -#define WT_STAT_CONN_SESSION_TABLE_COMPACT_TIMEOUT 1887 +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_TIMEOUT 1888 /*! session: table create failed calls */ -#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1888 +#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1889 /*! session: table create successful calls */ -#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1889 +#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1890 /*! session: table create with import failed calls */ -#define WT_STAT_CONN_SESSION_TABLE_CREATE_IMPORT_FAIL 1890 +#define WT_STAT_CONN_SESSION_TABLE_CREATE_IMPORT_FAIL 1891 /*! session: table create with import repair calls */ -#define WT_STAT_CONN_SESSION_TABLE_CREATE_IMPORT_REPAIR 1891 +#define WT_STAT_CONN_SESSION_TABLE_CREATE_IMPORT_REPAIR 1892 /*! session: table create with import successful calls */ -#define WT_STAT_CONN_SESSION_TABLE_CREATE_IMPORT_SUCCESS 1892 +#define WT_STAT_CONN_SESSION_TABLE_CREATE_IMPORT_SUCCESS 1893 /*! session: table drop failed calls */ -#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1893 +#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1894 /*! session: table drop successful calls */ -#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1894 +#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1895 /*! session: table publish failed calls */ -#define WT_STAT_CONN_SESSION_TABLE_PUBLISH_FAIL 1895 +#define WT_STAT_CONN_SESSION_TABLE_PUBLISH_FAIL 1896 /*! session: table publish successful calls */ -#define WT_STAT_CONN_SESSION_TABLE_PUBLISH_SUCCESS 1896 +#define WT_STAT_CONN_SESSION_TABLE_PUBLISH_SUCCESS 1897 /*! session: table salvage failed calls */ -#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1897 +#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1898 /*! session: table salvage successful calls */ -#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1898 +#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1899 /*! session: table truncate failed calls */ -#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1899 +#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1900 /*! session: table truncate successful calls */ -#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1900 +#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1901 /*! session: table verify failed calls */ -#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1901 +#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1902 /*! session: table verify successful calls */ -#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1902 +#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1903 /*! thread-state: active filesystem fsync calls */ -#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1903 +#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1904 /*! thread-state: active filesystem read calls */ -#define WT_STAT_CONN_THREAD_READ_ACTIVE 1904 +#define WT_STAT_CONN_THREAD_READ_ACTIVE 1905 /*! thread-state: active filesystem write calls */ -#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1905 +#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1906 /*! thread-yield: application thread operations waiting for cache */ -#define WT_STAT_CONN_APPLICATION_CACHE_OPS 1906 +#define WT_STAT_CONN_APPLICATION_CACHE_OPS 1907 /*! * thread-yield: application thread operations waiting for interruptible * cache eviction */ -#define WT_STAT_CONN_APPLICATION_CACHE_INTERRUPTIBLE_OPS 1907 +#define WT_STAT_CONN_APPLICATION_CACHE_INTERRUPTIBLE_OPS 1908 /*! * thread-yield: application thread operations waiting for mandatory * cache eviction */ -#define WT_STAT_CONN_APPLICATION_CACHE_UNINTERRUPTIBLE_OPS 1908 +#define WT_STAT_CONN_APPLICATION_CACHE_UNINTERRUPTIBLE_OPS 1909 /*! thread-yield: application thread snapshot refreshed for eviction */ -#define WT_STAT_CONN_APPLICATION_EVICT_SNAPSHOT_REFRESHED 1909 +#define WT_STAT_CONN_APPLICATION_EVICT_SNAPSHOT_REFRESHED 1910 /*! thread-yield: application thread time waiting for cache (usecs) */ -#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1910 +#define WT_STAT_CONN_APPLICATION_CACHE_TIME 1911 /*! * thread-yield: application thread time waiting for interruptible cache * eviction (usecs) */ -#define WT_STAT_CONN_APPLICATION_CACHE_INTERRUPTIBLE_TIME 1911 +#define WT_STAT_CONN_APPLICATION_CACHE_INTERRUPTIBLE_TIME 1912 /*! * thread-yield: application thread time waiting for mandatory cache * eviction (usecs) */ -#define WT_STAT_CONN_APPLICATION_CACHE_UNINTERRUPTIBLE_TIME 1912 +#define WT_STAT_CONN_APPLICATION_CACHE_UNINTERRUPTIBLE_TIME 1913 /*! * thread-yield: connection close blocked waiting for transaction state * stabilization */ -#define WT_STAT_CONN_TXN_RELEASE_BLOCKED 1913 +#define WT_STAT_CONN_TXN_RELEASE_BLOCKED 1914 /*! thread-yield: data handle lock yielded */ -#define WT_STAT_CONN_DHANDLE_LOCK_BLOCKED 1914 +#define WT_STAT_CONN_DHANDLE_LOCK_BLOCKED 1915 /*! * thread-yield: get reference for page index and slot time sleeping * (usecs) */ -#define WT_STAT_CONN_PAGE_INDEX_SLOT_REF_BLOCKED 1915 +#define WT_STAT_CONN_PAGE_INDEX_SLOT_REF_BLOCKED 1916 /*! thread-yield: page access yielded due to prepare state change */ -#define WT_STAT_CONN_PREPARED_TRANSITION_BLOCKED_PAGE 1916 +#define WT_STAT_CONN_PREPARED_TRANSITION_BLOCKED_PAGE 1917 /*! thread-yield: page acquire busy blocked */ -#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1917 +#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1918 /*! thread-yield: page acquire eviction blocked */ -#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1918 +#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1919 /*! thread-yield: page acquire locked blocked */ -#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1919 +#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1920 /*! thread-yield: page acquire read blocked */ -#define WT_STAT_CONN_PAGE_READ_BLOCKED 1920 +#define WT_STAT_CONN_PAGE_READ_BLOCKED 1921 /*! thread-yield: page acquire time sleeping (usecs) */ -#define WT_STAT_CONN_PAGE_SLEEP 1921 +#define WT_STAT_CONN_PAGE_SLEEP 1922 /*! * thread-yield: page delete rollback time sleeping for state change * (usecs) */ -#define WT_STAT_CONN_PAGE_DEL_ROLLBACK_BLOCKED 1922 +#define WT_STAT_CONN_PAGE_DEL_ROLLBACK_BLOCKED 1923 /*! thread-yield: page reconciliation yielded due to child modification */ -#define WT_STAT_CONN_CHILD_MODIFY_BLOCKED_PAGE 1923 +#define WT_STAT_CONN_CHILD_MODIFY_BLOCKED_PAGE 1924 /*! thread-yield: page split and restart read */ -#define WT_STAT_CONN_PAGE_SPLIT_RESTART 1924 +#define WT_STAT_CONN_PAGE_SPLIT_RESTART 1925 /*! thread-yield: pages skipped during read due to deleted state */ -#define WT_STAT_CONN_PAGE_READ_SKIP_DELETED 1925 +#define WT_STAT_CONN_PAGE_READ_SKIP_DELETED 1926 /*! * tiered-storage: attempts to remove a local object and the object is in * use */ -#define WT_STAT_CONN_LOCAL_OBJECTS_INUSE 1926 +#define WT_STAT_CONN_LOCAL_OBJECTS_INUSE 1927 /*! tiered-storage: flush_tier failed calls */ -#define WT_STAT_CONN_FLUSH_TIER_FAIL 1927 +#define WT_STAT_CONN_FLUSH_TIER_FAIL 1928 /*! tiered-storage: flush_tier operation calls */ -#define WT_STAT_CONN_FLUSH_TIER 1928 +#define WT_STAT_CONN_FLUSH_TIER 1929 /*! tiered-storage: flush_tier tables skipped due to no checkpoint */ -#define WT_STAT_CONN_FLUSH_TIER_SKIPPED 1929 +#define WT_STAT_CONN_FLUSH_TIER_SKIPPED 1930 /*! tiered-storage: flush_tier tables switched */ -#define WT_STAT_CONN_FLUSH_TIER_SWITCHED 1930 +#define WT_STAT_CONN_FLUSH_TIER_SWITCHED 1931 /*! tiered-storage: local objects removed */ -#define WT_STAT_CONN_LOCAL_OBJECTS_REMOVED 1931 +#define WT_STAT_CONN_LOCAL_OBJECTS_REMOVED 1932 /*! tiered-storage: tiered operations dequeued and processed */ -#define WT_STAT_CONN_TIERED_WORK_UNITS_DEQUEUED 1932 +#define WT_STAT_CONN_TIERED_WORK_UNITS_DEQUEUED 1933 /*! tiered-storage: tiered operations removed without processing */ -#define WT_STAT_CONN_TIERED_WORK_UNITS_REMOVED 1933 +#define WT_STAT_CONN_TIERED_WORK_UNITS_REMOVED 1934 /*! tiered-storage: tiered operations scheduled */ -#define WT_STAT_CONN_TIERED_WORK_UNITS_CREATED 1934 +#define WT_STAT_CONN_TIERED_WORK_UNITS_CREATED 1935 /*! tiered-storage: tiered storage local retention time (secs) */ -#define WT_STAT_CONN_TIERED_RETENTION 1935 +#define WT_STAT_CONN_TIERED_RETENTION 1936 /*! transaction: Number of prepared updates */ -#define WT_STAT_CONN_TXN_PREPARED_UPDATES 1936 +#define WT_STAT_CONN_TXN_PREPARED_UPDATES 1937 /*! transaction: Number of prepared updates committed */ -#define WT_STAT_CONN_TXN_PREPARED_UPDATES_COMMITTED 1937 +#define WT_STAT_CONN_TXN_PREPARED_UPDATES_COMMITTED 1938 /*! transaction: Number of prepared updates repeated on the same key */ -#define WT_STAT_CONN_TXN_PREPARED_UPDATES_KEY_REPEATED 1938 +#define WT_STAT_CONN_TXN_PREPARED_UPDATES_KEY_REPEATED 1939 /*! transaction: Number of prepared updates rolled back */ -#define WT_STAT_CONN_TXN_PREPARED_UPDATES_ROLLEDBACK 1939 +#define WT_STAT_CONN_TXN_PREPARED_UPDATES_ROLLEDBACK 1940 /*! * transaction: a reader raced with a prepared transaction commit and * skipped an update or updates */ -#define WT_STAT_CONN_TXN_READ_RACE_PREPARE_COMMIT 1940 +#define WT_STAT_CONN_TXN_READ_RACE_PREPARE_COMMIT 1941 /*! transaction: number of times overflow removed value is read */ -#define WT_STAT_CONN_TXN_READ_OVERFLOW_REMOVE 1941 +#define WT_STAT_CONN_TXN_READ_OVERFLOW_REMOVE 1942 /*! transaction: oldest pinned transaction ID rolled back for eviction */ -#define WT_STAT_CONN_TXN_ROLLBACK_OLDEST_PINNED 1942 +#define WT_STAT_CONN_TXN_ROLLBACK_OLDEST_PINNED 1943 /*! transaction: oldest transaction ID rolled back for eviction */ -#define WT_STAT_CONN_TXN_ROLLBACK_OLDEST_ID 1943 +#define WT_STAT_CONN_TXN_ROLLBACK_OLDEST_ID 1944 /*! transaction: prepared transactions */ -#define WT_STAT_CONN_TXN_PREPARE 1944 +#define WT_STAT_CONN_TXN_PREPARE 1945 /*! transaction: prepared transactions committed */ -#define WT_STAT_CONN_TXN_PREPARE_COMMIT 1945 +#define WT_STAT_CONN_TXN_PREPARE_COMMIT 1946 /*! transaction: prepared transactions currently active */ -#define WT_STAT_CONN_TXN_PREPARE_ACTIVE 1946 +#define WT_STAT_CONN_TXN_PREPARE_ACTIVE 1947 /*! transaction: prepared transactions rolled back */ -#define WT_STAT_CONN_TXN_PREPARE_ROLLBACK 1947 +#define WT_STAT_CONN_TXN_PREPARE_ROLLBACK 1948 /*! transaction: query timestamp calls */ -#define WT_STAT_CONN_TXN_QUERY_TS 1948 +#define WT_STAT_CONN_TXN_QUERY_TS 1949 /*! transaction: race to read prepared update retry */ -#define WT_STAT_CONN_TXN_READ_RACE_PREPARE_UPDATE 1949 +#define WT_STAT_CONN_TXN_READ_RACE_PREPARE_UPDATE 1950 /*! transaction: rollback to stable applied btrees */ -#define WT_STAT_CONN_TXN_RTS_BTREES_APPLIED 1950 +#define WT_STAT_CONN_TXN_RTS_BTREES_APPLIED 1951 /*! transaction: rollback to stable calls */ -#define WT_STAT_CONN_TXN_RTS 1951 +#define WT_STAT_CONN_TXN_RTS 1952 /*! * transaction: rollback to stable history store keys that would have * been swept in non-dryrun mode */ -#define WT_STAT_CONN_TXN_RTS_SWEEP_HS_KEYS_DRYRUN 1952 +#define WT_STAT_CONN_TXN_RTS_SWEEP_HS_KEYS_DRYRUN 1953 /*! * transaction: rollback to stable history store records with stop * timestamps older than newer records */ -#define WT_STAT_CONN_TXN_RTS_HS_STOP_OLDER_THAN_NEWER_START 1953 +#define WT_STAT_CONN_TXN_RTS_HS_STOP_OLDER_THAN_NEWER_START 1954 /*! transaction: rollback to stable inconsistent checkpoint */ -#define WT_STAT_CONN_TXN_RTS_INCONSISTENT_CKPT 1954 +#define WT_STAT_CONN_TXN_RTS_INCONSISTENT_CKPT 1955 /*! transaction: rollback to stable keys removed */ -#define WT_STAT_CONN_TXN_RTS_KEYS_REMOVED 1955 +#define WT_STAT_CONN_TXN_RTS_KEYS_REMOVED 1956 /*! transaction: rollback to stable keys restored */ -#define WT_STAT_CONN_TXN_RTS_KEYS_RESTORED 1956 +#define WT_STAT_CONN_TXN_RTS_KEYS_RESTORED 1957 /*! * transaction: rollback to stable keys that would have been removed in * non-dryrun mode */ -#define WT_STAT_CONN_TXN_RTS_KEYS_REMOVED_DRYRUN 1957 +#define WT_STAT_CONN_TXN_RTS_KEYS_REMOVED_DRYRUN 1958 /*! * transaction: rollback to stable keys that would have been restored in * non-dryrun mode */ -#define WT_STAT_CONN_TXN_RTS_KEYS_RESTORED_DRYRUN 1958 +#define WT_STAT_CONN_TXN_RTS_KEYS_RESTORED_DRYRUN 1959 /*! transaction: rollback to stable pages visited */ -#define WT_STAT_CONN_TXN_RTS_PAGES_VISITED 1959 +#define WT_STAT_CONN_TXN_RTS_PAGES_VISITED 1960 /*! transaction: rollback to stable restored tombstones from history store */ -#define WT_STAT_CONN_TXN_RTS_HS_RESTORE_TOMBSTONES 1960 +#define WT_STAT_CONN_TXN_RTS_HS_RESTORE_TOMBSTONES 1961 /*! transaction: rollback to stable restored updates from history store */ -#define WT_STAT_CONN_TXN_RTS_HS_RESTORE_UPDATES 1961 +#define WT_STAT_CONN_TXN_RTS_HS_RESTORE_UPDATES 1962 /*! transaction: rollback to stable skipped btrees */ -#define WT_STAT_CONN_TXN_RTS_BTREES_SKIPPED 1962 +#define WT_STAT_CONN_TXN_RTS_BTREES_SKIPPED 1963 /*! transaction: rollback to stable skipping delete rle */ -#define WT_STAT_CONN_TXN_RTS_DELETE_RLE_SKIPPED 1963 +#define WT_STAT_CONN_TXN_RTS_DELETE_RLE_SKIPPED 1964 /*! transaction: rollback to stable skipping stable rle */ -#define WT_STAT_CONN_TXN_RTS_STABLE_RLE_SKIPPED 1964 +#define WT_STAT_CONN_TXN_RTS_STABLE_RLE_SKIPPED 1965 /*! transaction: rollback to stable sweeping history store keys */ -#define WT_STAT_CONN_TXN_RTS_SWEEP_HS_KEYS 1965 +#define WT_STAT_CONN_TXN_RTS_SWEEP_HS_KEYS 1966 /*! * transaction: rollback to stable tombstones from history store that * would have been restored in non-dryrun mode */ -#define WT_STAT_CONN_TXN_RTS_HS_RESTORE_TOMBSTONES_DRYRUN 1966 +#define WT_STAT_CONN_TXN_RTS_HS_RESTORE_TOMBSTONES_DRYRUN 1967 /*! transaction: rollback to stable tree walk skipping pages */ -#define WT_STAT_CONN_TXN_RTS_TREE_WALK_SKIP_PAGES 1967 +#define WT_STAT_CONN_TXN_RTS_TREE_WALK_SKIP_PAGES 1968 /*! transaction: rollback to stable updates aborted */ -#define WT_STAT_CONN_TXN_RTS_UPD_ABORTED 1968 +#define WT_STAT_CONN_TXN_RTS_UPD_ABORTED 1969 /*! * transaction: rollback to stable updates from history store that would * have been restored in non-dryrun mode */ -#define WT_STAT_CONN_TXN_RTS_HS_RESTORE_UPDATES_DRYRUN 1969 +#define WT_STAT_CONN_TXN_RTS_HS_RESTORE_UPDATES_DRYRUN 1970 /*! transaction: rollback to stable updates removed from history store */ -#define WT_STAT_CONN_TXN_RTS_HS_REMOVED 1970 +#define WT_STAT_CONN_TXN_RTS_HS_REMOVED 1971 /*! * transaction: rollback to stable updates that would have been aborted * in non-dryrun mode */ -#define WT_STAT_CONN_TXN_RTS_UPD_ABORTED_DRYRUN 1971 +#define WT_STAT_CONN_TXN_RTS_UPD_ABORTED_DRYRUN 1972 /*! * transaction: rollback to stable updates that would have been removed * from history store in non-dryrun mode */ -#define WT_STAT_CONN_TXN_RTS_HS_REMOVED_DRYRUN 1972 +#define WT_STAT_CONN_TXN_RTS_HS_REMOVED_DRYRUN 1973 /*! transaction: sessions scanned in each walk of concurrent sessions */ -#define WT_STAT_CONN_TXN_SESSIONS_WALKED 1973 +#define WT_STAT_CONN_TXN_SESSIONS_WALKED 1974 /*! transaction: set timestamp calls */ -#define WT_STAT_CONN_TXN_SET_TS 1974 +#define WT_STAT_CONN_TXN_SET_TS 1975 /*! transaction: set timestamp durable calls */ -#define WT_STAT_CONN_TXN_SET_TS_DURABLE 1975 +#define WT_STAT_CONN_TXN_SET_TS_DURABLE 1976 /*! transaction: set timestamp durable updates */ -#define WT_STAT_CONN_TXN_SET_TS_DURABLE_UPD 1976 +#define WT_STAT_CONN_TXN_SET_TS_DURABLE_UPD 1977 /*! transaction: set timestamp force calls */ -#define WT_STAT_CONN_TXN_SET_TS_FORCE 1977 +#define WT_STAT_CONN_TXN_SET_TS_FORCE 1978 /*! * transaction: set timestamp global oldest timestamp set to be more * recent than the global stable timestamp */ -#define WT_STAT_CONN_TXN_SET_TS_OUT_OF_ORDER 1978 +#define WT_STAT_CONN_TXN_SET_TS_OUT_OF_ORDER 1979 /*! transaction: set timestamp oldest calls */ -#define WT_STAT_CONN_TXN_SET_TS_OLDEST 1979 +#define WT_STAT_CONN_TXN_SET_TS_OLDEST 1980 /*! transaction: set timestamp oldest updates */ -#define WT_STAT_CONN_TXN_SET_TS_OLDEST_UPD 1980 +#define WT_STAT_CONN_TXN_SET_TS_OLDEST_UPD 1981 /*! transaction: set timestamp stable calls */ -#define WT_STAT_CONN_TXN_SET_TS_STABLE 1981 +#define WT_STAT_CONN_TXN_SET_TS_STABLE 1982 /*! transaction: set timestamp stable disaggregated schema epoch calls */ -#define WT_STAT_CONN_TXN_SET_TS_STABLE_DISAGG_EPOCH 1982 +#define WT_STAT_CONN_TXN_SET_TS_STABLE_DISAGG_EPOCH 1983 /*! transaction: set timestamp stable disaggregated schema epoch updates */ -#define WT_STAT_CONN_TXN_SET_TS_STABLE_DISAGG_EPOCH_UPD 1983 +#define WT_STAT_CONN_TXN_SET_TS_STABLE_DISAGG_EPOCH_UPD 1984 /*! transaction: set timestamp stable updates */ -#define WT_STAT_CONN_TXN_SET_TS_STABLE_UPD 1984 +#define WT_STAT_CONN_TXN_SET_TS_STABLE_UPD 1985 /*! transaction: transaction begins */ -#define WT_STAT_CONN_TXN_BEGIN 1985 +#define WT_STAT_CONN_TXN_BEGIN 1986 /*! * transaction: transaction checkpoint history store file duration * (usecs) */ -#define WT_STAT_CONN_TXN_HS_CKPT_DURATION 1986 +#define WT_STAT_CONN_TXN_HS_CKPT_DURATION 1987 /*! transaction: transaction global checkpoint timestamp */ -#define WT_STAT_CONN_TXN_GLOBAL_CHECKPOINT_TIMESTAMP 1987 +#define WT_STAT_CONN_TXN_GLOBAL_CHECKPOINT_TIMESTAMP 1988 /*! transaction: transaction global durable timestamp */ -#define WT_STAT_CONN_TXN_GLOBAL_DURABLE_TIMESTAMP 1988 +#define WT_STAT_CONN_TXN_GLOBAL_DURABLE_TIMESTAMP 1989 /*! transaction: transaction global last running timestamp */ -#define WT_STAT_CONN_TXN_GLOBAL_LAST_RUNNING_TIMESTAMP 1989 +#define WT_STAT_CONN_TXN_GLOBAL_LAST_RUNNING_TIMESTAMP 1990 /*! transaction: transaction global newest timestamp */ -#define WT_STAT_CONN_TXN_GLOBAL_NEWEST_TIMESTAMP 1990 +#define WT_STAT_CONN_TXN_GLOBAL_NEWEST_TIMESTAMP 1991 /*! transaction: transaction global oldest timestamp */ -#define WT_STAT_CONN_TXN_GLOBAL_OLDEST_TIMESTAMP 1991 +#define WT_STAT_CONN_TXN_GLOBAL_OLDEST_TIMESTAMP 1992 /*! transaction: transaction global pinned timestamp */ -#define WT_STAT_CONN_TXN_GLOBAL_PINNED_TIMESTAMP 1992 +#define WT_STAT_CONN_TXN_GLOBAL_PINNED_TIMESTAMP 1993 /*! transaction: transaction global stable timestamp */ -#define WT_STAT_CONN_TXN_GLOBAL_STABLE_TIMESTAMP 1993 +#define WT_STAT_CONN_TXN_GLOBAL_STABLE_TIMESTAMP 1994 /*! transaction: transaction global version cursor timestamp */ -#define WT_STAT_CONN_TXN_GLOBAL_VERSION_CURSOR_TIMESTAMP 1994 +#define WT_STAT_CONN_TXN_GLOBAL_VERSION_CURSOR_TIMESTAMP 1995 /*! * transaction: transaction number of older readers older than oldest * timestamp */ -#define WT_STAT_CONN_TXN_PINNED_READERS 1995 +#define WT_STAT_CONN_TXN_PINNED_READERS 1996 /*! transaction: transaction range of IDs currently pinned */ -#define WT_STAT_CONN_TXN_PINNED_RANGE 1996 +#define WT_STAT_CONN_TXN_PINNED_RANGE 1997 /*! transaction: transaction range of IDs currently pinned by a checkpoint */ -#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1997 +#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1998 /*! transaction: transaction range of timestamps currently pinned */ -#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_LAG 1998 +#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_LAG 1999 /*! transaction: transaction range of timestamps pinned by a checkpoint */ -#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_CHECKPOINT_LAG 1999 +#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_CHECKPOINT_LAG 2000 /*! * transaction: transaction range of timestamps pinned by the oldest * active read timestamp */ -#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_READER_LAG 2000 +#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_READER_LAG 2001 /*! * transaction: transaction range of timestamps pinned by the oldest * timestamp */ -#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_OLDEST 2001 +#define WT_STAT_CONN_TXN_PINNED_TIMESTAMP_OLDEST 2002 /*! transaction: transaction read timestamp of the oldest active reader */ -#define WT_STAT_CONN_TXN_TIMESTAMP_OLDEST_ACTIVE_READ 2002 +#define WT_STAT_CONN_TXN_TIMESTAMP_OLDEST_ACTIVE_READ 2003 /*! transaction: transaction rollback to stable currently running */ -#define WT_STAT_CONN_TXN_ROLLBACK_TO_STABLE_RUNNING 2003 +#define WT_STAT_CONN_TXN_ROLLBACK_TO_STABLE_RUNNING 2004 /*! transaction: transaction walk of concurrent sessions */ -#define WT_STAT_CONN_TXN_WALK_SESSIONS 2004 +#define WT_STAT_CONN_TXN_WALK_SESSIONS 2005 /*! transaction: transactions committed */ -#define WT_STAT_CONN_TXN_COMMIT 2005 +#define WT_STAT_CONN_TXN_COMMIT 2006 /*! transaction: transactions rolled back */ -#define WT_STAT_CONN_TXN_ROLLBACK 2006 +#define WT_STAT_CONN_TXN_ROLLBACK 2007 /*! transaction: update conflicts */ -#define WT_STAT_CONN_TXN_UPDATE_CONFLICT 2007 +#define WT_STAT_CONN_TXN_UPDATE_CONFLICT 2008 /*! * @} diff --git a/src/third_party/wiredtiger/src/include/wt_internal.h b/src/third_party/wiredtiger/src/include/wt_internal.h index 2c466688724..e67764a2af3 100644 --- a/src/third_party/wiredtiger/src/include/wt_internal.h +++ b/src/third_party/wiredtiger/src/include/wt_internal.h @@ -671,6 +671,7 @@ typedef uint64_t wt_timestamp_t; #include "timestamp_inline.h" /* required by btree_inline.h */ #include "cell_inline.h" /* required by btree_inline.h */ #include "mutex_inline.h" /* required by btree_inline.h */ +#include "session_inline.h" /* required by api.h macros */ #include "txn_inline.h" /* required by btree_inline.h */ #include "bitstring_inline.h" diff --git a/src/third_party/wiredtiger/src/os_win/os_thread.c b/src/third_party/wiredtiger/src/os_win/os_thread.c index bb0bedc5352..44d1465e0fd 100644 --- a/src/third_party/wiredtiger/src/os_win/os_thread.c +++ b/src/third_party/wiredtiger/src/os_win/os_thread.c @@ -91,7 +91,7 @@ int __wt_thread_str(char *buf, size_t buflen) { return (__wt_snprintf(buf, buflen, "%" PRIu64 ":%" PRIu64, (uint64_t)GetCurrentProcessId(), - (uint64_t)GetCurrentThreadId)); + (uint64_t)GetCurrentThreadId())); } /* diff --git a/src/third_party/wiredtiger/src/prepared_discover/prepared_discover_walk.c b/src/third_party/wiredtiger/src/prepared_discover/prepared_discover_walk.c index d8111dbd1e3..9fc4f530f6f 100644 --- a/src/third_party/wiredtiger/src/prepared_discover/prepared_discover_walk.c +++ b/src/third_party/wiredtiger/src/prepared_discover/prepared_discover_walk.c @@ -463,6 +463,8 @@ __wt_prepared_discover_filter_apply_handles(WT_SESSION_IMPL *session) const char *checkpoint_name, *uri, *config; bool has_prepare; + checkpoint_name = NULL; + WT_RET(__wt_metadata_cursor(session, &cursor)); while ((ret = cursor->next(cursor)) == 0) { @@ -489,12 +491,14 @@ __wt_prepared_discover_filter_apply_handles(WT_SESSION_IMPL *session) */ WT_ERR(__wt_buf_fmt(session, stable_uri_buf, "%s/%s", uri, checkpoint_name)); uri = stable_uri_buf->data; + __wt_free(session, checkpoint_name); } WT_ERR(__prepared_discover_walk_one_tree(session, uri)); } if (ret == WT_NOTFOUND) ret = 0; err: + __wt_free(session, checkpoint_name); WT_TRET(__wt_metadata_cursor_release(session, &cursor)); __wt_scr_free(session, &stable_uri_buf); return (ret); diff --git a/src/third_party/wiredtiger/src/session/session_api.c b/src/third_party/wiredtiger/src/session/session_api.c index 0500e176e72..ac9914a6335 100644 --- a/src/third_party/wiredtiger/src/session/session_api.c +++ b/src/third_party/wiredtiger/src/session/session_api.c @@ -2636,7 +2636,7 @@ __open_session(WT_CONNECTION_IMPL *conn, WT_EVENT_HANDLER *event_handler, const #ifdef HAVE_UNITTEST_ASSERTS session_ret->unittest_assert_hit = false; - memset(session->unittest_assert_msg, 0, WT_SESSION_UNITTEST_BUF_LEN); + memset(session->unittest_assert_msg, 0, sizeof(session->unittest_assert_msg)); #endif #ifdef HAVE_DIAGNOSTIC diff --git a/src/third_party/wiredtiger/src/support/stat.c b/src/third_party/wiredtiger/src/support/stat.c index 5af3ca1dca7..354d59ef5ef 100644 --- a/src/third_party/wiredtiger/src/support/stat.c +++ b/src/third_party/wiredtiger/src/support/stat.c @@ -2507,6 +2507,7 @@ static const char *const __stats_connection_desc[] = { "live-restore: source read latency histogram (bucket 9) - 1000ms+", "live-restore: source read latency histogram total (msecs)", "live-restore: state", + "load-control: number of read operations rejected due to load control", "load-control: number of write operations rejected due to load control", "load-control: read load at the system level", "load-control: write load at the system level", @@ -3566,6 +3567,7 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats) stats->live_restore_hist_source_read_latency_gt1000 = 0; stats->live_restore_hist_source_read_latency_total_msecs = 0; /* not clearing live_restore_state */ + stats->read_reject_count = 0; stats->write_reject_count = 0; stats->read_load = 0; stats->write_load = 0; @@ -4759,6 +4761,7 @@ __wt_stat_connection_aggregate(WT_CONNECTION_STATS **from, WT_CONNECTION_STATS * to->live_restore_hist_source_read_latency_total_msecs += WT_STAT_CONN_READ(from, live_restore_hist_source_read_latency_total_msecs); to->live_restore_state += WT_STAT_CONN_READ(from, live_restore_state); + to->read_reject_count += WT_STAT_CONN_READ(from, read_reject_count); to->write_reject_count += WT_STAT_CONN_READ(from, write_reject_count); to->read_load += WT_STAT_CONN_READ(from, read_load); to->write_load += WT_STAT_CONN_READ(from, write_load); diff --git a/src/third_party/wiredtiger/test/catch2/misc_tests/test_assertions.cpp b/src/third_party/wiredtiger/test/catch2/misc_tests/test_assertions.cpp index 70dc3c43882..2d4f929891a 100644 --- a/src/third_party/wiredtiger/test/catch2/misc_tests/test_assertions.cpp +++ b/src/third_party/wiredtiger/test/catch2/misc_tests/test_assertions.cpp @@ -46,7 +46,7 @@ check_assertion_fired(WT_SESSION_IMPL *session) if (ret == ASSERT_FIRED) { // Clear the assertion flag and message for the next test step. session->unittest_assert_hit = false; - memset(session->unittest_assert_msg, 0, WT_SESSION_UNITTEST_BUF_LEN); + memset(session->unittest_assert_msg, 0, sizeof(session->unittest_assert_msg)); } return ret; diff --git a/src/third_party/wiredtiger/test/catch2/misc_tests/test_single_thread_check.cpp b/src/third_party/wiredtiger/test/catch2/misc_tests/test_single_thread_check.cpp new file mode 100644 index 00000000000..5e198325ab9 --- /dev/null +++ b/src/third_party/wiredtiger/test/catch2/misc_tests/test_single_thread_check.cpp @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2014-present MongoDB, Inc. + * Copyright (c) 2008-2014 WiredTiger, Inc. + * All rights reserved. + * + * See the file LICENSE for redistribution information. + */ + +#include + +#include "wt_internal.h" +#include "wrappers/mock_session.h" + +/* Tests that __wt_single_thread_check_start assertion failure handles some fields being NULL. */ + +#if defined(HAVE_DIAGNOSTIC) && defined(HAVE_UNITTEST_ASSERTS) + +TEST_CASE( + "Single thread check: concurrent access with NULL fields produces valid assertion message", + "[single_thread_check]") +{ + std::shared_ptr ms = mock_session::build_test_mock_session(); + WT_SESSION_IMPL *session = ms->get_wt_session_impl(); + + session->id = 1; + + /* + * Simulate another thread holding the session lock. Taking it here causes + * __wt_spin_trylock inside check_start to return EBUSY, which fires the assertion. + * Real thread IDs are never 0, so owning_thread (0) != current_tid is guaranteed. + */ + __wt_spin_lock(session, &session->thread_check.lock); + __wt_single_thread_check_start(session); + + REQUIRE(session->unittest_assert_hit); + + uintmax_t current_tid; + __wt_thread_id(¤t_tid); + + /* name, last op, dhandle remain NULL, owning_thread is also 0. */ + std::string expected = std::string("WiredTiger assertion failed: 'ret == 0'. ") + + "Session 1 is accessed concurrently by multiple threads: " + "current thread " + + std::to_string(current_tid) + + ", owning thread 0 (active op: none, last op: none, api depth: 0, dhandle: none)"; + REQUIRE(std::string(session->unittest_assert_msg) == expected); + + __wt_spin_unlock(session, &session->thread_check.lock); +} + +#endif diff --git a/src/third_party/wiredtiger/test/csuite/config/main.c b/src/third_party/wiredtiger/test/csuite/config/main.c index 55e8ff8f172..8b007595625 100644 --- a/src/third_party/wiredtiger/test/csuite/config/main.c +++ b/src/third_party/wiredtiger/test/csuite/config/main.c @@ -78,7 +78,8 @@ typedef struct key_values { */ #define COPY_MESSAGE_CONTENT(dest, src) \ do { \ - char *_dest, *_src, *_trailing; \ + const char *_src; \ + char *_dest, *_trailing; \ \ _src = strchr(src, ':') + 1; \ while (*_src == ' ') \ @@ -310,7 +311,8 @@ static int handle_wiredtiger_message(WT_EVENT_HANDLER *handler, WT_SESSION *session, const char *message) { CUSTOM_EVENT_HANDLER *custom; - char *output, *p; + const char *p; + char *output; (void)session; diff --git a/src/third_party/wiredtiger/test/suite/test_layered_prepare02.py b/src/third_party/wiredtiger/test/suite/test_layered_prepare02.py new file mode 100644 index 00000000000..6ce7b948d1d --- /dev/null +++ b/src/third_party/wiredtiger/test/suite/test_layered_prepare02.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python3 +# +# 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 helper_disagg import disagg_test_class +from wtscenario import make_scenarios + +# test_layered_prepare02.py +# Forward iteration after a search() or search_near() that returns +# WT_PREPARE_CONFLICT must yield correct results on a layered cursor. + +@disagg_test_class +class test_layered_prepare02(wttest.WiredTigerTestCase): + + scenarios = make_scenarios([ + ('search', dict(use_search_near=False)), + ('search_near', dict(use_search_near=True)), + ]) + + conn_base_config = 'precise_checkpoint=true,' + conn_config = conn_base_config + 'disaggregated=(role="leader")' + + def safe_next(self, cursor): + try: + return cursor.next() + except wiredtiger.WiredTigerError as e: + if 'WT_PREPARE_CONFLICT' in str(e): + return wiredtiger.WT_PREPARE_CONFLICT + raise + + def safe_search(self, cursor, key): + cursor.set_key(key) + try: + cursor.search() + return 0 + except wiredtiger.WiredTigerError as e: + if 'WT_PREPARE_CONFLICT' in str(e): + return wiredtiger.WT_PREPARE_CONFLICT + raise + + def safe_search_near(self, cursor, key): + cursor.set_key(key) + try: + cursor.search_near() + return 0 + except wiredtiger.WiredTigerError as e: + if 'WT_PREPARE_CONFLICT' in str(e): + return wiredtiger.WT_PREPARE_CONFLICT + raise + + def conflict_search(self, cursor, key): + if self.use_search_near: + return self.safe_search_near(cursor, key) + return self.safe_search(cursor, key) + + def _setup_follower(self, prepared_key): + ''' + Open a follower with keys '1','2','3' checkpointed as stable and one + prepared ingest update on prepared_key. Return (stable_keys, + conn_follow, prep_session, iter_session, iter_cursor). + ''' + uri = 'table:test_layered_prepare02' + conn_follow = self.wiredtiger_open('follower', self.extensionsConfig() + + ',create,' + self.conn_base_config + 'disaggregated=(role="follower")') + + stable_keys = ['1', '2', '3'] + self.session.create(uri, 'key_format=S,value_format=S,block_manager=disagg,type=layered') + with self.transaction(session=self.session, commit_timestamp=100): + c = self.session.open_cursor(uri) + for k in stable_keys: + c[k] = 'stable_' + k + c.close() + self.conn.set_timestamp(f'stable_timestamp={self.timestamp_str(200)}') + self.session.checkpoint() + self.disagg_advance_checkpoint(conn_follow) + + prep_session = conn_follow.open_session('') + prep_cursor = prep_session.open_cursor(uri) + prep_session.begin_transaction() + prep_cursor[prepared_key] = 'prepared_update' + prep_cursor.close() + prep_session.prepare_transaction( + f'prepare_timestamp={self.timestamp_str(300)}' + + f',prepared_id={self.prepared_id_str(1)}') + + # Reader whose read_timestamp covers the prepare so it sees the conflict. + iter_session = conn_follow.open_session('') + iter_session.begin_transaction(f'read_timestamp={self.timestamp_str(400)}') + iter_cursor = iter_session.open_cursor(uri) + + return stable_keys, conn_follow, prep_session, iter_session, iter_cursor + + def test_next_after_prepare_conflict(self): + # A search that succeeds followed by a search/search_near that returns + # WT_PREPARE_CONFLICT must leave the cursor fully reset so that subsequent + # next() calls iterate all keys from the beginning. + stable_keys, conn_follow, prep_session, iter_session, cursor = \ + self._setup_follower('2') + + # Position cursor at '3', then trigger WT_PREPARE_CONFLICT on '2'. + # The cursor must reset regardless of where it was previously positioned. + self.assertEqual(self.safe_search(cursor, '3'), 0) + self.assertEqual(self.conflict_search(cursor, '2'), wiredtiger.WT_PREPARE_CONFLICT) + + # After rolling back the prepare, iteration must return all stable keys. + prep_session.rollback_transaction() + got = [] + ret = cursor.next() + while ret == 0: + got.append(cursor.get_key()) + ret = cursor.next() + self.assertEqual(ret, wiredtiger.WT_NOTFOUND) + self.assertEqual(got, stable_keys) + + cursor.close() + iter_session.rollback_transaction() + conn_follow.close() + + def test_next_after_conflicting_next_then_search(self): + # A next() that returns WT_PREPARE_CONFLICT followed by a search/search_near + # on the same prepared key must leave the cursor fully reset so that + # subsequent next() calls iterate all keys from the beginning. + stable_keys, conn_follow, prep_session, iter_session, cursor = \ + self._setup_follower('1') + + # next() conflicts on the first key; search/search_near on the same key + # also conflicts. Both must leave the cursor in a clean state. + self.assertEqual(self.safe_next(cursor), wiredtiger.WT_PREPARE_CONFLICT) + self.assertEqual(self.conflict_search(cursor, '1'), wiredtiger.WT_PREPARE_CONFLICT) + + # After rolling back the prepare, iteration must return all stable keys. + prep_session.rollback_transaction() + got = [] + ret = cursor.next() + while ret == 0: + got.append(cursor.get_key()) + ret = cursor.next() + self.assertEqual(ret, wiredtiger.WT_NOTFOUND) + self.assertEqual(got, stable_keys) + + cursor.close() + iter_session.rollback_transaction() + conn_follow.close()