master
c 73 lines 2.78 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "rrddim-backfill.h"
4 #include "database/rrddim-collection.h"
5
6 // ----------------------------------------------------------------------------
7 // fill the gap of a tier
8
9 NOT_INLINE_HOT bool backfill_tier_from_smaller_tiers(RRDDIM *rd, size_t tier, time_t now_s) {
10 if(unlikely(tier >= nd_profile.storage_tiers)) return false;
11 #ifdef ENABLE_DBENGINE
12 if(default_backfill == RRD_BACKFILL_NONE) return false;
13 #else
14 return false;
15 #endif
16
17 struct rrddim_tier *t = &rd->tiers[tier];
18 if(unlikely(!t)) return false;
19
20 time_t latest_time_s = storage_engine_latest_time_s(t->seb, t->smh);
21 time_t granularity = (time_t)t->tier_grouping * (time_t)rd->rrdset->update_every;
22 time_t time_diff = now_s - latest_time_s;
23
24 // if the user wants only NEW backfilling, and we don't have any data
25 #ifdef ENABLE_DBENGINE
26 if(default_backfill == RRD_BACKFILL_NEW && latest_time_s <= 0) return false;
27 #else
28 return false;
29 #endif
30
31 // there is really nothing we can do
32 if(now_s <= latest_time_s || time_diff < granularity) return false;
33
34 stream_control_backfill_query_started();
35
36 // for each lower tier
37 struct storage_engine_query_handle seqh;
38 for(int read_tier = (int)tier - 1; read_tier >= 0 ; read_tier--){
39 time_t smaller_tier_first_time = storage_engine_oldest_time_s(rd->tiers[read_tier].seb, rd->tiers[read_tier].smh);
40 time_t smaller_tier_last_time = storage_engine_latest_time_s(rd->tiers[read_tier].seb, rd->tiers[read_tier].smh);
41 if(smaller_tier_last_time <= latest_time_s) continue; // it is as bad as we are
42
43 long after_wanted = (latest_time_s < smaller_tier_first_time) ? smaller_tier_first_time : latest_time_s;
44 long before_wanted = smaller_tier_last_time;
45
46 struct rrddim_tier *tmp = &rd->tiers[read_tier];
47 storage_engine_query_init(tmp->seb, tmp->smh, &seqh, after_wanted, before_wanted, STORAGE_PRIORITY_SYNCHRONOUS_FIRST);
48
49 size_t points_read = 0;
50
51 while(!storage_engine_query_is_finished(&seqh)) {
52
53 STORAGE_POINT sp = storage_engine_query_next_metric(&seqh);
54 points_read++;
55
56 if(sp.end_time_s > latest_time_s) {
57 latest_time_s = sp.end_time_s;
58 store_metric_at_tier(rd, tier, t, sp, sp.end_time_s * USEC_PER_SEC);
59 }
60 }
61
62 storage_engine_query_finalize(&seqh);
63 store_metric_collection_completed();
64 pulse_queries_backfill_query_completed(points_read);
65
66 //internal_error(true, "DBENGINE: backfilled chart '%s', dimension '%s', tier %d, from %ld to %ld, with %zu points from tier %d",
67 // rd->rrdset->name, rd->name, tier, after_wanted, before_wanted, points, tr);
68 }
69
70 stream_control_backfill_query_finished();
71
72 return true;
73 }