Revert "Configurable storage engine for Netdata agents: step 3 (#12892)" (#13171)
This reverts commit 100a12c6cc01222b1518e5e50d2147f592d8a111. A couple parent/child startup/shutdown scenarios can lead to crashes.
vkalintiris committed
Jun 17, 2022 at 14:59 UTC
afae8971f0f9df87c09920430c288d65e4643292
19 files changed
+217
-320
daemon/analytics.c
-3
@@ -2,9 +2,6 @@
2
3
#include "common.h"
4
#include "buildinfo.h"
5
-#ifdef ENABLE_DBENGINE
6
-#include "database/engine/rrdengineapi.h"
7
-#endif
5
6
struct analytics_data analytics_data;
7
extern void analytics_exporting_connectors (BUFFER *b);
daemon/global_statistics.c
+1
-4
@@ -1,9 +1,6 @@
1
// SPDX-License-Identifier: GPL-3.0-or-later
2
3
#include "common.h"
4
-#ifdef ENABLE_DBENGINE
5
-#include "database/engine/rrdengineapi.h"
6
-#endif
4
5
#define GLOBAL_STATS_RESET_WEB_USEC_MAX 0x01
6
@@ -459,7 +456,7 @@ static void dbengine_statistics_charts(void) {
456
457
rrdhost_foreach_read(host) {
458
if (host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE && !rrdhost_flag_check(host, RRDHOST_FLAG_ARCHIVED)) {
462
- if (host->rrdeng_ctx == host->rrdeng_ctx->engine->context) {
459
+ if (&multidb_ctx == host->rrdeng_ctx) {
460
if (counted_multihost_db)
461
continue; /* Only count multi-host DB once */
462
counted_multihost_db = 1;
daemon/main.c
+6
-15
@@ -3,10 +3,6 @@
3
#include "common.h"
4
#include "buildinfo.h"
5
#include "static_threads.h"
6
-#include "database/storage_engine.h"
7
-#ifdef ENABLE_DBENGINE
8
-#include "database/engine/rrdengineapi.h"
9
-#endif
6
7
int netdata_zero_metrics_enabled;
8
int netdata_anonymous_statistics_enabled;
@@ -58,18 +54,13 @@ void netdata_cleanup_and_exit(int ret) {
54
55
// free the database
56
info("EXIT: freeing database memory...");
61
- for (STORAGE_ENGINE* eng = storage_engine_foreach_init(); eng; eng = storage_engine_foreach_next(eng)) {
62
- if (eng->context)
63
- eng->api.engine_ops.exit(eng->context);
64
- }
65
-
57
+#ifdef ENABLE_DBENGINE
58
+ rrdeng_prepare_exit(&multidb_ctx);
59
+#endif
60
rrdhost_free_all();
67
- for (STORAGE_ENGINE* eng = storage_engine_foreach_init(); eng; eng = storage_engine_foreach_next(eng)) {
68
- if (eng->context) {
69
- eng->api.engine_ops.destroy(eng->context);
70
- eng->context = NULL;
71
- }
72
- }
61
+#ifdef ENABLE_DBENGINE
62
+ rrdeng_exit(&multidb_ctx);
63
+#endif
64
}
65
sql_close_database();
66
daemon/unit_test.c
+2
-5
@@ -1,9 +1,6 @@
1
// SPDX-License-Identifier: GPL-3.0-or-later
2
3
#include "common.h"
4
-#ifdef ENABLE_DBENGINE
5
-#include "database/engine/rrdengineapi.h"
6
-#endif
4
5
static int check_number_printing(void) {
6
struct {
@@ -1160,7 +1157,7 @@ int run_test(struct test *test)
1157
RRDSET *st = rrdset_create_localhost("netdata", name, name, "netdata", NULL, "Unit Testing", "a value", "unittest", NULL, 1
1158
, test->update_every, RRDSET_TYPE_LINE);
1159
RRDDIM *rd = rrddim_add(st, "dim1", NULL, test->multiplier, test->divisor, test->algorithm);
1163
-
1160
+
1161
RRDDIM *rd2 = NULL;
1162
if(test->feed2)
1163
rd2 = rrddim_add(st, "dim2", NULL, test->multiplier, test->divisor, test->algorithm);
@@ -1176,7 +1173,7 @@ int run_test(struct test *test)
1173
1174
if(c) {
1175
time_now += test->feed[c].microseconds;
1179
- fprintf(stderr, " > %s: feeding position %lu, after %0.3f seconds (%0.3f seconds from start), delta " CALCULATED_NUMBER_FORMAT ", rate " CALCULATED_NUMBER_FORMAT "\n",
1176
+ fprintf(stderr, " > %s: feeding position %lu, after %0.3f seconds (%0.3f seconds from start), delta " CALCULATED_NUMBER_FORMAT ", rate " CALCULATED_NUMBER_FORMAT "\n",
1177
test->name, c+1,
1178
(float)test->feed[c].microseconds / 1000000.0,
1179
(float)time_now / 1000000.0,
database/engine/rrdengine.c
+5
-4
@@ -1339,12 +1339,13 @@ error_after_loop_init:
1339
*/
1340
void rrdengine_main(void)
1341
{
1342
- STORAGE_ENGINE_INSTANCE* ctx;
1342
+ int ret;
1343
+ struct rrdengine_instance *ctx;
1344
1345
sanity_check();
1345
- ctx = rrdeng_init(storage_engine_get(RRD_MEMORY_MODE_DBENGINE), NULL);
1346
- if (!ctx) {
1347
- exit(1);
1346
+ ret = rrdeng_init(NULL, &ctx, "/tmp", RRDENG_MIN_PAGE_CACHE_SIZE_MB, RRDENG_MIN_DISK_SPACE_MB);
1347
+ if (ret) {
1348
+ exit(ret);
1349
}
1350
rrdeng_exit(ctx);
1351
fprintf(stderr, "Hello world!");
database/engine/rrdengine.h
-2
@@ -13,7 +13,6 @@
13
#include <openssl/evp.h>
14
#include "daemon/common.h"
15
#include "../rrd.h"
16
-#include "../storage_engine.h"
16
#include "rrddiskprotocol.h"
17
#include "rrdenginelib.h"
18
#include "datafile.h"
@@ -227,7 +226,6 @@ extern rrdeng_stats_t global_flushing_pressure_page_deletions; /* number of dele
226
#define QUIESCED (2) /* is set after all threads have finished running */
227
228
struct rrdengine_instance {
230
- STORAGE_ENGINE_INSTANCE parent;
229
struct metalog_instance *metalog_ctx;
230
struct rrdengine_worker_config worker_config;
231
struct completion rrdengine_completion;
database/engine/rrdengineapi.c
+42
-57
@@ -1,6 +1,8 @@
1
// SPDX-License-Identifier: GPL-3.0-or-later
2
#include "rrdengine.h"
3
-#include "../storage_engine.h"
3
+
4
+/* Default global database instance */
5
+struct rrdengine_instance multidb_ctx;
6
7
int db_engine_use_malloc = 0;
8
int default_rrdeng_page_cache_mb = 32;
@@ -9,16 +11,9 @@ int default_multidb_disk_quota_mb = 256;
11
/* Default behaviour is to unblock data collection if the page cache is full of dirty pages by dropping metrics */
12
uint8_t rrdeng_drop_metrics_under_page_cache_pressure = 1;
13
12
-void *rrdeng_create_page(struct rrdengine_instance *ctx, uuid_t *id, struct rrdeng_page_descr **ret_descr);
13
-void rrdeng_commit_page(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr,
14
- Word_t page_correlation_id);
15
-void *rrdeng_get_latest_page(struct rrdengine_instance *ctx, uuid_t *id, void **handle);
16
-void *rrdeng_get_page(struct rrdengine_instance *ctx, uuid_t *id, usec_t point_in_time, void **handle);
17
-void rrdeng_put_page(struct rrdengine_instance *ctx, void *handle);
18
-
14
static inline struct rrdengine_instance *get_rrdeng_ctx_from_host(RRDHOST *host)
15
{
21
- return (struct rrdengine_instance*) host->rrdeng_ctx;
16
+ return host->rrdeng_ctx;
17
}
18
19
/* This UUID is not unique across hosts */
@@ -74,7 +69,7 @@ void rrdeng_metric_init(RRDDIM *rd)
69
pg_cache = &ctx->pg_cache;
70
71
rrdeng_generate_legacy_uuid(rd->id, rd->rrdset->id, &legacy_uuid);
77
- if (host != localhost && host->rrdeng_ctx->engine && host->rrdeng_ctx == host->rrdeng_ctx->engine->context)
72
+ if (host != localhost && host->rrdeng_ctx == &multidb_ctx)
73
is_multihost_child = 1;
74
75
uv_rwlock_rdlock(&pg_cache->metrics_index.lock);
@@ -201,12 +196,16 @@ void rrdeng_store_metric_flush_current_page(RRDDIM *rd)
196
void rrdeng_store_metric_next(RRDDIM *rd, usec_t point_in_time, storage_number number)
197
{
198
struct rrdeng_collect_handle *handle = (struct rrdeng_collect_handle *)rd->state->handle;
204
- struct rrdengine_instance *ctx = handle->ctx;
205
- struct page_cache *pg_cache = &ctx->pg_cache;
206
- struct rrdeng_page_descr *descr = handle->descr;
199
+ struct rrdengine_instance *ctx;
200
+ struct page_cache *pg_cache;
201
+ struct rrdeng_page_descr *descr;
202
storage_number *page;
203
uint8_t must_flush_unaligned_page = 0, perfect_page_alignment = 0;
204
205
+ ctx = handle->ctx;
206
+ pg_cache = &ctx->pg_cache;
207
+ descr = handle->descr;
208
+
209
if (descr) {
210
/* Make alignment decisions */
211
@@ -821,11 +820,10 @@ void *rrdeng_get_page(struct rrdengine_instance *ctx, uuid_t *id, usec_t point_i
820
* You must not change the indices of the statistics or user code will break.
821
* You must not exceed RRDENG_NR_STATS or it will crash.
822
*/
824
-void rrdeng_get_37_statistics(STORAGE_ENGINE_INSTANCE* context, unsigned long long *array)
823
+void rrdeng_get_37_statistics(struct rrdengine_instance *ctx, unsigned long long *array)
824
{
826
- if (context == NULL)
825
+ if (ctx == NULL)
826
return;
828
- struct rrdengine_instance* ctx = (struct rrdengine_instance*) context;
827
828
struct page_cache *pg_cache = &ctx->pg_cache;
829
@@ -876,23 +874,19 @@ void rrdeng_put_page(struct rrdengine_instance *ctx, void *handle)
874
pg_cache_put(ctx, (struct rrdeng_page_descr *)handle);
875
}
876
879
-
880
-STORAGE_ENGINE_INSTANCE*
881
-rrdeng_init(STORAGE_ENGINE* eng, RRDHOST *host)
877
+/*
878
+ * Returns 0 on success, negative on error
879
+ */
880
+int rrdeng_init(RRDHOST *host, struct rrdengine_instance **ctxp, char *dbfiles_path, unsigned page_cache_mb,
881
+ unsigned disk_space_mb)
882
{
883
struct rrdengine_instance *ctx;
884
int error;
885
+ uint32_t max_open_files;
886
886
- bool is_legacy = is_legacy_child(host->machine_guid);
887
- if (!is_legacy && eng->context) {
888
- if (host->rrd_memory_mode == eng->id && host->rrdeng_ctx == NULL) {
889
- host->rrdeng_ctx = eng->context;
890
- }
891
- return eng->context;
892
- }
887
+ max_open_files = rlimit_nofile.rlim_cur / 4;
888
889
/* reserve RRDENG_FD_BUDGET_PER_INSTANCE file descriptors for this instance */
895
- uint32_t max_open_files = rlimit_nofile.rlim_cur / 4;
890
rrd_stat_atomic_add(&rrdeng_reserved_file_descriptors, RRDENG_FD_BUDGET_PER_INSTANCE);
891
if (rrdeng_reserved_file_descriptors > max_open_files) {
892
error(
@@ -901,18 +895,15 @@ rrdeng_init(STORAGE_ENGINE* eng, RRDHOST *host)
895
896
rrd_stat_atomic_add(&global_fs_errors, 1);
897
rrd_stat_atomic_add(&rrdeng_reserved_file_descriptors, -RRDENG_FD_BUDGET_PER_INSTANCE);
904
- return NULL;//UV_EMFILE;
898
+ return UV_EMFILE;
899
}
906
- char dbfiles_path[FILENAME_MAX + 1];
907
-
908
- snprintfz(dbfiles_path, FILENAME_MAX, "%s/dbengine", host->cache_dir);
909
- mkdir(dbfiles_path, 0775);
910
-
911
- int page_cache_mb = default_rrdeng_page_cache_mb;
912
- int disk_space_mb = default_rrdeng_disk_quota_mb;
900
914
- ctx = callocz(1, sizeof(*ctx));
915
- ctx->parent.engine = eng;
901
+ if (NULL == ctxp) {
902
+ ctx = &multidb_ctx;
903
+ memset(ctx, 0, sizeof(*ctx));
904
+ } else {
905
+ *ctxp = ctx = callocz(1, sizeof(*ctx));
906
+ }
907
ctx->global_compress_alg = RRD_LZ4;
908
if (page_cache_mb < RRDENG_MIN_PAGE_CACHE_SIZE_MB)
909
page_cache_mb = RRDENG_MIN_PAGE_CACHE_SIZE_MB;
@@ -935,15 +926,6 @@ rrdeng_init(STORAGE_ENGINE* eng, RRDHOST *host)
926
ctx->metalog_ctx = NULL; /* only set this after the metadata log has finished initializing */
927
ctx->host = host;
928
938
- // Attach context as the global context
939
- if (!is_legacy && !eng->context) {
940
- eng->context = (STORAGE_ENGINE_INSTANCE *)ctx;
941
- }
942
- // Attach context as the host context
943
- if (host->rrd_memory_mode == eng->id && host->rrdeng_ctx == NULL) {
944
- host->rrdeng_ctx = eng->context;
945
- }
946
-
929
memset(&ctx->worker_config, 0, sizeof(ctx->worker_config));
930
ctx->worker_config.ctx = ctx;
931
init_page_cache(ctx);
@@ -968,30 +950,30 @@ rrdeng_init(STORAGE_ENGINE* eng, RRDHOST *host)
950
goto error_after_rrdeng_worker;
951
}
952
971
- return (STORAGE_ENGINE_INSTANCE *)ctx;
953
+ return 0;
954
955
error_after_rrdeng_worker:
956
finalize_rrd_files(ctx);
957
error_after_init_rrd_files:
958
free_page_cache(ctx);
977
- if ((STORAGE_ENGINE_INSTANCE *)ctx != eng->context) {
959
+ if (ctx != &multidb_ctx) {
960
freez(ctx);
961
+ *ctxp = NULL;
962
}
963
rrd_stat_atomic_add(&rrdeng_reserved_file_descriptors, -RRDENG_FD_BUDGET_PER_INSTANCE);
981
- return NULL;//UV_EIO;
964
+ return UV_EIO;
965
}
966
967
/*
968
* Returns 0 on success, 1 on error
969
*/
987
-void rrdeng_exit(STORAGE_ENGINE_INSTANCE* context)
970
+int rrdeng_exit(struct rrdengine_instance *ctx)
971
{
972
struct rrdeng_cmd cmd;
973
991
- if (NULL == context) {
992
- return;
974
+ if (NULL == ctx) {
975
+ return 1;
976
}
994
- struct rrdengine_instance* ctx = (struct rrdengine_instance*)context;
977
978
/* TODO: add page to page cache */
979
cmd.opcode = RRDENG_SHUTDOWN;
@@ -1002,18 +984,21 @@ void rrdeng_exit(STORAGE_ENGINE_INSTANCE* context)
984
finalize_rrd_files(ctx);
985
//metalog_exit(ctx->metalog_ctx);
986
free_page_cache(ctx);
1005
- freez(ctx);
987
+
988
+ if (ctx != &multidb_ctx) {
989
+ freez(ctx);
990
+ }
991
rrd_stat_atomic_add(&rrdeng_reserved_file_descriptors, -RRDENG_FD_BUDGET_PER_INSTANCE);
992
+ return 0;
993
}
994
1009
-void rrdeng_prepare_exit(STORAGE_ENGINE_INSTANCE* context)
995
+void rrdeng_prepare_exit(struct rrdengine_instance *ctx)
996
{
997
struct rrdeng_cmd cmd;
998
1013
- if (NULL == context) {
999
+ if (NULL == ctx) {
1000
return;
1001
}
1016
- struct rrdengine_instance* ctx = (struct rrdengine_instance*)context;
1002
1003
completion_init(&ctx->rrdengine_completion);
1004
cmd.opcode = RRDENG_QUIESCE;
database/engine/rrdengineapi.h
+13
-4
@@ -17,6 +17,7 @@ extern int default_rrdeng_page_cache_mb;
17
extern int default_rrdeng_disk_quota_mb;
18
extern int default_multidb_disk_quota_mb;
19
extern uint8_t rrdeng_drop_metrics_under_page_cache_pressure;
20
+extern struct rrdengine_instance multidb_ctx;
21
22
struct rrdeng_region_info {
23
time_t start_time;
@@ -24,6 +25,13 @@ struct rrdeng_region_info {
25
unsigned points;
26
};
27
28
+extern void *rrdeng_create_page(struct rrdengine_instance *ctx, uuid_t *id, struct rrdeng_page_descr **ret_descr);
29
+extern void rrdeng_commit_page(struct rrdengine_instance *ctx, struct rrdeng_page_descr *descr,
30
+ Word_t page_correlation_id);
31
+extern void *rrdeng_get_latest_page(struct rrdengine_instance *ctx, uuid_t *id, void **handle);
32
+extern void *rrdeng_get_page(struct rrdengine_instance *ctx, uuid_t *id, usec_t point_in_time, void **handle);
33
+extern void rrdeng_put_page(struct rrdengine_instance *ctx, void *handle);
34
+
35
extern void rrdeng_generate_legacy_uuid(const char *dim_id, char *chart_id, uuid_t *ret_uuid);
36
extern void rrdeng_convert_legacy_uuid_to_multihost(char machine_guid[GUID_LEN + 1], uuid_t *legacy_uuid,
37
uuid_t *ret_uuid);
@@ -44,13 +52,14 @@ extern int rrdeng_load_metric_is_finished(struct rrddim_query_handle *rrdimm_han
52
extern void rrdeng_load_metric_finalize(struct rrddim_query_handle *rrdimm_handle);
53
extern time_t rrdeng_metric_latest_time(RRDDIM *rd);
54
extern time_t rrdeng_metric_oldest_time(RRDDIM *rd);
47
-extern void rrdeng_get_37_statistics(STORAGE_ENGINE_INSTANCE *ctx, unsigned long long *array);
55
+extern void rrdeng_get_37_statistics(struct rrdengine_instance *ctx, unsigned long long *array);
56
57
/* must call once before using anything */
50
-extern STORAGE_ENGINE_INSTANCE* rrdeng_init(STORAGE_ENGINE* eng, RRDHOST *host);
58
+extern int rrdeng_init(RRDHOST *host, struct rrdengine_instance **ctxp, char *dbfiles_path, unsigned page_cache_mb,
59
+ unsigned disk_space_mb);
60
52
-extern void rrdeng_exit(STORAGE_ENGINE_INSTANCE *ctx);
53
-extern void rrdeng_prepare_exit(STORAGE_ENGINE_INSTANCE *ctx);
61
+extern int rrdeng_exit(struct rrdengine_instance *ctx);
62
+extern void rrdeng_prepare_exit(struct rrdengine_instance *ctx);
63
extern int rrdeng_metric_latest_time_by_uuid(uuid_t *dim_uuid, time_t *first_entry_t, time_t *last_entry_t);
64
65
#endif /* NETDATA_RRDENGINEAPI_H */
database/ram/rrddim_mem.c
-14
@@ -1,20 +1,6 @@
1
// SPDX-License-Identifier: GPL-3.0-or-later
2
3
#include "rrddim_mem.h"
4
-#include "../storage_engine.h"
5
-
6
-STORAGE_ENGINE_INSTANCE* rrddim_storage_engine_instance_new(STORAGE_ENGINE* engine, RRDHOST *host) {
7
- (void)engine; (void)host;
8
- return NULL;
9
-}
10
-
11
-void rrddim_storage_engine_instance_exit(STORAGE_ENGINE_INSTANCE* context) {
12
- (void)context;
13
-}
14
-
15
-void rrddim_storage_engine_instance_destroy(STORAGE_ENGINE_INSTANCE* context) {
16
- (void)context;
17
-}
4
5
// ----------------------------------------------------------------------------
6
// RRDDIM legacy data collection functions
database/ram/rrddim_mem.h
-4
@@ -15,10 +15,6 @@ struct mem_query_handle {
15
uint8_t finished;
16
};
17
18
-STORAGE_ENGINE_INSTANCE* rrddim_storage_engine_instance_new(STORAGE_ENGINE* engine, RRDHOST *host);
19
-void rrddim_storage_engine_instance_exit(STORAGE_ENGINE_INSTANCE* context);
20
-void rrddim_storage_engine_instance_destroy(STORAGE_ENGINE_INSTANCE* context);
21
-
18
extern void rrddim_collect_init(RRDDIM *rd);
19
extern void rrddim_collect_store_metric(RRDDIM *rd, usec_t point_in_time, storage_number number);
20
extern int rrddim_collect_finalize(RRDDIM *rd);
database/rrd.c
+21
@@ -28,10 +28,31 @@ int gap_when_lost_iterations_above = 1;
28
// RRD - memory modes
29
30
inline const char *rrd_memory_mode_name(RRD_MEMORY_MODE id) {
31
+ switch(id) {
32
+ case RRD_MEMORY_MODE_RAM:
33
+ return RRD_MEMORY_MODE_RAM_NAME;
34
+
35
+ case RRD_MEMORY_MODE_MAP:
36
+ return RRD_MEMORY_MODE_MAP_NAME;
37
+
38
+ case RRD_MEMORY_MODE_NONE:
39
+ return RRD_MEMORY_MODE_NONE_NAME;
40
+
41
+ case RRD_MEMORY_MODE_SAVE:
42
+ return RRD_MEMORY_MODE_SAVE_NAME;
43
+
44
+ case RRD_MEMORY_MODE_ALLOC:
45
+ return RRD_MEMORY_MODE_ALLOC_NAME;
46
+
47
+ case RRD_MEMORY_MODE_DBENGINE:
48
+ return RRD_MEMORY_MODE_DBENGINE_NAME;
49
+ }
50
+
51
STORAGE_ENGINE* eng = storage_engine_get(id);
52
if (eng) {
53
return eng->name;
54
}
55
+
56
return RRD_MEMORY_MODE_SAVE_NAME;
57
}
58
database/rrd.h
+6
-3
@@ -18,8 +18,6 @@ typedef struct rrdcalc RRDCALC;
18
typedef struct rrdcalctemplate RRDCALCTEMPLATE;
19
typedef struct alarm_entry ALARM_ENTRY;
20
typedef struct context_param CONTEXT_PARAM;
21
-typedef struct storage_engine_instance STORAGE_ENGINE_INSTANCE;
22
-typedef struct storage_engine STORAGE_ENGINE;
21
22
typedef void *ml_host_t;
23
typedef void *ml_dimension_t;
@@ -856,7 +854,9 @@ struct rrdhost {
854
avl_tree_lock rrdfamily_root_index; // the host's chart families index
855
avl_tree_lock rrdvar_root_index; // the host's chart variables index
856
859
- STORAGE_ENGINE_INSTANCE *rrdeng_ctx; // DB engine instance for this host
857
+#ifdef ENABLE_DBENGINE
858
+ struct rrdengine_instance *rrdeng_ctx; // DB engine instance for this host
859
+#endif
860
uuid_t host_uuid; // Global GUID for this host
861
uuid_t *node_id; // Cloud node_id
862
@@ -1324,6 +1324,9 @@ extern void set_host_properties(
1324
// ----------------------------------------------------------------------------
1325
// RRD DB engine declarations
1326
1327
+#ifdef ENABLE_DBENGINE
1328
+#include "database/engine/rrdengineapi.h"
1329
+#endif
1330
#include "sqlite/sqlite_functions.h"
1331
#include "sqlite/sqlite_aclk.h"
1332
#include "sqlite/sqlite_aclk_chart.h"
database/rrdhost.c
+70
-19
@@ -2,10 +2,6 @@
2
3
#define NETDATA_RRD_INTERNALS
4
#include "rrd.h"
5
-#include "storage_engine.h"
6
-#ifdef ENABLE_DBENGINE
7
-#include "engine/rrdenginelib.h"
8
-#endif
5
6
RRDHOST *localhost = NULL;
7
size_t rrd_hosts_available = 0;
@@ -337,8 +333,41 @@ RRDHOST *rrdhost_create(const char *hostname,
333
else
334
error_report("Host machine GUID %s is not valid", host->machine_guid);
335
340
- // Create engine
341
- host->rrdeng_ctx = storage_engine_new(storage_engine_get(host->rrd_memory_mode), host);
336
+ if (host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
337
+#ifdef ENABLE_DBENGINE
338
+ char dbenginepath[FILENAME_MAX + 1];
339
+ int ret;
340
+
341
+ snprintfz(dbenginepath, FILENAME_MAX, "%s/dbengine", host->cache_dir);
342
+ ret = mkdir(dbenginepath, 0775);
343
+ if (ret != 0 && errno != EEXIST)
344
+ error("Host '%s': cannot create directory '%s'", host->hostname, dbenginepath);
345
+ else ret = 0; // succeed
346
+ if (is_legacy) // initialize legacy dbengine instance as needed
347
+ ret = rrdeng_init(host, &host->rrdeng_ctx, dbenginepath, default_rrdeng_page_cache_mb,
348
+ default_rrdeng_disk_quota_mb); // may fail here for legacy dbengine initialization
349
+ else
350
+ host->rrdeng_ctx = &multidb_ctx;
351
+ if (ret) { // check legacy or multihost initialization success
352
+ error(
353
+ "Host '%s': cannot initialize host with machine guid '%s'. Failed to initialize DB engine at '%s'.",
354
+ host->hostname, host->machine_guid, host->cache_dir);
355
+ rrdhost_free(host);
356
+ host = NULL;
357
+ //rrd_hosts_available++; //TODO: maybe we want this?
358
+
359
+ return host;
360
+ }
361
+
362
+#else
363
+ fatal("RRD_MEMORY_MODE_DBENGINE is not supported in this platform.");
364
+#endif
365
+ }
366
+ else {
367
+#ifdef ENABLE_DBENGINE
368
+ host->rrdeng_ctx = &multidb_ctx;
369
+#endif
370
+ }
371
372
// ------------------------------------------------------------------------
373
// link it and add it to the index
@@ -641,8 +670,10 @@ restart_after_removal:
670
info("Host '%s' with machine guid '%s' is obsolete - cleaning up.", host->hostname, host->machine_guid);
671
672
if (rrdhost_flag_check(host, RRDHOST_FLAG_DELETE_ORPHAN_HOST)
673
+#ifdef ENABLE_DBENGINE
674
/* don't delete multi-host DB host files */
645
- && !(host->rrdeng_ctx->engine && host->rrdeng_ctx->engine->context == host->rrdeng_ctx)
675
+ && !(host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE && host->rrdeng_ctx == &multidb_ctx)
676
+#endif
677
)
678
rrdhost_delete_charts(host);
679
else
@@ -709,6 +740,25 @@ int rrd_init(char *hostname, struct rrdhost_system_info *system_info) {
740
return 1;
741
}
742
743
+#ifdef ENABLE_DBENGINE
744
+ char dbenginepath[FILENAME_MAX + 1];
745
+ int ret;
746
+ snprintfz(dbenginepath, FILENAME_MAX, "%s/dbengine", localhost->cache_dir);
747
+ ret = mkdir(dbenginepath, 0775);
748
+ if (ret != 0 && errno != EEXIST)
749
+ error("Host '%s': cannot create directory '%s'", localhost->hostname, dbenginepath);
750
+ else // Unconditionally create multihost db to support on demand host creation
751
+ ret = rrdeng_init(NULL, NULL, dbenginepath, default_rrdeng_page_cache_mb, default_multidb_disk_quota_mb);
752
+ if (ret) {
753
+ error(
754
+ "Host '%s' with machine guid '%s' failed to initialize multi-host DB engine instance at '%s'.",
755
+ localhost->hostname, localhost->machine_guid, localhost->cache_dir);
756
+ rrdhost_free(localhost);
757
+ localhost = NULL;
758
+ rrd_unlock();
759
+ fatal("Failed to initialize dbengine");
760
+ }
761
+#endif
762
sql_aclk_sync_init();
763
rrd_unlock();
764
@@ -853,12 +903,12 @@ void rrdhost_free(RRDHOST *host) {
903
// ------------------------------------------------------------------------
904
// release its children resources
905
856
- STORAGE_ENGINE* eng = host->rrdeng_ctx->engine;
857
- if (host->rrdeng_ctx != eng->context) {
858
- if (eng && eng->api.engine_ops.exit)
859
- eng->api.engine_ops.exit(host->rrdeng_ctx);
906
+#ifdef ENABLE_DBENGINE
907
+ if (host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
908
+ if (host->rrdeng_ctx != &multidb_ctx)
909
+ rrdeng_prepare_exit(host->rrdeng_ctx);
910
}
861
-
911
+#endif
912
while(host->rrdset_root)
913
rrdset_free(host->rrdset_root);
914
@@ -889,11 +939,10 @@ void rrdhost_free(RRDHOST *host) {
939
940
health_alarm_log_free(host);
941
892
- if (host->rrdeng_ctx != eng->context) {
893
- if (eng)
894
- eng->api.engine_ops.destroy(host->rrdeng_ctx);
895
- host->rrdeng_ctx = NULL;
896
- }
942
+#ifdef ENABLE_DBENGINE
943
+ if (host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE && host->rrdeng_ctx != &multidb_ctx)
944
+ rrdeng_exit(host->rrdeng_ctx);
945
+#endif
946
947
// ------------------------------------------------------------------------
948
// remove it from the indexes
@@ -1209,8 +1258,10 @@ void rrdhost_cleanup_all(void) {
1258
RRDHOST *host;
1259
rrdhost_foreach_read(host) {
1260
if (host != localhost && rrdhost_flag_check(host, RRDHOST_FLAG_DELETE_ORPHAN_HOST) && !host->receiver
1261
+#ifdef ENABLE_DBENGINE
1262
/* don't delete multi-host DB host files */
1213
- && !(host->rrdeng_ctx->engine && host->rrdeng_ctx->engine->context == host->rrdeng_ctx)
1263
+ && !(host->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE && host->rrdeng_ctx == &multidb_ctx)
1264
+#endif
1265
)
1266
rrdhost_delete_charts(host);
1267
else
@@ -1293,7 +1344,7 @@ restart_after_removal:
1344
rrdvar_free_remaining_variables(host, &st->rrdvar_root_index);
1345
1346
rrdset_flag_clear(st, RRDSET_FLAG_OBSOLETE);
1296
-
1347
+
1348
if (st->dimensions) {
1349
/* If the chart still has dimensions don't delete it from the metadata log */
1350
continue;
database/rrdset.c
-4
@@ -3,10 +3,6 @@
3
#define NETDATA_RRD_INTERNALS
4
#include "rrd.h"
5
#include <sched.h>
6
-#ifdef ENABLE_DBENGINE
7
-#include "database/engine/rrddiskprotocol.h"
8
-#include "database/engine/rrdengineapi.h"
9
-#endif
6
7
void __rrdset_check_rdlock(RRDSET *st, const char *file, const char *function, const unsigned long line) {
8
debug(D_RRD_CALLS, "Checking read lock on chart '%s'", st->id);
database/sqlite/sqlite_aclk_chart.c
-3
@@ -2,9 +2,6 @@
2
3
#include "sqlite_functions.h"
4
#include "sqlite_aclk_chart.h"
5
-#ifdef ENABLE_DBENGINE
6
-#include "../engine/rrdengineapi.h"
7
-#endif
5
6
#if defined(ENABLE_ACLK) && defined(ENABLE_NEW_CLOUD_PROTOCOL)
7
#include "../../aclk/aclk_charts_api.h"
database/sqlite/sqlite_functions.c
+4
-8
@@ -1,10 +1,6 @@
1
// SPDX-License-Identifier: GPL-3.0-or-later
2
3
#include "sqlite_functions.h"
4
-#ifdef ENABLE_DBENGINE
5
-#include "../engine/rrdengineapi.h"
6
-#endif
7
-#include "database/storage_engine.h"
4
5
#define DB_METADATA_VERSION "1"
6
@@ -427,7 +423,7 @@ int sql_init_database(db_check_action_type_t rebuild, int memory)
423
// PRAGMA temp_store = 0 | DEFAULT | 1 | FILE | 2 | MEMORY;
424
snprintfz(buf, 1024, "PRAGMA temp_store=%s;", config_get(CONFIG_SECTION_SQLITE, "temp store", "MEMORY"));
425
if(init_database_batch(rebuild, 0, list)) return 1;
430
-
426
+
427
// https://www.sqlite.org/pragma.html#pragma_journal_size_limit
428
// PRAGMA schema.journal_size_limit = N ;
429
snprintfz(buf, 1024, "PRAGMA journal_size_limit=%lld;", config_get_number(CONFIG_SECTION_SQLITE, "journal size limit", 16777216));
@@ -1282,9 +1278,9 @@ RRDHOST *sql_create_host_by_uuid(char *hostname)
1278
1279
host->system_info = callocz(1, sizeof(*host->system_info));;
1280
rrdhost_flag_set(host, RRDHOST_FLAG_ARCHIVED);
1285
-
1286
- // Create multidb engine instance if necessary
1287
- host->rrdeng_ctx = storage_engine_new(storage_engine_get(RRD_MEMORY_MODE_DBENGINE), host);
1281
+#ifdef ENABLE_DBENGINE
1282
+ host->rrdeng_ctx = &multidb_ctx;
1283
+#endif
1284
1285
failed:
1286
rc = sqlite3_finalize(res);
database/storage_engine.c
+47
-147
@@ -5,144 +5,68 @@
5
#ifdef ENABLE_DBENGINE
6
#include "engine/rrdengineapi.h"
7
#endif
8
-#include "libnetdata/libnetdata.h"
8
+
9
+#define im_collect_ops { \
10
+ .init = rrddim_collect_init,\
11
+ .store_metric = rrddim_collect_store_metric,\
12
+ .finalize = rrddim_collect_finalize\
13
+}
14
+
15
+#define im_query_ops { \
16
+ .init = rrddim_query_init, \
17
+ .next_metric = rrddim_query_next_metric, \
18
+ .is_finished = rrddim_query_is_finished, \
19
+ .finalize = rrddim_query_finalize, \
20
+ .latest_time = rrddim_query_latest_time, \
21
+ .oldest_time = rrddim_query_oldest_time \
22
+}
23
24
static STORAGE_ENGINE engines[] = {
25
{
26
.id = RRD_MEMORY_MODE_NONE,
27
.name = RRD_MEMORY_MODE_NONE_NAME,
28
.api = {
15
- .engine_ops = {
16
- .create = rrddim_storage_engine_instance_new,
17
- .exit = rrddim_storage_engine_instance_exit,
18
- .destroy = rrddim_storage_engine_instance_destroy
19
- },
20
- .collect_ops = {
21
- .init = rrddim_collect_init,
22
- .store_metric = rrddim_collect_store_metric,
23
- .finalize = rrddim_collect_finalize
24
- },
25
- .query_ops = {
26
- .init = rrddim_query_init,
27
- .next_metric = rrddim_query_next_metric,
28
- .is_finished = rrddim_query_is_finished,
29
- .finalize = rrddim_query_finalize,
30
- .latest_time = rrddim_query_latest_time,
31
- .oldest_time = rrddim_query_oldest_time
32
- }
33
- },
34
- .context = NULL
29
+ .collect_ops = im_collect_ops,
30
+ .query_ops = im_query_ops
31
+ }
32
},
33
{
34
.id = RRD_MEMORY_MODE_RAM,
35
.name = RRD_MEMORY_MODE_RAM_NAME,
36
.api = {
40
- .engine_ops = {
41
- .create = rrddim_storage_engine_instance_new,
42
- .exit = rrddim_storage_engine_instance_exit,
43
- .destroy = rrddim_storage_engine_instance_destroy
44
- },
45
- .collect_ops = {
46
- .init = rrddim_collect_init,
47
- .store_metric = rrddim_collect_store_metric,
48
- .finalize = rrddim_collect_finalize
49
- },
50
- .query_ops = {
51
- .init = rrddim_query_init,
52
- .next_metric = rrddim_query_next_metric,
53
- .is_finished = rrddim_query_is_finished,
54
- .finalize = rrddim_query_finalize,
55
- .latest_time = rrddim_query_latest_time,
56
- .oldest_time = rrddim_query_oldest_time
57
- }
58
- },
59
- .context = NULL
37
+ .collect_ops = im_collect_ops,
38
+ .query_ops = im_query_ops
39
+ }
40
},
41
{
42
.id = RRD_MEMORY_MODE_MAP,
43
.name = RRD_MEMORY_MODE_MAP_NAME,
44
.api = {
65
- .engine_ops = {
66
- .create = rrddim_storage_engine_instance_new,
67
- .exit = rrddim_storage_engine_instance_exit,
68
- .destroy = rrddim_storage_engine_instance_destroy
69
- },
70
- .collect_ops = {
71
- .init = rrddim_collect_init,
72
- .store_metric = rrddim_collect_store_metric,
73
- .finalize = rrddim_collect_finalize
74
- },
75
- .query_ops = {
76
- .init = rrddim_query_init,
77
- .next_metric = rrddim_query_next_metric,
78
- .is_finished = rrddim_query_is_finished,
79
- .finalize = rrddim_query_finalize,
80
- .latest_time = rrddim_query_latest_time,
81
- .oldest_time = rrddim_query_oldest_time
82
- }
83
- },
84
- .context = NULL
45
+ .collect_ops = im_collect_ops,
46
+ .query_ops = im_query_ops
47
+ }
48
},
49
{
50
.id = RRD_MEMORY_MODE_SAVE,
51
.name = RRD_MEMORY_MODE_SAVE_NAME,
52
.api = {
90
- .engine_ops = {
91
- .create = rrddim_storage_engine_instance_new,
92
- .exit = rrddim_storage_engine_instance_exit,
93
- .destroy = rrddim_storage_engine_instance_destroy
94
- },
95
- .collect_ops = {
96
- .init = rrddim_collect_init,
97
- .store_metric = rrddim_collect_store_metric,
98
- .finalize = rrddim_collect_finalize
99
- },
100
- .query_ops = {
101
- .init = rrddim_query_init,
102
- .next_metric = rrddim_query_next_metric,
103
- .is_finished = rrddim_query_is_finished,
104
- .finalize = rrddim_query_finalize,
105
- .latest_time = rrddim_query_latest_time,
106
- .oldest_time = rrddim_query_oldest_time
107
- }
108
- },
109
- .context = NULL
53
+ .collect_ops = im_collect_ops,
54
+ .query_ops = im_query_ops
55
+ }
56
},
57
{
58
.id = RRD_MEMORY_MODE_ALLOC,
59
.name = RRD_MEMORY_MODE_ALLOC_NAME,
60
.api = {
115
- .engine_ops = {
116
- .create = rrddim_storage_engine_instance_new,
117
- .exit = rrddim_storage_engine_instance_exit,
118
- .destroy = rrddim_storage_engine_instance_destroy
119
- },
120
- .collect_ops = {
121
- .init = rrddim_collect_init,
122
- .store_metric = rrddim_collect_store_metric,
123
- .finalize = rrddim_collect_finalize
124
- },
125
- .query_ops = {
126
- .init = rrddim_query_init,
127
- .next_metric = rrddim_query_next_metric,
128
- .is_finished = rrddim_query_is_finished,
129
- .finalize = rrddim_query_finalize,
130
- .latest_time = rrddim_query_latest_time,
131
- .oldest_time = rrddim_query_oldest_time
132
- }
133
- },
134
- .context = NULL
61
+ .collect_ops = im_collect_ops,
62
+ .query_ops = im_query_ops
63
+ }
64
},
65
#ifdef ENABLE_DBENGINE
66
{
67
.id = RRD_MEMORY_MODE_DBENGINE,
68
.name = RRD_MEMORY_MODE_DBENGINE_NAME,
69
.api = {
141
- .engine_ops = {
142
- .create = rrdeng_init,
143
- .exit = rrdeng_prepare_exit,
144
- .destroy = rrdeng_exit
145
- },
70
.collect_ops = {
71
.init = rrdeng_store_metric_init,
72
.store_metric = rrdeng_store_metric_next,
@@ -156,34 +80,28 @@ static STORAGE_ENGINE engines[] = {
80
.latest_time = rrdeng_metric_latest_time,
81
.oldest_time = rrdeng_metric_oldest_time
82
}
159
- },
160
- .context = NULL
161
- }
83
+ }
84
+ },
85
#endif
86
+ { .id = RRD_MEMORY_MODE_NONE, .name = NULL }
87
};
88
165
-const size_t engine_count = sizeof(engines) / sizeof(engines[0]);
166
-
89
STORAGE_ENGINE* storage_engine_find(const char* name)
90
{
169
- for (size_t i = 0; i != engine_count; i++)
170
- if (strcmp(engines[i].name, name) == 0)
171
- return &engines[i];
172
-
173
- error("No storage engine found for memory mode %s.", name);
174
- return storage_engine_get(default_rrd_memory_mode);
91
+ for (STORAGE_ENGINE* it = engines; it->name; it++) {
92
+ if (strcmp(it->name, name) == 0)
93
+ return it;
94
+ }
95
+ return NULL;
96
}
97
98
STORAGE_ENGINE* storage_engine_get(RRD_MEMORY_MODE mmode)
99
{
179
- for (size_t i = 0; i != engine_count; i++)
180
- if (engines[i].id == mmode)
181
- return &engines[i];
182
- STORAGE_ENGINE* eng = mmode == default_rrd_memory_mode
183
- ? &engines[0] // default engine not available, use NONE
184
- : storage_engine_get(default_rrd_memory_mode);
185
- error("No storage engine for memory mode %u, will use %s (%u) instead.", mmode, eng->name, eng->id);
186
- return eng;
100
+ for (STORAGE_ENGINE* it = engines; it->name; it++) {
101
+ if (it->id == mmode)
102
+ return it;
103
+ }
104
+ return NULL;
105
}
106
107
STORAGE_ENGINE* storage_engine_foreach_init()
@@ -194,27 +112,9 @@ STORAGE_ENGINE* storage_engine_foreach_init()
112
113
STORAGE_ENGINE* storage_engine_foreach_next(STORAGE_ENGINE* it)
114
{
197
- it++;
198
- return (it >= &engines[engine_count]) ? NULL : it;
199
-}
115
+ if (!it || !it->name)
116
+ return NULL;
117
201
-STORAGE_ENGINE_INSTANCE* storage_engine_new(STORAGE_ENGINE* eng, RRDHOST *host)
202
-{
203
- STORAGE_ENGINE_INSTANCE* instance = host->rrdeng_ctx;
204
- if (!instance && eng) {
205
- instance = eng->api.engine_ops.create(eng, host);
206
- if (instance) {
207
- instance->engine = eng;
208
- }
209
- }
210
- return instance;
211
-}
212
-
213
-void storage_engine_delete(STORAGE_ENGINE_INSTANCE* instance) {
214
- if (instance) {
215
- STORAGE_ENGINE* eng = instance->engine;
216
- if (eng) {
217
- eng->api.engine_ops.destroy(instance);
218
- }
219
- }
118
+ it++;
119
+ return it->name ? it : NULL;
120
}
database/storage_engine.h
-21
@@ -6,20 +6,10 @@
6
#include "rrd.h"
7
8
typedef struct storage_engine STORAGE_ENGINE;
9
-typedef struct storage_engine_instance STORAGE_ENGINE_INSTANCE;
10
-
11
-// ------------------------------------------------------------------------
12
-// function pointers that handle storage engine instance creation and destruction
13
-struct storage_engine_ops {
14
- STORAGE_ENGINE_INSTANCE*(*create)(STORAGE_ENGINE* engine, RRDHOST *host);
15
- void(*exit)(STORAGE_ENGINE_INSTANCE*);
16
- void(*destroy)(STORAGE_ENGINE_INSTANCE*);
17
-};
9
10
// ------------------------------------------------------------------------
11
// function pointers for all APIs provided by a storge engine
12
typedef struct storage_engine_api {
22
- struct storage_engine_ops engine_ops;
13
struct rrddim_collect_ops collect_ops;
14
struct rrddim_query_ops query_ops;
15
} STORAGE_ENGINE_API;
@@ -28,12 +18,6 @@ struct storage_engine {
18
RRD_MEMORY_MODE id;
19
const char* name;
20
STORAGE_ENGINE_API api;
31
- STORAGE_ENGINE_INSTANCE* context;
32
-};
33
-
34
-// Abstract structure to be extended by implementations
35
-struct storage_engine_instance {
36
- STORAGE_ENGINE* engine;
21
};
22
23
extern STORAGE_ENGINE* storage_engine_get(RRD_MEMORY_MODE mmode);
@@ -43,9 +27,4 @@ extern STORAGE_ENGINE* storage_engine_find(const char* name);
27
extern STORAGE_ENGINE* storage_engine_foreach_init();
28
extern STORAGE_ENGINE* storage_engine_foreach_next(STORAGE_ENGINE* it);
29
46
-// ------------------------------------------------------------------------
47
-// Retreive or create a storage engine instance for host
48
-STORAGE_ENGINE_INSTANCE* storage_engine_new(STORAGE_ENGINE* engine, RRDHOST *host);
49
-void storage_engine_delete(STORAGE_ENGINE_INSTANCE* engine);
50
-
30
#endif
web/api/queries/query.c
-3
@@ -4,9 +4,6 @@
4
#include "web/api/formatters/rrd2json.h"
5
#include "rrdr.h"
6
#include "database/ram/rrddim_mem.h"
7
-#ifdef ENABLE_DBENGINE
8
-#include "database/engine/rrdengine.h"
9
-#endif
7
8
#include "average/average.h"
9
#include "incremental_sum/incremental_sum.h"