@cryptotaxi247 / netdata-1 / commits / 3240d07c4

dbengine: cache bug-fix when under pressure (#17231)

when a page cannot be acquired, repeat the call until it can or does not exist

Costa Tsaousis committed Mar 23, 2024 at 11:06 UTC 3240d07c435864a33bef93e5a1c3971c5398c6d1
1 file changed +43 -26
src/database/engine/cache.c
+43 -26
@@ -1325,21 +1325,8 @@ static PGC_PAGE *page_add(PGC *cache, PGC_ENTRY *entry, bool *added) {
1325 return page;
1326 }
1327
1328 -static PGC_PAGE *page_find_and_acquire(PGC *cache, Word_t section, Word_t metric_id, time_t start_time_s, PGC_SEARCH method) {
1329 - __atomic_add_fetch(&cache->stats.workers_search, 1, __ATOMIC_RELAXED);
1330 -
1331 - size_t *stats_hit_ptr, *stats_miss_ptr;
1332 -
1333 - if(method == PGC_SEARCH_CLOSEST) {
1334 - __atomic_add_fetch(&cache->stats.searches_closest, 1, __ATOMIC_RELAXED);
1335 - stats_hit_ptr = &cache->stats.searches_closest_hits;
1336 - stats_miss_ptr = &cache->stats.searches_closest_misses;
1337 - }
1338 - else {
1339 - __atomic_add_fetch(&cache->stats.searches_exact, 1, __ATOMIC_RELAXED);
1340 - stats_hit_ptr = &cache->stats.searches_exact_hits;
1341 - stats_miss_ptr = &cache->stats.searches_exact_misses;
1342 - }
1328 +static PGC_PAGE *page_find_and_acquire_once(PGC *cache, Word_t section, Word_t metric_id, time_t start_time_s, PGC_SEARCH method, bool *retry) {
1329 + *retry = false;
1330
1331 PGC_PAGE *page = NULL;
1332 size_t partition = pgc_indexing_partition(cache, metric_id);
@@ -1462,22 +1449,13 @@ static PGC_PAGE *page_find_and_acquire(PGC *cache, Word_t section, Word_t metric
1449
1450 if(!page_acquire(cache, page)) {
1451 // this page is not good to use
1452 + *retry = true;
1453 page = NULL;
1454 }
1455 }
1456
1457 cleanup:
1458 pgc_index_read_unlock(cache, partition);
1471 -
1472 - if(page) {
1473 - __atomic_add_fetch(stats_hit_ptr, 1, __ATOMIC_RELAXED);
1474 - page_has_been_accessed(cache, page);
1475 - }
1476 - else
1477 - __atomic_add_fetch(stats_miss_ptr, 1, __ATOMIC_RELAXED);
1478 -
1479 - __atomic_sub_fetch(&cache->stats.workers_search, 1, __ATOMIC_RELAXED);
1480 -
1459 return page;
1460 }
1461
@@ -2048,7 +2026,46 @@ void pgc_page_hot_set_end_time_s(PGC *cache __maybe_unused, PGC_PAGE *page, time
2026 }
2027
2028 PGC_PAGE *pgc_page_get_and_acquire(PGC *cache, Word_t section, Word_t metric_id, time_t start_time_s, PGC_SEARCH method) {
2051 - return page_find_and_acquire(cache, section, metric_id, start_time_s, method);
2029 + static const struct timespec ns = { .tv_sec = 0, .tv_nsec = 1 };
2030 +
2031 + PGC_PAGE *page = NULL;
2032 +
2033 + __atomic_add_fetch(&cache->stats.workers_search, 1, __ATOMIC_RELAXED);
2034 +
2035 + size_t *stats_hit_ptr, *stats_miss_ptr;
2036 +
2037 + if(method == PGC_SEARCH_CLOSEST) {
2038 + __atomic_add_fetch(&cache->stats.searches_closest, 1, __ATOMIC_RELAXED);
2039 + stats_hit_ptr = &cache->stats.searches_closest_hits;
2040 + stats_miss_ptr = &cache->stats.searches_closest_misses;
2041 + }
2042 + else {
2043 + __atomic_add_fetch(&cache->stats.searches_exact, 1, __ATOMIC_RELAXED);
2044 + stats_hit_ptr = &cache->stats.searches_exact_hits;
2045 + stats_miss_ptr = &cache->stats.searches_exact_misses;
2046 + }
2047 +
2048 + while(1) {
2049 + bool retry = false;
2050 +
2051 + page = page_find_and_acquire_once(cache, section, metric_id, start_time_s, method, &retry);
2052 +
2053 + if(page || !retry)
2054 + break;
2055 +
2056 + nanosleep(&ns, NULL);
2057 + }
2058 +
2059 + if(page) {
2060 + __atomic_add_fetch(stats_hit_ptr, 1, __ATOMIC_RELAXED);
2061 + page_has_been_accessed(cache, page);
2062 + }
2063 + else
2064 + __atomic_add_fetch(stats_miss_ptr, 1, __ATOMIC_RELAXED);
2065 +
2066 + __atomic_sub_fetch(&cache->stats.workers_search, 1, __ATOMIC_RELAXED);
2067 +
2068 + return page;
2069 }
2070
2071 struct pgc_statistics pgc_get_statistics(PGC *cache) {