@cryptotaxi247 / netdata-1 / commits / 7ccb6d56b

Adjust tier retention calculation (#21280)

Stelios Fragkakis committed Nov 11, 2025 at 00:19 UTC 7ccb6d56bda2e280a5368ebd9980adc160e7a64c
1 file changed +35 -38
src/database/engine/rrdengine.c
+35 -38
@@ -692,9 +692,13 @@ extent_flush_to_open(struct rrdengine_instance *ctx, struct extent_io_descriptor
692
693 bool still_running = ctx_is_available_for_queries(ctx);
694
695 + usec_t max_end_time_ut = 0;
696 for (i = 0 ; i < xt_io_descr->descr_count ; ++i) {
697 descr = xt_io_descr->descr_array[i];
698
699 + if (descr->end_time_ut > max_end_time_ut)
700 + max_end_time_ut = descr->end_time_ut;
701 +
702 if (likely(still_running && !have_error))
703 pgc_open_add_hot_page(
704 (Word_t)ctx,
@@ -709,6 +713,18 @@ extent_flush_to_open(struct rrdengine_instance *ctx, struct extent_io_descriptor
713 page_descriptor_release(descr);
714 }
715
716 + if (!have_error) {
717 + if (max_end_time_ut > 0) {
718 + time_t new_last_time_s = (time_t)(max_end_time_ut / USEC_PER_SEC);
719 +
720 + // Atomically update to keep the maximum
721 + spinlock_lock(&datafile->journalfile->data_spinlock);
722 + if (new_last_time_s > datafile->journalfile->v2.last_time_s)
723 + datafile->journalfile->v2.last_time_s = new_last_time_s;
724 + spinlock_unlock(&datafile->journalfile->data_spinlock);
725 + }
726 + }
727 +
728 posix_memalign_freez(xt_io_descr->buf);
729 extent_io_descriptor_release(xt_io_descr);
730
@@ -1792,23 +1808,6 @@ uint64_t rrdeng_target_data_file_size(struct rrdengine_instance *ctx) {
1808 return target_size;
1809 }
1810
1795 -time_t get_datafile_end_time(struct rrdengine_instance *ctx)
1796 -{
1797 - time_t last_time_s = 0;
1798 -
1799 - netdata_rwlock_rdlock(&ctx->datafiles.rwlock);
1800 - struct rrdengine_datafile *datafile = get_last_ctx_datafile(ctx, true);
1801 -
1802 - if (datafile) {
1803 - last_time_s = datafile->journalfile->v2.last_time_s;
1804 - if (!last_time_s)
1805 - last_time_s = datafile->journalfile->v2.first_time_s;
1806 - }
1807 -
1808 - netdata_rwlock_rdunlock(&ctx->datafiles.rwlock);
1809 - return last_time_s;
1810 -}
1811 -
1811 /* return 0 on success */
1812 int init_rrd_files(struct rrdengine_instance *ctx)
1813 {
@@ -2079,23 +2078,12 @@ uint64_t rrdeng_get_used_disk_space(struct rrdengine_instance *ctx, bool having_
2078 return estimated_disk_space;
2079 }
2080
2082 -static time_t get_tier_retention(struct rrdengine_instance *ctx)
2083 -{
2084 - time_t retention = 0;
2085 - if (localhost) {
2086 - STORAGE_ENGINE *eng = localhost->db[ctx->config.tier].eng;
2087 - if (eng) {
2088 - time_t first_time_s = get_datafile_end_time(ctx);
2089 - if (first_time_s)
2090 - retention = now_realtime_sec() - first_time_s;
2091 - }
2092 - }
2093 - return retention;
2094 -}
2095 -
2081 // Check if disk or retention time cap reached
2082 bool rrdeng_ctx_tier_cap_exceeded(struct rrdengine_instance *ctx)
2083 {
2084 + bool trigger_time_retention = false;
2085 + uint64_t estimated_disk_space = 0;
2086 +
2087 netdata_rwlock_rdlock(&ctx->datafiles.rwlock);
2088 struct rrdengine_datafile *first_datafile = get_first_ctx_datafile(ctx, true);
2089
@@ -2104,16 +2092,25 @@ bool rrdeng_ctx_tier_cap_exceeded(struct rrdengine_instance *ctx)
2092 return false;
2093 }
2094
2107 - uint64_t estimated_disk_space = rrdeng_get_used_disk_space(ctx, true);
2095 + if (ctx->config.max_retention_s) {
2096 + time_t last_time_s = first_datafile->journalfile->v2.last_time_s;
2097 + if (!last_time_s)
2098 + last_time_s = first_datafile->journalfile->v2.first_time_s;
2099 +
2100 + time_t cutoff_before_time_s = now_realtime_sec() - ctx->config.max_retention_s;
2101 + trigger_time_retention = (last_time_s && last_time_s <= cutoff_before_time_s);
2102 + }
2103 +
2104 + // avoid disk calculation if we will trigger time retention
2105 + // calculate estimated disk space only if we have a disk cap
2106 + if (false == trigger_time_retention && ctx->config.max_disk_space)
2107 + estimated_disk_space = rrdeng_get_used_disk_space(ctx, true);
2108
2109 netdata_rwlock_rdunlock(&ctx->datafiles.rwlock);
2110
2111 - if (ctx->config.max_retention_s) {
2112 - time_t retention = get_tier_retention(ctx);
2113 - if (retention > ctx->config.max_retention_s) {
2114 - __atomic_store_n(&ctx->datafiles.disk_time, false, __ATOMIC_RELAXED);
2115 - return true;
2116 - }
2111 + if (trigger_time_retention) {
2112 + __atomic_store_n(&ctx->datafiles.disk_time, false, __ATOMIC_RELAXED);
2113 + return true;
2114 }
2115
2116 if (ctx->config.max_disk_space && estimated_disk_space > ctx->config.max_disk_space) {