From d164a043426e395a0b11feea2094c5f00c528202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Thu, 30 Apr 2026 14:36:53 +0200 Subject: [PATCH] node: smooth oversized `-dbcache` warnings The oversized `-dbcache` warning currently switches from a fixed `450 MiB` threshold below `2 GiB` of RAM to `75%` of total RAM at `2 GiB`. This creates a cliff where a small increase in RAM can raise the warning threshold to about `1536 MiB`. Apply the `75%` factor only to RAM above a `2 GiB` reserve while keeping `DEFAULT_DB_CACHE` as the minimum threshold. This removes the cliff: the threshold stays at the default until the percentage term exceeds it, then grows by `0.75 MiB` per additional MiB of RAM. This also aligns better with the recently merged parallel input prevout fetcher which performs better with slightly lower dbcache memory. Co-authored-by: Bortlesboat --- src/node/caches.h | 6 +++++- src/test/caches_tests.cpp | 40 +++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/node/caches.h b/src/node/caches.h index 4c66d39afac..4fd14ed9d0c 100644 --- a/src/node/caches.h +++ b/src/node/caches.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -17,6 +18,8 @@ class ArgsManager; static constexpr uint64_t MIN_DB_CACHE{4_MiB}; //! -dbcache default (bytes) static constexpr uint64_t DEFAULT_DB_CACHE{DEFAULT_KERNEL_CACHE}; +//! Reserved non-dbcache memory usage. +static constexpr uint64_t DBCACHE_WARNING_RESERVED_RAM{2_GiB}; namespace node { uint64_t GetDefaultDBCache(); @@ -32,7 +35,8 @@ struct CacheSizes { CacheSizes CalculateCacheSizes(const ArgsManager& args, size_t n_indexes = 0); constexpr bool ShouldWarnOversizedDbCache(uint64_t dbcache, uint64_t total_ram) noexcept { - const uint64_t cap{(total_ram < 2_GiB) ? DEFAULT_DB_CACHE : (total_ram / 100) * 75}; + const uint64_t available_ram{total_ram > DBCACHE_WARNING_RESERVED_RAM ? total_ram - DBCACHE_WARNING_RESERVED_RAM : 0}; + const uint64_t cap{std::max(DEFAULT_DB_CACHE, (available_ram / 4) * 3)}; return dbcache > cap; } diff --git a/src/test/caches_tests.cpp b/src/test/caches_tests.cpp index 69c42f0bbf1..c96bef7e254 100644 --- a/src/test/caches_tests.cpp +++ b/src/test/caches_tests.cpp @@ -7,36 +7,34 @@ #include +#include + using namespace node; +namespace { +void CheckDbCacheWarnThreshold(uint64_t threshold, uint64_t total_ram) +{ + BOOST_CHECK(!ShouldWarnOversizedDbCache(threshold, total_ram)); + BOOST_CHECK( ShouldWarnOversizedDbCache(threshold + 1, total_ram)); +} +} // namespace + BOOST_AUTO_TEST_SUITE(caches_tests) BOOST_AUTO_TEST_CASE(oversized_dbcache_warning) { - // memory restricted setup - cap is DEFAULT_DB_CACHE (450 MiB) - BOOST_CHECK(!ShouldWarnOversizedDbCache(/*dbcache=*/4_MiB, /*total_ram=*/1_GiB)); // Under cap - BOOST_CHECK( ShouldWarnOversizedDbCache(/*dbcache=*/512_MiB, /*total_ram=*/1_GiB)); // At cap - BOOST_CHECK( ShouldWarnOversizedDbCache(/*dbcache=*/1500_MiB, /*total_ram=*/1_GiB)); // Over cap + BOOST_CHECK(!ShouldWarnOversizedDbCache(MIN_DB_CACHE, 1_GiB)); - // 2 GiB RAM - cap is 75% - BOOST_CHECK(!ShouldWarnOversizedDbCache(/*dbcache=*/1500_MiB, /*total_ram=*/2_GiB)); // Under cap - BOOST_CHECK( ShouldWarnOversizedDbCache(/*dbcache=*/1600_MiB, /*total_ram=*/2_GiB)); // Over cap + // Below DBCACHE_WARNING_RESERVED_RAM the existing fixed default dominates. + CheckDbCacheWarnThreshold(DEFAULT_DB_CACHE, 1_GiB); + CheckDbCacheWarnThreshold(DEFAULT_DB_CACHE, DBCACHE_WARNING_RESERVED_RAM); - // 4 GiB RAM - cap is 75% - BOOST_CHECK(!ShouldWarnOversizedDbCache(/*dbcache=*/2500_MiB, /*total_ram=*/4_GiB)); // Under cap - BOOST_CHECK( ShouldWarnOversizedDbCache(/*dbcache=*/3500_MiB, /*total_ram=*/4_GiB)); // Over cap + // Above DBCACHE_WARNING_RESERVED_RAM the warning fires at 75% of the headroom. + CheckDbCacheWarnThreshold(((3_GiB - DBCACHE_WARNING_RESERVED_RAM) / 4) * 3, 3_GiB); - // 8 GiB RAM - cap is 75% - BOOST_CHECK(!ShouldWarnOversizedDbCache(/*dbcache=*/6000_MiB, /*total_ram=*/8_GiB)); // Under cap - BOOST_CHECK( ShouldWarnOversizedDbCache(/*dbcache=*/7000_MiB, /*total_ram=*/8_GiB)); // Over cap - - // 16 GiB RAM - cap is 75% - BOOST_CHECK(!ShouldWarnOversizedDbCache(/*dbcache=*/10_GiB, /*total_ram=*/16_GiB)); // Under cap - BOOST_CHECK( ShouldWarnOversizedDbCache(/*dbcache=*/15_GiB, /*total_ram=*/16_GiB)); // Over cap - - // 32 GiB RAM - cap is 75% - BOOST_CHECK(!ShouldWarnOversizedDbCache(/*dbcache=*/20_GiB, /*total_ram=*/32_GiB)); // Under cap - BOOST_CHECK( ShouldWarnOversizedDbCache(/*dbcache=*/30_GiB, /*total_ram=*/32_GiB)); // Over cap + for (const auto total_ram : {8_GiB, 16_GiB, 32_GiB}) { + CheckDbCacheWarnThreshold(((total_ram - DBCACHE_WARNING_RESERVED_RAM) / 4) * 3, total_ram); + } } BOOST_AUTO_TEST_SUITE_END()