@cryptotaxi247 / netdata-1 / commits / 95a3194fa

PGC wanted size (#19349)

* fix wanted cache size calculation to always have an absolute minimum * add chart for out of memory protection

Costa Tsaousis committed Jan 8, 2025 at 15:08 UTC 95a3194fabe96fc903fa2c3f24ee14bbe03a4f18
2 files changed +47 -13
src/daemon/pulse/pulse-daemon-memory.c
+34 -1
@@ -178,6 +178,39 @@ void pulse_daemon_memory_do(bool extended) {
178
179 // ----------------------------------------------------------------------------------------------------------------
180
181 + OS_SYSTEM_MEMORY sm = os_last_reported_system_memory();
182 + if (sm.ram_total_bytes) {
183 + static RRDSET *st_memory_available = NULL;
184 + static RRDDIM *rd_available = NULL;
185 +
186 + if (unlikely(!st_memory_available)) {
187 + st_memory_available = rrdset_create_localhost(
188 + "netdata",
189 + "out_of_memory_protection",
190 + NULL,
191 + "Memory Usage",
192 + NULL,
193 + "Out of Memory Protection",
194 + "bytes",
195 + "netdata",
196 + "pulse",
197 + 130102,
198 + localhost->rrd_update_every,
199 + RRDSET_TYPE_AREA);
200 +
201 + rd_available = rrddim_add(st_memory_available, "available", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
202 + }
203 +
204 + // the sum of all these needs to be above at the total buffers calculation
205 + rrddim_set_by_pointer(
206 + st_memory_available, rd_available,
207 + (collected_number)sm.ram_available_bytes);
208 +
209 + rrdset_done(st_memory_available);
210 + }
211 +
212 + // ----------------------------------------------------------------------------------------------------------------
213 +
214 if(!extended)
215 return;
216
@@ -211,7 +244,7 @@ void pulse_daemon_memory_do(bool extended) {
244 "bytes",
245 "netdata",
246 "pulse",
214 - 130101,
247 + 130103,
248 localhost->rrd_update_every,
249 RRDSET_TYPE_STACKED);
250
src/database/engine/cache.c
+13 -12
@@ -396,15 +396,10 @@ static inline size_t cache_usage_per1000(PGC *cache, size_t *size_to_evict) {
396 else
397 wanted_cache_size = hot + dirty + index + cache->config.clean_size;
398
399 - // protection against huge queries
400 - // if huge queries are running, or huge amounts need to be saved
401 - // allow the cache to grow more (hot pages in the main cache are also referenced)
402 - if(unlikely(wanted_cache_size < referenced_size + dirty))
403 - wanted_cache_size = referenced_size + dirty;
404 -
405 - // if we don't have enough clean pages, there is no reason to be aggressive or critical
406 - if(wanted_cache_size < (current_cache_size - clean) && current_cache_size > clean)
407 - wanted_cache_size = current_cache_size - clean;
399 + // calculate the absolute minimum we can go
400 + const uint64_t min_cache_size1 = (referenced_size > hot ? referenced_size : hot) + dirty + index;
401 + const uint64_t min_cache_size2 = (current_cache_size > clean) ? current_cache_size - clean : min_cache_size1;
402 + const uint64_t min_cache_size = MAX(min_cache_size1, min_cache_size2);
403
404 if(cache->config.out_of_memory_protection_bytes) {
405 // out of memory protection
@@ -415,10 +410,12 @@ static inline size_t cache_usage_per1000(PGC *cache, size_t *size_to_evict) {
410 const uint64_t min_available = cache->config.out_of_memory_protection_bytes;
411 if (sm.ram_available_bytes < min_available) {
412 // we must shrink
418 - if(current_cache_size > (min_available - sm.ram_available_bytes))
419 - wanted_cache_size = current_cache_size - (min_available - sm.ram_available_bytes);
413 + uint64_t must_lose = min_available - sm.ram_available_bytes;
414 +
415 + if(current_cache_size > must_lose)
416 + wanted_cache_size = current_cache_size - must_lose;
417 else
421 - wanted_cache_size = hot + dirty;
418 + wanted_cache_size = min_cache_size;
419 }
420 else if(cache->config.use_all_ram) {
421 // we can grow
@@ -427,6 +424,10 @@ static inline size_t cache_usage_per1000(PGC *cache, size_t *size_to_evict) {
424 }
425 }
426
427 + // never go below our minimum
428 + if(unlikely(wanted_cache_size < min_cache_size))
429 + wanted_cache_size = min_cache_size;
430 +
431 const size_t per1000 = (size_t)(current_cache_size * 1000ULL / wanted_cache_size);
432 __atomic_store_n(&cache->usage.per1000, per1000, __ATOMIC_RELAXED);
433 __atomic_store_n(&cache->stats.wanted_cache_size, wanted_cache_size, __ATOMIC_RELAXED);