mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-11 21:20:39 +02:00
Merge bitcoin/bitcoin#35200: node: smooth oversized dbcache warnings
d164a04342node: smooth oversized `-dbcache` warnings (Lőrinc) Pull request description: **Problem:** The oversized `-dbcache` warning threshold has a sharp formula cliff when detected RAM crosses the cutoff used by the warning logic. This was reported during review of [#34641](https://github.com/bitcoin/bitcoin/pull/34641#discussion_r2900769756), where an earlier version could jump from the auto default at `4095 MiB` RAM to `75%` of RAM at `4096 MiB`. That made `1 MiB` of extra detected RAM raise the warning threshold from about `511 MiB` to `3072 MiB`. The surviving warning-only code has the same shape at a different boundary. Below `2 GiB` RAM the cap is `DEFAULT_DB_CACHE` (`450 MiB`), but at `2 GiB` it switches to `75%` of total RAM, so a tiny increase in detected RAM can suddenly raise the warning threshold from `450 MiB` to about `1536 MiB`. <img width="1484" height="881" alt="Image" src="https://github.com/user-attachments/assets/b51d5d24-31b8-4a2a-8f70-e7536481f855" /> **Fix:** Base the warning on a reserved non-dbcache memory budget instead: ```math \text{warn if } \mathit{dbcache} > \max\left(\mathit{DEFAULT\_DB\_CACHE}, 0.75 \cdot \max(\text{total RAM} - \mathit{DBCACHE\_WARNING\_RESERVED\_RAM}, 0)\right) ``` `DBCACHE_WARNING_RESERVED_RAM` is `2 GiB`, so the fixed `DEFAULT_DB_CACHE` cap remains the floor below that reserve and the warning threshold grows monotonically above it. This keeps the warning conservative around low-memory boundaries and avoids treating a boundary-crossing `1 MiB` RAM difference as a reason to allow a much larger explicit `-dbcache`. **Quick reference:** | System RAM | Previous warning cap | New warning cap | | ---------- | -------------------- | --------------- | | 1 GiB | 450 MiB | 450 MiB | | 2 GiB | 1536 MiB | 450 MiB | | 3 GiB | 2304 MiB | 768 MiB | | 4 GiB | 3072 MiB | 1536 MiB | | 8 GiB | 6144 MiB | 4608 MiB | | 16 GiB | 12288 MiB | 10752 MiB | | 32 GiB | 24576 MiB | 23040 MiB | On 32-bit builds, effective `-dbcache` values are still capped to `1024 MiB` before the warning check, so thresholds above that cap are not reachable there. ACKs for top commit: optout21: reACKd164a04342sedited: Re-ACKd164a04342w0xlt: reACKd164a04342Tree-SHA512: deb81f0e192261f01dda6f1575a7b2e147f1e07e813d0833c7aeaf6a3fbd7594c0145ec1c98ded74efee9005108d229942949279c9458cbec4046913387db845
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
#include <kernel/caches.h>
|
||||
#include <util/byte_units.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -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<uint64_t>(DEFAULT_DB_CACHE, (available_ram / 4) * 3)};
|
||||
return dbcache > cap;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,36 +7,34 @@
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user