@cryptotaxi247 / netdata-1 / commits / 20bd48e48

Fix datafile creation race condition (#20662)

Fix datafile creation lock

Stelios Fragkakis committed Jul 13, 2025 at 17:25 UTC 20bd48e4878832f35cb7b1a105af539d398adf8d
3 files changed +11 -16
src/database/engine/datafile.c
+8 -13
@@ -1,20 +1,15 @@
1 // SPDX-License-Identifier: GPL-3.0-or-later
2 #include "rrdengine.h"
3
4 -void datafile_list_insert(struct rrdengine_instance *ctx, struct rrdengine_datafile *datafile, bool having_lock)
4 +void datafile_list_insert(struct rrdengine_instance *ctx, struct rrdengine_datafile *datafile)
5 {
6 - if(!having_lock)
7 - uv_rwlock_wrlock(&ctx->datafiles.rwlock);
8 -
6 + uv_rwlock_wrlock(&ctx->datafiles.rwlock);
7 Pvoid_t *Pvalue = JudyLIns(&ctx->datafiles.JudyL, (Word_t ) datafile->fileno, PJE0);
8 if(!Pvalue || Pvalue == PJERR)
9 fatal("DBENGINE: cannot insert datafile %u of tier %d into the datafiles list",
10 datafile->fileno, ctx->config.tier);
13 -
11 *Pvalue = datafile;
15 -
16 - if(!having_lock)
17 - uv_rwlock_wrunlock(&ctx->datafiles.rwlock);
12 + uv_rwlock_wrunlock(&ctx->datafiles.rwlock);
13 }
14
15 void datafile_list_delete_unsafe(struct rrdengine_instance *ctx, struct rrdengine_datafile *datafile)
@@ -515,7 +510,7 @@ static int scan_data_files(struct rrdengine_instance *ctx)
510 }
511
512 ctx_current_disk_space_increase(ctx, datafile->pos + journalfile->unsafe.pos);
518 - datafile_list_insert(ctx, datafile, false);
513 + datafile_list_insert(ctx, datafile);
514 }
515
516 matched_files -= failed_to_load;
@@ -525,7 +520,7 @@ static int scan_data_files(struct rrdengine_instance *ctx)
520 }
521
522 /* Creates a datafile and a journalfile pair */
528 -int create_new_datafile_pair(struct rrdengine_instance *ctx, bool having_lock)
523 +int create_new_datafile_pair(struct rrdengine_instance *ctx)
524 {
525 __atomic_add_fetch(&rrdeng_cache_efficiency_stats.datafile_creation_started, 1, __ATOMIC_RELAXED);
526
@@ -556,7 +551,7 @@ int create_new_datafile_pair(struct rrdengine_instance *ctx, bool having_lock)
551 nd_log(NDLS_DAEMON, NDLP_INFO, "DBENGINE: created journal file \"%s\".", path);
552
553 ctx_current_disk_space_increase(ctx, datafile->pos + journalfile->unsafe.pos);
559 - datafile_list_insert(ctx, datafile, having_lock);
554 + datafile_list_insert(ctx, datafile);
555 ctx_last_fileno_increment(ctx);
556
557 return 0;
@@ -584,7 +579,7 @@ int init_data_files(struct rrdengine_instance *ctx)
579 } else if (0 == ret) {
580 netdata_log_info("DBENGINE: data files not found, creating in path \"%s\".", ctx->config.dbfiles_path);
581 ctx->atomic.last_fileno = 0;
587 - ret = create_new_datafile_pair(ctx, false);
582 + ret = create_new_datafile_pair(ctx);
583 if (ret) {
584 netdata_log_error("DBENGINE: failed to create data and journal files in path \"%s\".", ctx->config.dbfiles_path);
585 return ret;
@@ -592,7 +587,7 @@ int init_data_files(struct rrdengine_instance *ctx)
587 }
588 else {
589 if (ctx->loading.create_new_datafile_pair)
595 - create_new_datafile_pair(ctx, false);
590 + create_new_datafile_pair(ctx);
591
592 while(rrdeng_ctx_tier_cap_exceeded(ctx)) {
593 Word_t Index = 0;
src/database/engine/datafile.h
+2 -2
@@ -92,14 +92,14 @@ void datafile_release_with_trace(struct rrdengine_datafile *df, DATAFILE_ACQUIRE
92 #define datafile_release(df, reason) datafile_release_with_trace(df, reason, __FUNCTION__)
93 bool datafile_acquire_for_deletion(struct rrdengine_datafile *df, bool is_shutdown);
94
95 -void datafile_list_insert(struct rrdengine_instance *ctx, struct rrdengine_datafile *datafile, bool having_lock);
95 +void datafile_list_insert(struct rrdengine_instance *ctx, struct rrdengine_datafile *datafile);
96 void datafile_list_delete_unsafe(struct rrdengine_instance *ctx, struct rrdengine_datafile *datafile);
97 void generate_datafilepath(struct rrdengine_datafile *datafile, char *str, size_t maxlen);
98 int close_data_file(struct rrdengine_datafile *datafile);
99 int unlink_data_file(struct rrdengine_datafile *datafile);
100 int destroy_data_file_unsafe(struct rrdengine_datafile *datafile);
101 int create_data_file(struct rrdengine_datafile *datafile);
102 -int create_new_datafile_pair(struct rrdengine_instance *ctx, bool having_lock);
102 +int create_new_datafile_pair(struct rrdengine_instance *ctx);
103 int init_data_files(struct rrdengine_instance *ctx);
104 void finalize_data_files(struct rrdengine_instance *ctx);
105 void cleanup_datafile_epdl_structures(struct rrdengine_datafile *datafile);
src/database/engine/rrdengine.c
+1 -1
@@ -798,7 +798,7 @@ static struct rrdengine_datafile *get_datafile_to_write_extent(struct rrdengine_
798 // take the latest datafile again - without this, multiple threads may create multiple files
799 datafile = get_last_ctx_datafile(ctx, false);
800
801 - if(datafile_is_full(ctx, datafile) && create_new_datafile_pair(ctx, true) == 0)
801 + if(datafile_is_full(ctx, datafile) && create_new_datafile_pair(ctx) == 0)
802 __atomic_store_n(&ctx->atomic.needs_indexing, true, __ATOMIC_RELAXED);
803
804 netdata_mutex_unlock(&mutex);