@cryptotaxi247 / netdata-1 / commits / 936832d57

Handle journal_v2 file creation failure due to OOM (#19965)

Stelios Fragkakis committed Apr 3, 2025 at 11:08 UTC 936832d5777e4b8c24c24d2987493929b88918aa
4 files changed +18 -12
src/database/engine/cache.c
+7 -5
@@ -2552,7 +2552,7 @@ void pgc_open_cache_to_journal_v2(PGC *cache, Word_t section, unsigned datafile_
2552 pgc_queue_unlock(cache, &cache->hot);
2553
2554 // callback
2555 - cb(section, datafile_fileno, type, JudyL_metrics, JudyL_extents_pos, count_of_unique_extents, count_of_unique_metrics, count_of_unique_pages, data);
2555 + bool success = cb(section, datafile_fileno, type, JudyL_metrics, JudyL_extents_pos, count_of_unique_extents, count_of_unique_metrics, count_of_unique_pages, data);
2556
2557 {
2558 Pvoid_t *PValue1;
@@ -2567,12 +2567,14 @@ void pgc_open_cache_to_journal_v2(PGC *cache, Word_t section, unsigned datafile_
2567 while ((PValue2 = JudyLFirstThenNext(mi->JudyL_pages_by_start_time, &start_time, &start_time_first))) {
2568 struct jv2_page_info *pi = *PValue2;
2569
2570 - // balance-parents: transition from hot to clean directly
2570 yield_the_processor(); // do not lock too aggressively
2572 - page_set_clean(cache, pi->page, true, false, PGC_QUEUE_LOCK_PRIO_LOW);
2573 - page_transition_unlock(cache, pi->page);
2574 - page_release(cache, pi->page, true);
2571 + if (likely(success))
2572 + page_set_clean(cache, pi->page, true, false, PGC_QUEUE_LOCK_PRIO_LOW);
2573 + else
2574 + page_flag_clear(pi->page, PGC_PAGE_IS_BEING_MIGRATED_TO_V2);
2575
2576 + page_transition_unlock(cache, pi->page);
2577 + page_release(cache, pi->page, success);
2578 // before balance-parents:
2579 // page_transition_unlock(cache, pi->page);
2580 // pgc_page_hot_to_dirty_and_release(cache, pi->page, true);
src/database/engine/cache.h
+1 -1
@@ -227,7 +227,7 @@ int64_t pgc_get_wanted_cache_size(PGC *cache);
227 void pgc_page_hot_set_end_time_s(PGC *cache, PGC_PAGE *page, time_t end_time_s, size_t additional_bytes);
228 bool pgc_page_to_clean_evict_or_release(PGC *cache, PGC_PAGE *page);
229
230 -typedef void (*migrate_to_v2_callback)(Word_t section, unsigned datafile_fileno, uint8_t type, Pvoid_t JudyL_metrics, Pvoid_t JudyL_extents_pos, size_t count_of_unique_extents, size_t count_of_unique_metrics, size_t count_of_unique_pages, void *data);
230 +typedef bool (*migrate_to_v2_callback)(Word_t section, unsigned datafile_fileno, uint8_t type, Pvoid_t JudyL_metrics, Pvoid_t JudyL_extents_pos, size_t count_of_unique_extents, size_t count_of_unique_metrics, size_t count_of_unique_pages, void *data);
231 void pgc_open_cache_to_journal_v2(PGC *cache, Word_t section, unsigned datafile_fileno, uint8_t type, migrate_to_v2_callback cb, void *data);
232 void pgc_open_evict_clean_pages_of_datafile(PGC *cache, struct rrdengine_datafile *datafile);
233 size_t pgc_count_clean_pages_having_data_ptr(PGC *cache, Word_t section, void *ptr);
src/database/engine/journalfile.c
+9 -5
@@ -1293,7 +1293,7 @@ static void *journalfile_v2_write_descriptors(struct journal_v2_header *j2_heade
1293 // startup : if the migration is done during agent startup
1294 // this will allow us to optimize certain things
1295
1296 -void journalfile_migrate_to_v2_callback(Word_t section, unsigned datafile_fileno __maybe_unused, uint8_t type __maybe_unused,
1296 +bool journalfile_migrate_to_v2_callback(Word_t section, unsigned datafile_fileno __maybe_unused, uint8_t type __maybe_unused,
1297 Pvoid_t JudyL_metrics, Pvoid_t JudyL_extents_pos,
1298 size_t number_of_extents, size_t number_of_metrics, size_t number_of_pages, void *user_data)
1299 {
@@ -1346,8 +1346,10 @@ void journalfile_migrate_to_v2_callback(Word_t section, unsigned datafile_fileno
1346
1347 int fd_v2;
1348 uint8_t *data_start = nd_mmap_advanced(path, total_file_size, MAP_SHARED, 0, false, true, &fd_v2);
1349 - if(!data_start)
1350 - out_of_memory(__FUNCTION__, total_file_size, path);
1349 + if(!data_start) {
1350 + nd_log_daemon(NDLP_WARNING, "DBENGINE: Failed to allocate %"PRIu64" bytes of memory for journal file '%s'. Will retry later", total_file_size, path);
1351 + return false;
1352 + }
1353
1354 memset(data_start, 0, extent_offset);
1355
@@ -1492,7 +1494,7 @@ void journalfile_migrate_to_v2_callback(Word_t section, unsigned datafile_fileno
1494 internal_error(true, "DBENGINE: ACTIVATING NEW INDEX JNL %llu", (now_monotonic_usec() - start_loading) / USEC_PER_MS);
1495 ctx_current_disk_space_increase(ctx, total_file_size);
1496 freez(uuid_list);
1495 - return;
1497 + return true;
1498 }
1499 else {
1500 netdata_log_info("DBENGINE: failed to build index '%s', file will be skipped", path);
@@ -1506,7 +1508,7 @@ void journalfile_migrate_to_v2_callback(Word_t section, unsigned datafile_fileno
1508 freez(uuid_list);
1509
1510 if (likely(resize_file_to == total_file_size))
1509 - return;
1511 + return true;
1512
1513 int ret = truncate(path, (long) resize_file_to);
1514 if (ret < 0) {
@@ -1516,6 +1518,8 @@ void journalfile_migrate_to_v2_callback(Word_t section, unsigned datafile_fileno
1518 }
1519 else
1520 ctx_current_disk_space_increase(ctx, resize_file_to);
1521 +
1522 + return true;
1523 }
1524
1525 int journalfile_load(struct rrdengine_instance *ctx, struct rrdengine_journalfile *journalfile,
src/database/engine/journalfile.h
+1 -1
@@ -264,7 +264,7 @@ int journalfile_load(struct rrdengine_instance *ctx, struct rrdengine_journalfil
264 struct rrdengine_datafile *datafile);
265 void journalfile_v2_populate_retention_to_mrg(struct rrdengine_instance *ctx, struct rrdengine_journalfile *journalfile);
266
267 -void journalfile_migrate_to_v2_callback(Word_t section, unsigned datafile_fileno __maybe_unused, uint8_t type __maybe_unused,
267 +bool journalfile_migrate_to_v2_callback(Word_t section, unsigned datafile_fileno __maybe_unused, uint8_t type __maybe_unused,
268 Pvoid_t JudyL_metrics, Pvoid_t JudyL_extents_pos,
269 size_t number_of_extents, size_t number_of_metrics, size_t number_of_pages, void *user_data);
270