summaryrefslogtreecommitdiffstats
path: root/database/rrddim.c
diff options
context:
space:
mode:
Diffstat (limited to 'database/rrddim.c')
-rw-r--r--database/rrddim.c157
1 files changed, 80 insertions, 77 deletions
diff --git a/database/rrddim.c b/database/rrddim.c
index 2d909a70..b8059b3c 100644
--- a/database/rrddim.c
+++ b/database/rrddim.c
@@ -64,12 +64,15 @@ static void rrddim_insert_callback(const DICTIONARY_ITEM *item __maybe_unused, v
size_t entries = st->entries;
if(!entries) entries = 5;
- rd->db = netdata_mmap(NULL, entries * sizeof(storage_number), MAP_PRIVATE, 1);
+ rd->db = netdata_mmap(NULL, entries * sizeof(storage_number), MAP_PRIVATE, 1, false, NULL);
if(!rd->db) {
info("Failed to use memory mode ram for chart '%s', dimension '%s', falling back to alloc", rrdset_name(st), rrddim_name(rd));
ctr->memory_mode = RRD_MEMORY_MODE_ALLOC;
}
- else rd->memsize = entries * sizeof(storage_number);
+ else {
+ rd->memsize = entries * sizeof(storage_number);
+ __atomic_add_fetch(&rrddim_db_memory_size, rd->memsize, __ATOMIC_RELAXED);
+ }
}
if(ctr->memory_mode == RRD_MEMORY_MODE_ALLOC || ctr->memory_mode == RRD_MEMORY_MODE_NONE) {
@@ -78,42 +81,24 @@ static void rrddim_insert_callback(const DICTIONARY_ITEM *item __maybe_unused, v
rd->db = rrddim_alloc_db(entries);
rd->memsize = entries * sizeof(storage_number);
+ __atomic_add_fetch(&rrddim_db_memory_size, rd->memsize, __ATOMIC_RELAXED);
}
rd->rrd_memory_mode = ctr->memory_mode;
- if (unlikely(rrdcontext_find_dimension_uuid(st, rrddim_id(rd), &(rd->metric_uuid)))) {
+ if (unlikely(rrdcontext_find_dimension_uuid(st, rrddim_id(rd), &(rd->metric_uuid))))
uuid_generate(rd->metric_uuid);
- bool found_in_sql = false; (void)found_in_sql;
-
-// bool found_in_sql = true;
-// if(unlikely(sql_find_dimension_uuid(st, rd, &rd->metric_uuid))) {
-// found_in_sql = false;
-// uuid_generate(rd->metric_uuid);
-// }
-
-#ifdef NETDATA_INTERNAL_CHECKS
- char uuid_str[UUID_STR_LEN];
- uuid_unparse_lower(rd->metric_uuid, uuid_str);
- error_report("Dimension UUID for host %s chart [%s] dimension [%s] not found in context. It is now set to %s (%s)",
- string2str(host->hostname),
- string2str(st->name),
- string2str(rd->name),
- uuid_str, found_in_sql ? "found in sqlite" : "newly generated");
-#endif
- }
// initialize the db tiers
{
size_t initialized = 0;
for(size_t tier = 0; tier < storage_tiers ; tier++) {
STORAGE_ENGINE *eng = host->db[tier].eng;
- rd->tiers[tier] = callocz(1, sizeof(struct rrddim_tier));
- rd->tiers[tier]->tier_grouping = host->db[tier].tier_grouping;
- rd->tiers[tier]->collect_ops = &eng->api.collect_ops;
- rd->tiers[tier]->query_ops = &eng->api.query_ops;
- rd->tiers[tier]->db_metric_handle = eng->api.metric_get_or_create(rd, host->db[tier].instance);
- storage_point_unset(rd->tiers[tier]->virtual_point);
+ rd->tiers[tier].tier_grouping = host->db[tier].tier_grouping;
+ rd->tiers[tier].collect_ops = &eng->api.collect_ops;
+ rd->tiers[tier].query_ops = &eng->api.query_ops;
+ rd->tiers[tier].db_metric_handle = eng->api.metric_get_or_create(rd, host->db[tier].instance);
+ storage_point_unset(rd->tiers[tier].virtual_point);
initialized++;
// internal_error(true, "TIER GROUPING of chart '%s', dimension '%s' for tier %d is set to %d", rd->rrdset->name, rd->name, tier, rd->tiers[tier]->tier_grouping);
@@ -122,7 +107,7 @@ static void rrddim_insert_callback(const DICTIONARY_ITEM *item __maybe_unused, v
if(!initialized)
error("Failed to initialize all db tiers for chart '%s', dimension '%s", rrdset_name(st), rrddim_name(rd));
- if(!rd->tiers[0])
+ if(!rd->tiers[0].db_metric_handle)
error("Failed to initialize the first db tier for chart '%s', dimension '%s", rrdset_name(st), rrddim_name(rd));
}
@@ -130,8 +115,8 @@ static void rrddim_insert_callback(const DICTIONARY_ITEM *item __maybe_unused, v
{
size_t initialized = 0;
for (size_t tier = 0; tier < storage_tiers; tier++) {
- if (rd->tiers[tier]) {
- rd->tiers[tier]->db_collection_handle = rd->tiers[tier]->collect_ops->init(rd->tiers[tier]->db_metric_handle, st->rrdhost->db[tier].tier_grouping * st->update_every, rd->rrdset->storage_metrics_groups[tier]);
+ if (rd->tiers[tier].db_metric_handle) {
+ rd->tiers[tier].db_collection_handle = rd->tiers[tier].collect_ops->init(rd->tiers[tier].db_metric_handle, st->rrdhost->db[tier].tier_grouping * st->update_every, rd->rrdset->storage_metrics_groups[tier]);
initialized++;
}
}
@@ -172,7 +157,7 @@ static void rrddim_insert_callback(const DICTIONARY_ITEM *item __maybe_unused, v
rrdset_flag_set(st, RRDSET_FLAG_SYNC_CLOCK);
rrdset_flag_clear(st, RRDSET_FLAG_UPSTREAM_EXPOSED);
- ml_new_dimension(rd);
+ ml_dimension_new(rd);
ctr->react_action = RRDDIM_REACT_NEW;
@@ -181,6 +166,25 @@ static void rrddim_insert_callback(const DICTIONARY_ITEM *item __maybe_unused, v
}
+bool rrddim_finalize_collection_and_check_retention(RRDDIM *rd) {
+ size_t tiers_available = 0, tiers_said_no_retention = 0;
+
+ for(size_t tier = 0; tier < storage_tiers ;tier++) {
+ if(!rd->tiers[tier].db_collection_handle)
+ continue;
+
+ tiers_available++;
+
+ if(rd->tiers[tier].collect_ops->finalize(rd->tiers[tier].db_collection_handle))
+ tiers_said_no_retention++;
+
+ rd->tiers[tier].db_collection_handle = NULL;
+ }
+
+ // return true if the dimension has retention in the db
+ return (!tiers_said_no_retention || tiers_available > tiers_said_no_retention);
+}
+
static void rrddim_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, void *rrddim, void *rrdset) {
RRDDIM *rd = rrddim;
RRDSET *st = rrdset;
@@ -191,23 +195,11 @@ static void rrddim_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, v
rrdcontext_removed_rrddim(rd);
- ml_delete_dimension(rd);
+ ml_dimension_delete(rd);
debug(D_RRD_CALLS, "rrddim_free() %s.%s", rrdset_name(st), rrddim_name(rd));
- size_t tiers_available = 0, tiers_said_no_retention = 0;
- for(size_t tier = 0; tier < storage_tiers ;tier++) {
- if(rd->tiers[tier] && rd->tiers[tier]->db_collection_handle) {
- tiers_available++;
-
- if(rd->tiers[tier]->collect_ops->finalize(rd->tiers[tier]->db_collection_handle))
- tiers_said_no_retention++;
-
- rd->tiers[tier]->db_collection_handle = NULL;
- }
- }
-
- if (tiers_available == tiers_said_no_retention && tiers_said_no_retention && rd->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
+ if (!rrddim_finalize_collection_and_check_retention(rd) && rd->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
/* This metric has no data and no references */
metaqueue_delete_dimension_uuid(&rd->metric_uuid);
}
@@ -224,16 +216,16 @@ static void rrddim_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, v
rrddim_memory_file_free(rd);
for(size_t tier = 0; tier < storage_tiers ;tier++) {
- if(!rd->tiers[tier]) continue;
+ if(!rd->tiers[tier].db_metric_handle) continue;
STORAGE_ENGINE* eng = host->db[tier].eng;
- eng->api.metric_release(rd->tiers[tier]->db_metric_handle);
-
- freez(rd->tiers[tier]);
- rd->tiers[tier] = NULL;
+ eng->api.metric_release(rd->tiers[tier].db_metric_handle);
+ rd->tiers[tier].db_metric_handle = NULL;
}
if(rd->db) {
+ __atomic_sub_fetch(&rrddim_db_memory_size, rd->memsize, __ATOMIC_RELAXED);
+
if(rd->rrd_memory_mode == RRD_MEMORY_MODE_RAM)
netdata_munmap(rd->db, rd->memsize);
else
@@ -259,9 +251,9 @@ static bool rrddim_conflict_callback(const DICTIONARY_ITEM *item __maybe_unused,
rc += rrddim_set_divisor(st, rd, ctr->divisor);
for(size_t tier = 0; tier < storage_tiers ;tier++) {
- if (rd->tiers[tier] && !rd->tiers[tier]->db_collection_handle)
- rd->tiers[tier]->db_collection_handle =
- rd->tiers[tier]->collect_ops->init(rd->tiers[tier]->db_metric_handle, st->rrdhost->db[tier].tier_grouping * st->update_every, rd->rrdset->storage_metrics_groups[tier]);
+ if (!rd->tiers[tier].db_collection_handle)
+ rd->tiers[tier].db_collection_handle =
+ rd->tiers[tier].collect_ops->init(rd->tiers[tier].db_metric_handle, st->rrdhost->db[tier].tier_grouping * st->update_every, rd->rrdset->storage_metrics_groups[tier]);
}
if(rrddim_flag_check(rd, RRDDIM_FLAG_ARCHIVED)) {
@@ -285,7 +277,6 @@ static void rrddim_react_callback(const DICTIONARY_ITEM *item __maybe_unused, vo
if(ctr->react_action & (RRDDIM_REACT_UPDATED | RRDDIM_REACT_NEW)) {
rrddim_flag_set(rd, RRDDIM_FLAG_METADATA_UPDATE);
- rrdset_flag_set(rd->rrdset, RRDSET_FLAG_METADATA_UPDATE);
rrdhost_flag_set(rd->rrdset->rrdhost, RRDHOST_FLAG_METADATA_UPDATE);
}
@@ -300,7 +291,8 @@ static void rrddim_react_callback(const DICTIONARY_ITEM *item __maybe_unused, vo
void rrddim_index_init(RRDSET *st) {
if(!st->rrddim_root_index) {
- st->rrddim_root_index = dictionary_create(DICT_OPTION_DONT_OVERWRITE_VALUE);
+ st->rrddim_root_index = dictionary_create_advanced(DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE,
+ &dictionary_stats_category_rrdset_rrddim, sizeof(RRDDIM));
dictionary_register_insert_callback(st->rrddim_root_index, rrddim_insert_callback, NULL);
dictionary_register_conflict_callback(st->rrddim_root_index, rrddim_conflict_callback, NULL);
@@ -420,38 +412,45 @@ inline int rrddim_set_divisor(RRDSET *st, RRDDIM *rd, collected_number divisor)
// ----------------------------------------------------------------------------
+time_t rrddim_last_entry_s_of_tier(RRDDIM *rd, size_t tier) {
+ if(unlikely(tier > storage_tiers || !rd->tiers[tier].db_metric_handle))
+ return 0;
+
+ return rd->tiers[tier].query_ops->latest_time_s(rd->tiers[tier].db_metric_handle);
+}
+
// get the timestamp of the last entry in the round-robin database
-time_t rrddim_last_entry_t(RRDDIM *rd) {
- time_t latest = rd->tiers[0]->query_ops->latest_time(rd->tiers[0]->db_metric_handle);
+time_t rrddim_last_entry_s(RRDDIM *rd) {
+ time_t latest_time_s = rrddim_last_entry_s_of_tier(rd, 0);
for(size_t tier = 1; tier < storage_tiers ;tier++) {
- if(unlikely(!rd->tiers[tier])) continue;
+ if(unlikely(!rd->tiers[tier].db_metric_handle)) continue;
- time_t t = rd->tiers[tier]->query_ops->latest_time(rd->tiers[tier]->db_metric_handle);
- if(t > latest)
- latest = t;
+ time_t t = rrddim_last_entry_s_of_tier(rd, tier);
+ if(t > latest_time_s)
+ latest_time_s = t;
}
- return latest;
+ return latest_time_s;
}
-time_t rrddim_first_entry_t_of_tier(RRDDIM *rd, size_t tier) {
- if(unlikely(tier > storage_tiers || !rd->tiers[tier]))
+time_t rrddim_first_entry_s_of_tier(RRDDIM *rd, size_t tier) {
+ if(unlikely(tier > storage_tiers || !rd->tiers[tier].db_metric_handle))
return 0;
- return rd->tiers[tier]->query_ops->oldest_time(rd->tiers[tier]->db_metric_handle);
+ return rd->tiers[tier].query_ops->oldest_time_s(rd->tiers[tier].db_metric_handle);
}
-time_t rrddim_first_entry_t(RRDDIM *rd) {
- time_t oldest = 0;
+time_t rrddim_first_entry_s(RRDDIM *rd) {
+ time_t oldest_time_s = 0;
for(size_t tier = 0; tier < storage_tiers ;tier++) {
- time_t t = rrddim_first_entry_t_of_tier(rd, tier);
- if(t != 0 && (oldest == 0 || t < oldest))
- oldest = t;
+ time_t t = rrddim_first_entry_s_of_tier(rd, tier);
+ if(t != 0 && (oldest_time_s == 0 || t < oldest_time_s))
+ oldest_time_s = t;
}
- return oldest;
+ return oldest_time_s;
}
RRDDIM *rrddim_add_custom(RRDSET *st
@@ -498,8 +497,8 @@ int rrddim_hide(RRDSET *st, const char *id) {
return 1;
}
if (!rrddim_flag_check(rd, RRDDIM_FLAG_META_HIDDEN)) {
- rrddim_flag_set(rd, RRDDIM_FLAG_META_HIDDEN);
- metaqueue_dimension_update_flags(rd);
+ rrddim_flag_set(rd, RRDDIM_FLAG_META_HIDDEN | RRDDIM_FLAG_METADATA_UPDATE);
+ rrdhost_flag_set(rd->rrdset->rrdhost, RRDHOST_FLAG_METADATA_UPDATE);
}
rrddim_option_set(rd, RRDDIM_OPTION_HIDDEN);
@@ -518,7 +517,8 @@ int rrddim_unhide(RRDSET *st, const char *id) {
}
if (rrddim_flag_check(rd, RRDDIM_FLAG_META_HIDDEN)) {
rrddim_flag_clear(rd, RRDDIM_FLAG_META_HIDDEN);
- metaqueue_dimension_update_flags(rd);
+ rrddim_flag_set(rd, RRDDIM_FLAG_METADATA_UPDATE);
+ rrdhost_flag_set(rd->rrdset->rrdhost, RRDHOST_FLAG_METADATA_UPDATE);
}
rrddim_option_clear(rd, RRDDIM_OPTION_HIDDEN);
@@ -650,6 +650,7 @@ void rrddim_memory_file_free(RRDDIM *rd) {
rrddim_memory_file_update(rd);
struct rrddim_map_save_v019 *rd_on_file = rd->rd_on_file;
+ __atomic_sub_fetch(&rrddim_db_memory_size, rd_on_file->memsize + strlen(rd_on_file->cache_filename), __ATOMIC_RELAXED);
freez(rd_on_file->cache_filename);
netdata_munmap(rd_on_file, rd_on_file->memsize);
@@ -686,10 +687,10 @@ bool rrddim_memory_load_or_create_map_save(RRDSET *st, RRDDIM *rd, RRD_MEMORY_MO
char filename[FILENAME_MAX + 1];
char fullfilename[FILENAME_MAX + 1];
rrdset_strncpyz_name(filename, rrddim_id(rd), FILENAME_MAX);
- snprintfz(fullfilename, FILENAME_MAX, "%s/%s.db", st->cache_dir, filename);
+ snprintfz(fullfilename, FILENAME_MAX, "%s/%s.db", rrdset_cache_dir(st), filename);
- rd_on_file = (struct rrddim_map_save_v019 *)netdata_mmap(fullfilename, size,
- ((memory_mode == RRD_MEMORY_MODE_MAP) ? MAP_SHARED : MAP_PRIVATE), 1);
+ rd_on_file = (struct rrddim_map_save_v019 *)netdata_mmap(
+ fullfilename, size, ((memory_mode == RRD_MEMORY_MODE_MAP) ? MAP_SHARED : MAP_PRIVATE), 1, false, NULL);
if(unlikely(!rd_on_file)) return false;
@@ -747,6 +748,8 @@ bool rrddim_memory_load_or_create_map_save(RRDSET *st, RRDDIM *rd, RRD_MEMORY_MO
rd_on_file->rrd_memory_mode = memory_mode;
rd_on_file->cache_filename = strdupz(fullfilename);
+ __atomic_add_fetch(&rrddim_db_memory_size, rd_on_file->memsize + strlen(rd_on_file->cache_filename), __ATOMIC_RELAXED);
+
rd->db = &rd_on_file->values[0];
rd->rd_on_file = rd_on_file;
rd->memsize = size;