summaryrefslogtreecommitdiffstats
path: root/database
diff options
context:
space:
mode:
authorCosta Tsaousis <costa@netdata.cloud>2022-08-31 10:04:14 +0300
committerGitHub <noreply@github.com>2022-08-31 10:04:14 +0300
commit77b0e7bccd7666ad6df609051a2736aec29e2d39 (patch)
treea0933be2982e4d9dea590069a1c838e252690f25 /database
parentc9620ca3ed6af773216356ea91fd0140c7e2725a (diff)
sqlite3 global statistics (#13594)
Diffstat (limited to 'database')
-rw-r--r--database/sqlite/sqlite_aclk.c12
-rw-r--r--database/sqlite/sqlite_aclk_alert.c14
-rw-r--r--database/sqlite/sqlite_aclk_chart.c28
-rw-r--r--database/sqlite/sqlite_context.c8
-rw-r--r--database/sqlite/sqlite_db_migration.c10
-rw-r--r--database/sqlite/sqlite_functions.c81
-rw-r--r--database/sqlite/sqlite_functions.h9
-rw-r--r--database/sqlite/sqlite_health.c12
8 files changed, 104 insertions, 70 deletions
diff --git a/database/sqlite/sqlite_aclk.c b/database/sqlite/sqlite_aclk.c
index ac7112a09a..941e302f74 100644
--- a/database/sqlite/sqlite_aclk.c
+++ b/database/sqlite/sqlite_aclk.c
@@ -361,7 +361,7 @@ void sql_aclk_sync_init(void)
for (int i = 0; aclk_sync_config[i]; i++) {
debug(D_ACLK_SYNC, "Executing %s", aclk_sync_config[i]);
- rc = sqlite3_exec(db_meta, aclk_sync_config[i], 0, 0, &err_msg);
+ rc = sqlite3_exec_monitored(db_meta, aclk_sync_config[i], 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error_report("SQLite error aclk sync initialization setup, rc = %d (%s)", rc, err_msg);
error_report("SQLite failed statement %s", aclk_sync_config[i]);
@@ -373,7 +373,7 @@ void sql_aclk_sync_init(void)
fatal_assert(0 == uv_mutex_init(&aclk_async_lock));
if (likely(rrdcontext_enabled == CONFIG_BOOLEAN_YES)) {
- rc = sqlite3_exec(db_meta, "SELECT host_id, hostname, registry_hostname, update_every, os, "
+ rc = sqlite3_exec_monitored(db_meta, "SELECT host_id, hostname, registry_hostname, update_every, os, "
"timezone, tags, hops, memory_mode, abbrev_timezone, utc_offset, program_name, "
"program_version, entries, health_enabled FROM host WHERE hops >0;",
create_host_callback, NULL, &err_msg);
@@ -383,7 +383,7 @@ void sql_aclk_sync_init(void)
}
}
- rc = sqlite3_exec(db_meta, "SELECT ni.host_id, ni.node_id FROM host h, node_instance ni WHERE "
+ rc = sqlite3_exec_monitored(db_meta, "SELECT ni.host_id, ni.node_id FROM host h, node_instance ni WHERE "
"h.host_id = ni.host_id AND ni.node_id IS NOT NULL;", aclk_start_sync_thread, NULL, &err_msg);
if (rc != SQLITE_OK) {
error_report("SQLite error when starting ACLK sync threads, rc = %d (%s)", rc, err_msg);
@@ -927,7 +927,7 @@ static int is_host_available(uuid_t *host_id)
error_report("Failed to bind host_id parameter to select node instance information");
goto failed;
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
failed:
if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
@@ -980,7 +980,7 @@ void sql_delete_aclk_table_list(struct aclk_database_worker_config *wc, struct a
}
buffer_flush(sql);
- while (sqlite3_step(res) == SQLITE_ROW)
+ while (sqlite3_step_monitored(res) == SQLITE_ROW)
buffer_strcat(sql, (char *) sqlite3_column_text(res, 0));
rc = sqlite3_finalize(res);
@@ -1016,7 +1016,7 @@ void sql_check_aclk_table_list(struct aclk_database_worker_config *wc)
{
char *err_msg = NULL;
debug(D_ACLK_SYNC,"Cleaning tables for nodes that do not exist");
- int rc = sqlite3_exec(db_meta, SQL_SELECT_ACLK_ACTIVE_LIST, sql_check_aclk_table, (void *) wc, &err_msg);
+ int rc = sqlite3_exec_monitored(db_meta, SQL_SELECT_ACLK_ACTIVE_LIST, sql_check_aclk_table, (void *) wc, &err_msg);
if (rc != SQLITE_OK) {
error_report("Query failed when trying to check for obsolete ACLK sync tables, %s", err_msg);
sqlite3_free(err_msg);
diff --git a/database/sqlite/sqlite_aclk_alert.c b/database/sqlite/sqlite_aclk_alert.c
index ea1cc9feab..c95b98f263 100644
--- a/database/sqlite/sqlite_aclk_alert.c
+++ b/database/sqlite/sqlite_aclk_alert.c
@@ -24,7 +24,7 @@ time_t removed_when(uint32_t alarm_id, uint32_t before_unique_id, uint32_t after
return 0;
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (likely(rc == SQLITE_ROW)) {
when = (time_t) sqlite3_column_int64(res, 0);
}
@@ -70,7 +70,7 @@ int should_send_to_cloud(RRDHOST *host, ALARM_ENTRY *ae)
return send;
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (likely(rc == SQLITE_ROW)) {
status = (RRDCALC_STATUS) sqlite3_column_int(res, 0);
if (sqlite3_column_type(res, 1) != SQLITE_NULL)
@@ -280,7 +280,7 @@ void aclk_push_alert_event(struct aclk_database_worker_config *wc, struct aclk_d
static __thread uint64_t log_first_sequence_id = 0;
static __thread uint64_t log_last_sequence_id = 0;
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
struct alarm_log_entry alarm_log;
char old_value_string[100 + 1];
char new_value_string[100 + 1];
@@ -500,7 +500,7 @@ void aclk_push_alarm_health_log(struct aclk_database_worker_config *wc, struct a
last_timestamp.tv_sec = 0;
last_timestamp.tv_usec = 0;
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
first_sequence = sqlite3_column_bytes(res, 0) > 0 ? (uint64_t) sqlite3_column_int64(res, 0) : 0;
if (sqlite3_column_bytes(res, 1) > 0) {
first_timestamp.tv_sec = sqlite3_column_int64(res, 1);
@@ -603,7 +603,7 @@ int aclk_push_alert_config_event(struct aclk_database_worker_config *wc, struct
struct provide_alarm_configuration p_alarm_config;
p_alarm_config.cfg_hash = NULL;
- if (sqlite3_step(res) == SQLITE_ROW) {
+ if (sqlite3_step_monitored(res) == SQLITE_ROW) {
alarm_config.alarm = sqlite3_column_bytes(res, 0) > 0 ? strdupz((char *)sqlite3_column_text(res, 0)) : NULL;
alarm_config.tmpl = sqlite3_column_bytes(res, 1) > 0 ? strdupz((char *)sqlite3_column_text(res, 1)) : NULL;
@@ -1029,7 +1029,7 @@ void sql_aclk_alert_clean_dead_entries(RRDHOST *host)
" (select unique_id from health_log_%s); ", uuid_str, uuid_str);
char *err_msg = NULL;
- int rc = sqlite3_exec(db_meta, buffer_tostring(sql), NULL, NULL, &err_msg);
+ int rc = sqlite3_exec_monitored(db_meta, buffer_tostring(sql), NULL, NULL, &err_msg);
if (rc != SQLITE_OK) {
error_report("Failed when trying to clean stale ACLK alert entries from aclk_alert_%s, error message \"%s""",
uuid_str, err_msg);
@@ -1064,7 +1064,7 @@ int get_proto_alert_status(RRDHOST *host, struct proto_alert_status *proto_alert
return 1;
}
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
proto_alert_status->pending_min_sequence_id = sqlite3_column_bytes(res, 0) > 0 ? (uint64_t) sqlite3_column_int64(res, 0) : 0;
proto_alert_status->pending_max_sequence_id = sqlite3_column_bytes(res, 1) > 0 ? (uint64_t) sqlite3_column_int64(res, 1) : 0;
proto_alert_status->last_acked_sequence_id = sqlite3_column_bytes(res, 2) > 0 ? (uint64_t) sqlite3_column_int64(res, 2) : 0;
diff --git a/database/sqlite/sqlite_aclk_chart.c b/database/sqlite/sqlite_aclk_chart.c
index c1db60c493..0d9b9cda06 100644
--- a/database/sqlite/sqlite_aclk_chart.c
+++ b/database/sqlite/sqlite_aclk_chart.c
@@ -48,7 +48,7 @@ static time_t payload_sent(char *uuid_str, uuid_t *uuid, void *payload, size_t p
if (unlikely(rc != SQLITE_OK))
goto bind_fail;
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
send_status = (time_t) sqlite3_column_int64(res, 0);
}
@@ -245,7 +245,7 @@ void aclk_process_dimension_deletion(struct aclk_database_worker_config *wc, str
goto bind_fail;
unsigned count = 0;
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
(void) aclk_upd_dimension_event(
wc,
claim_id,
@@ -357,7 +357,7 @@ void aclk_send_chart_event(struct aclk_database_worker_config *wc, struct aclk_d
int count = 0;
first_sequence = 0;
last_sequence = 0;
- while (count < limit && sqlite3_step(res) == SQLITE_ROW) {
+ while (count < limit && sqlite3_step_monitored(res) == SQLITE_ROW) {
size_t payload_size = sqlite3_column_bytes(res, 1);
if (payload_list_max_size[count] < payload_size) {
freez(payload_list[count]);
@@ -487,7 +487,7 @@ int aclk_send_chart_config(struct aclk_database_worker_config *wc, struct aclk_d
struct chart_config_updated chart_config;
chart_config.config_hash = NULL;
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
chart_config.type = strdupz((char *)sqlite3_column_text(res, 0));
chart_config.family = strdupz((char *)sqlite3_column_text(res, 1));
chart_config.context = strdupz((char *)sqlite3_column_text(res, 2));
@@ -799,7 +799,7 @@ static RRD_MEMORY_MODE sql_get_host_memory_mode(uuid_t *host_id)
goto failed;
}
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
memory_mode = (RRD_MEMORY_MODE)sqlite3_column_int(res, 0);
}
@@ -891,7 +891,7 @@ void aclk_update_retention(struct aclk_database_worker_config *wc)
rotate_data.node_id = strdupz(wc->node_id);
time_t now = now_realtime_sec();
- while (sqlite3_step(res) == SQLITE_ROW && dimension_update_count < ACLK_MAX_DIMENSION_CLEANUP) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW && dimension_update_count < ACLK_MAX_DIMENSION_CLEANUP) {
if (unlikely(netdata_exit))
break;
if (!update_every || update_every != (uint32_t)sqlite3_column_int(res, 1)) {
@@ -1022,7 +1022,7 @@ uint32_t sql_get_pending_count(struct aclk_database_worker_config *wc)
return 0;
}
}
- while (sqlite3_step(res) == SQLITE_ROW)
+ while (sqlite3_step_monitored(res) == SQLITE_ROW)
chart_payload_count = (uint32_t) sqlite3_column_int(res, 0);
rc = sqlite3_reset(res);
@@ -1049,7 +1049,7 @@ void sql_get_last_chart_sequence(struct aclk_database_worker_config *wc)
wc->chart_sequence_id = 0;
wc->chart_timestamp = 0;
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
wc->chart_sequence_id = (uint64_t)sqlite3_column_int64(res, 0);
wc->chart_timestamp = (time_t)sqlite3_column_int64(res, 1);
}
@@ -1220,37 +1220,37 @@ struct aclk_chart_sync_stats *aclk_get_chart_sync_stats(RRDHOST *host)
return NULL;
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (rc == SQLITE_ROW) {
aclk_statistics->min_seqid = SQL_SEQ_NULL(res, 0);
aclk_statistics->max_seqid = SQL_SEQ_NULL(res, 1);
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (rc == SQLITE_ROW) {
aclk_statistics->min_seqid_pend = SQL_SEQ_NULL(res, 0);
aclk_statistics->max_seqid_pend = SQL_SEQ_NULL(res, 1);
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (rc == SQLITE_ROW) {
aclk_statistics->min_seqid_sent = SQL_SEQ_NULL(res, 0);
aclk_statistics->max_seqid_sent = SQL_SEQ_NULL(res, 1);
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (rc == SQLITE_ROW) {
aclk_statistics->min_seqid_ack = SQL_SEQ_NULL(res, 0);
aclk_statistics->max_seqid_ack = SQL_SEQ_NULL(res, 1);
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (rc == SQLITE_ROW) {
aclk_statistics->min_seqid_ack = SQL_SEQ_NULL(res, 0);
aclk_statistics->max_seqid_ack = SQL_SEQ_NULL(res, 1);
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (rc == SQLITE_ROW) {
aclk_statistics->max_date_created = (time_t) SQL_SEQ_NULL(res, 0);
aclk_statistics->max_date_submitted = (time_t) SQL_SEQ_NULL(res, 1);
diff --git a/database/sqlite/sqlite_context.c b/database/sqlite/sqlite_context.c
index 901ab00319..a4d1668577 100644
--- a/database/sqlite/sqlite_context.c
+++ b/database/sqlite/sqlite_context.c
@@ -150,7 +150,7 @@ void ctx_get_chart_list(uuid_t *host_uuid, void (*dict_cb)(SQL_CHART_DATA *, voi
}
SQL_CHART_DATA chart_data = { 0 };
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
uuid_copy(chart_data.chart_id, *((uuid_t *)sqlite3_column_blob(res, 0)));
chart_data.id = (char *) sqlite3_column_text(res, 1);
chart_data.name = (char *) sqlite3_column_text(res, 2);
@@ -191,7 +191,7 @@ void ctx_get_dimension_list(uuid_t *chart_uuid, void (*dict_cb)(SQL_DIMENSION_DA
SQL_DIMENSION_DATA dimension_data;
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
uuid_copy(dimension_data.dim_id, *((uuid_t *)sqlite3_column_blob(res, 0)));
dimension_data.id = (char *) sqlite3_column_text(res, 1);
dimension_data.name = (char *) sqlite3_column_text(res, 2);
@@ -225,7 +225,7 @@ void ctx_get_label_list(uuid_t *chart_uuid, void (*dict_cb)(SQL_CLABEL_DATA *, v
SQL_CLABEL_DATA label_data;
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
label_data.label_key = (char *) sqlite3_column_text(res, 0);
label_data.label_value = (char *) sqlite3_column_text(res, 1);
label_data.label_source = sqlite3_column_int(res, 2);
@@ -267,7 +267,7 @@ void ctx_get_context_list(uuid_t *host_uuid, void (*dict_cb)(VERSIONED_CONTEXT_D
goto failed;
}
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
context_data.id = (char *) sqlite3_column_text(res, 0);
context_data.version = sqlite3_column_int64(res, 1);
context_data.title = (char *) sqlite3_column_text(res, 2);
diff --git a/database/sqlite/sqlite_db_migration.c b/database/sqlite/sqlite_db_migration.c
index bd47433649..7b2b16da4f 100644
--- a/database/sqlite/sqlite_db_migration.c
+++ b/database/sqlite/sqlite_db_migration.c
@@ -21,7 +21,7 @@ static int table_exists_in_database(const char *table)
snprintf(sql, 127, "select 1 from sqlite_schema where type = 'table' and name = '%s';", table);
- int rc = sqlite3_exec(db_meta, sql, return_int_cb, (void *) &exists, &err_msg);
+ int rc = sqlite3_exec_monitored(db_meta, sql, return_int_cb, (void *) &exists, &err_msg);
if (rc != SQLITE_OK) {
info("Error checking table existence; %s", err_msg);
sqlite3_free(err_msg);
@@ -39,7 +39,7 @@ static int column_exists_in_table(const char *table, const char *column)
snprintf(sql, 127, "SELECT 1 FROM pragma_table_info('%s') where name = '%s';", table, column);
- int rc = sqlite3_exec(db_meta, sql, return_int_cb, (void *) &exists, &err_msg);
+ int rc = sqlite3_exec_monitored(db_meta, sql, return_int_cb, (void *) &exists, &err_msg);
if (rc != SQLITE_OK) {
info("Error checking column existence; %s", err_msg);
sqlite3_free(err_msg);
@@ -100,11 +100,11 @@ static int do_migration_v3_v4(sqlite3 *database, const char *name)
return 1;
}
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
char *table = strdupz((char *) sqlite3_column_text(res, 0));
if (!column_exists_in_table(table, "chart_context")) {
snprintfz(sql, 255, "ALTER TABLE %s ADD chart_context text", table);
- sqlite3_exec(database, sql, 0, 0, NULL);
+ sqlite3_exec_monitored(database, sql, 0, 0, NULL);
}
freez(table);
}
@@ -135,7 +135,7 @@ static int migrate_database(sqlite3 *database, int target_version, char *db_name
int user_version = 0;
char *err_msg = NULL;
- int rc = sqlite3_exec(database, "PRAGMA user_version;", return_int_cb, (void *) &user_version, &err_msg);
+ int rc = sqlite3_exec_monitored(database, "PRAGMA user_version;", return_int_cb, (void *) &user_version, &err_msg);
if (rc != SQLITE_OK) {
info("Error checking the %s database version; %s", db_name, err_msg);
sqlite3_free(err_msg);
diff --git a/database/sqlite/sqlite_functions.c b/database/sqlite/sqlite_functions.c
index f46450afa8..e0e9b26d37 100644
--- a/database/sqlite/sqlite_functions.c
+++ b/database/sqlite/sqlite_functions.c
@@ -88,11 +88,35 @@ pthread_key_t key_pool[MAX_PREPARED_STATEMENTS];
static uv_mutex_t sqlite_transaction_lock;
+
+SQLITE_API int sqlite3_exec_monitored(
+ sqlite3 *db, /* An open database */
+ const char *sql, /* SQL to be evaluated */
+ int (*callback)(void*,int,char**,char**), /* Callback function */
+ void *data, /* 1st argument to callback */
+ char **errmsg /* Error msg written here */
+) {
+ int rc = sqlite3_exec(db, sql, callback, data, errmsg);
+ sqlite3_query_completed(rc == SQLITE_OK, rc == SQLITE_BUSY, rc == SQLITE_LOCKED);
+ return rc;
+}
+
+SQLITE_API int sqlite3_step_monitored(sqlite3_stmt *stmt) {
+ int rc = sqlite3_step(stmt);
+
+ if(likely(rc == SQLITE_ROW))
+ sqlite3_row_completed();
+ else
+ sqlite3_query_completed(rc == SQLITE_DONE, rc == SQLITE_BUSY, rc == SQLITE_LOCKED);
+
+ return rc;
+}
+
int execute_insert(sqlite3_stmt *res)
{
int rc;
int cnt = 0;
- while ((rc = sqlite3_step(res)) != SQLITE_DONE && ++cnt < SQL_MAX_RETRY && likely(!netdata_exit)) {
+ while ((rc = sqlite3_step_monitored(res)) != SQLITE_DONE && ++cnt < SQL_MAX_RETRY && likely(!netdata_exit)) {
if (likely(rc == SQLITE_BUSY || rc == SQLITE_LOCKED)) {
usleep(SQLITE_INSERT_DELAY * USEC_PER_MS);
error_report("Failed to insert/update, rc = %d -- attempt %d", rc, cnt);
@@ -273,7 +297,7 @@ static int check_table_integrity(char *table)
strcpy(wstr,"PRAGMA integrity_check;");
}
- int rc = sqlite3_exec(db_meta, wstr, check_table_integrity_cb, (void *) &status, &err_msg);
+ int rc = sqlite3_exec_monitored(db_meta, wstr, check_table_integrity_cb, (void *) &status, &err_msg);
if (rc != SQLITE_OK) {
error_report("SQLite error during database integrity check for %s, rc = %d (%s)",
table ? table : "the entire database", rc, err_msg);
@@ -306,7 +330,7 @@ static void rebuild_chart()
info("Rebuilding chart table");
for (int i = 0; rebuild_chart_commands[i]; i++) {
info("Executing %s", rebuild_chart_commands[i]);
- rc = sqlite3_exec(db_meta, rebuild_chart_commands[i], 0, 0, &err_msg);
+ rc = sqlite3_exec_monitored(db_meta, rebuild_chart_commands[i], 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error_report("SQLite error during database setup, rc = %d (%s)", rc, err_msg);
error_report("SQLite failed statement %s", rebuild_chart_commands[i]);
@@ -339,7 +363,7 @@ void rebuild_dimension()
info("Rebuilding dimension table");
for (int i = 0; rebuild_dimension_commands[i]; i++) {
info("Executing %s", rebuild_dimension_commands[i]);
- rc = sqlite3_exec(db_meta, rebuild_dimension_commands[i], 0, 0, &err_msg);
+ rc = sqlite3_exec_monitored(db_meta, rebuild_dimension_commands[i], 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error_report("SQLite error during database setup, rc = %d (%s)", rc, err_msg);
error_report("SQLite failed statement %s", rebuild_dimension_commands[i]);
@@ -366,7 +390,7 @@ int init_database_batch(sqlite3 *database, int rebuild, int init_type, const cha
char *err_msg = NULL;
for (int i = 0; batch[i]; i++) {
debug(D_METADATALOG, "Executing %s", batch[i]);
- rc = sqlite3_exec(database, batch[i], 0, 0, &err_msg);
+ rc = sqlite3_exec_monitored(database, batch[i], 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error_report("SQLite error during database %s, rc = %d (%s)", init_type ? "cleanup" : "setup", rc, err_msg);
error_report("SQLite failed statement %s", batch[i]);
@@ -437,7 +461,7 @@ int sql_init_database(db_check_action_type_t rebuild, int memory)
if (rebuild & DB_CHECK_RECLAIM_SPACE) {
if (!(rebuild & DB_CHECK_CONT))
info("Reclaiming space of %s", sqlite_database);
- rc = sqlite3_exec(db_meta, "VACUUM;", 0, 0, &err_msg);
+ rc = sqlite3_exec_monitored(db_meta, "VACUUM;", 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error_report("Failed to execute VACUUM rc = %d (%s)", rc, err_msg);
sqlite3_free(err_msg);
@@ -546,7 +570,7 @@ int find_uuid_type(uuid_t *uuid)
if (unlikely(rc != SQLITE_OK))
goto bind_fail;
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (likely(rc == SQLITE_ROW))
uuid_type = sqlite3_column_int(res, 0);
@@ -589,7 +613,7 @@ int find_dimension_uuid(RRDSET *st, RRDDIM *rd, uuid_t *store_uuid)
if (unlikely(rc != SQLITE_OK))
goto bind_fail;
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (likely(rc == SQLITE_ROW)) {
uuid_copy(*store_uuid, *((uuid_t *) sqlite3_column_blob(res, 0)));
status = 0;
@@ -636,7 +660,7 @@ void delete_dimension_uuid(uuid_t *dimension_uuid)
if (unlikely(rc != SQLITE_OK))
goto bind_fail;
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (unlikely(rc != SQLITE_DONE))
error_report("Failed to delete dimension uuid, rc = %d", rc);
@@ -684,7 +708,7 @@ uuid_t *find_chart_uuid(RRDHOST *host, const char *type, const char *id, const c
if (unlikely(rc != SQLITE_OK))
goto bind_fail;
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (likely(rc == SQLITE_ROW)) {
uuid = mallocz(sizeof(uuid_t));
uuid_copy(*uuid, sqlite3_column_blob(res, 0));
@@ -847,7 +871,7 @@ int sql_store_host(
if (unlikely(rc != SQLITE_OK))
goto bind_fail;
- int store_rc = sqlite3_step(res);
+ int store_rc = sqlite3_step_monitored(res);
if (unlikely(store_rc != SQLITE_DONE))
error_report("Failed to store host %s, rc = %d", hostname, rc);
@@ -954,7 +978,7 @@ int sql_store_host_info(RRDHOST *host)
if (unlikely(rc != SQLITE_OK))
goto bind_fail;
- int store_rc = sqlite3_step(res);
+ int store_rc = sqlite3_step_monitored(res);
if (unlikely(store_rc != SQLITE_DONE))
error_report("Failed to store host %s, rc = %d", host->hostname, rc);
@@ -1229,7 +1253,7 @@ void sql_rrdim2json(sqlite3_stmt *res_dim, uuid_t *chart_uuid, BUFFER *wb, size_
int dimensions = 0;
buffer_sprintf(wb, "\t\t\t\"dimensions\": {\n");
- while (sqlite3_step(res_dim) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res_dim) == SQLITE_ROW) {
if (dimensions)
buffer_strcat(wb, ",\n\t\t\t\t\"");
else
@@ -1305,7 +1329,7 @@ void sql_rrdset2json(RRDHOST *host, BUFFER *wb)
size_t c = 0;
size_t dimensions = 0;
- while (sqlite3_step(res_chart) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res_chart) == SQLITE_ROW) {
char id[512];
sprintf(id, "%s.%s", sqlite3_column_text(res_chart, 3), sqlite3_column_text(res_chart, 1));
RRDSET *st = rrdset_find(host, id);
@@ -1471,7 +1495,7 @@ RRDHOST *sql_create_host_by_uuid(char *hostname)
}
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (unlikely(rc != SQLITE_ROW)) {
error_report("Failed to find hostname %s", hostname);
goto failed;
@@ -1511,20 +1535,21 @@ void db_execute(const char *cmd)
int cnt = 0;
while (cnt < SQL_MAX_RETRY) {
char *err_msg;
- rc = sqlite3_exec(db_meta, cmd, 0, 0, &err_msg);
+ rc = sqlite3_exec_monitored(db_meta, cmd, 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error_report("Failed to execute '%s', rc = %d (%s) -- attempt %d", cmd, rc, err_msg, cnt);
sqlite3_free(err_msg);
if (likely(rc == SQLITE_BUSY || rc == SQLITE_LOCKED)) {
usleep(SQLITE_INSERT_DELAY * USEC_PER_MS);
}
- else break;
+ else
+ break;
}
else
break;
+
++cnt;
}
- return;
}
void db_lock(void)
@@ -1559,7 +1584,7 @@ int file_is_migrated(char *path)
return 0;
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (unlikely(sqlite3_finalize(res) != SQLITE_OK))
error_report("Failed to finalize the prepared statement when checking if metadata file is migrated");
@@ -1838,7 +1863,7 @@ void sql_build_context_param_list(ONEWAYALLOC *owa, struct context_param **para
uuid_t rrdeng_uuid;
uuid_t chart_id;
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
char id[512];
sprintf(id, "%s.%s", sqlite3_column_text(res, 3), sqlite3_column_text(res, 1));
@@ -2242,7 +2267,7 @@ char *get_hostname_by_node_id(char *node)
goto failed;
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (likely(rc == SQLITE_ROW))
hostname = strdupz((char *)sqlite3_column_text(res, 0));
@@ -2280,7 +2305,7 @@ int get_host_id(uuid_t *node_id, uuid_t *host_id)
goto failed;
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (likely(rc == SQLITE_ROW && host_id))
uuid_copy(*host_id, *((uuid_t *) sqlite3_column_blob(res, 0)));
@@ -2316,7 +2341,7 @@ int get_node_id(uuid_t *host_id, uuid_t *node_id)
goto failed;
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (likely(rc == SQLITE_ROW && node_id))
uuid_copy(*node_id, *((uuid_t *) sqlite3_column_blob(res, 0)));
@@ -2395,7 +2420,7 @@ struct node_instance_list *get_node_list(void)
int row = 0;
char host_guid[37];
- while (sqlite3_step(res) == SQLITE_ROW)
+ while (sqlite3_step_monitored(res) == SQLITE_ROW)
row++;
if (sqlite3_reset(res) != SQLITE_OK) {
@@ -2406,7 +2431,7 @@ struct node_instance_list *get_node_list(void)
int max_rows = row;
row = 0;
rrd_rdlock();
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
if (sqlite3_column_bytes(res, 0) == sizeof(uuid_t))
uuid_copy(node_list[row].node_id, *((uuid_t *)sqlite3_column_blob(res, 0)));
if (sqlite3_column_bytes(res, 1) == sizeof(uuid_t)) {
@@ -2461,7 +2486,7 @@ void sql_load_node_id(RRDHOST *host)
goto failed;
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (likely(rc == SQLITE_ROW)) {
if (likely(sqlite3_column_bytes(res, 0) == sizeof(uuid_t)))
set_host_node_id(host, (uuid_t *)sqlite3_column_blob(res, 0));
@@ -2497,7 +2522,7 @@ void sql_build_host_system_info(uuid_t *host_id, struct rrdhost_system_info *sys
goto skip_loading;
}
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
rrdhost_set_system_info_variable(system_info, (char *) sqlite3_column_text(res, 0),
(char *) sqlite3_column_text(res, 1));
}
@@ -2681,7 +2706,7 @@ DICTIONARY *sql_load_host_labels(uuid_t *host_id)
labels = rrdlabels_create();
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
rrdlabels_add(
labels,
(const char *)sqlite3_column_text(res, 0),
diff --git a/database/sqlite/sqlite_functions.h b/database/sqlite/sqlite_functions.h
index e6808aa81f..94e8ec7ec9 100644
--- a/database/sqlite/sqlite_functions.h
+++ b/database/sqlite/sqlite_functions.h
@@ -58,6 +58,15 @@ typedef enum db_check_action_type {
return 1; \
}
+extern SQLITE_API int sqlite3_step_monitored(sqlite3_stmt *stmt);
+extern SQLITE_API int sqlite3_exec_monitored(
+ sqlite3 *db, /* An open database */
+ const char *sql, /* SQL to be evaluated */
+ int (*callback)(void*,int,char**,char**), /* Callback function */
+ void *data, /* 1st argument to callback */
+ char **errmsg /* Error msg written here */
+ );
+
extern int sql_init_database(db_check_action_type_t rebuild, int memory);
extern void sql_close_database(void);
extern int bind_text_null(sqlite3_stmt *res, int position, const char *text, bool can_be_null);
diff --git a/database/sqlite/sqlite_health.c b/database/sqlite/sqlite_health.c
index 8e59cad1ec..1eb5c05b02 100644
--- a/database/sqlite/sqlite_health.c
+++ b/database/sqlite/sqlite_health.c
@@ -24,7 +24,7 @@ int sql_create_health_log_table(RRDHOST *host) {
snprintfz(command, MAX_HEALTH_SQL_SIZE, SQL_CREATE_HEALTH_LOG_TABLE(uuid_str));
- rc = sqlite3_exec(db_meta, command, 0, 0, &err_msg);
+ rc = sqlite3_exec_monitored(db_meta, command, 0, 0, &err_msg);
if (rc != SQLITE_OK) {
error_report("HEALTH [%s]: SQLite error during creation of health log table, rc = %d (%s)", host->hostname, rc, err_msg);
sqlite3_free(err_msg);
@@ -389,7 +389,7 @@ void sql_health_alarm_log_cleanup(RRDHOST *host) {
return;
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (unlikely(rc != SQLITE_DONE))
error_report("Failed to cleanup health log table, rc = %d", rc);
@@ -428,7 +428,7 @@ void sql_health_alarm_log_count(RRDHOST *host) {
return;
}
- rc = sqlite3_step(res);
+ rc = sqlite3_step_monitored(res);
if (likely(rc == SQLITE_ROW))
host->health_log_entries_written = (size_t) sqlite3_column_int64(res, 0);
@@ -556,7 +556,7 @@ uint32_t sql_get_max_unique_id (char *uuid_str)
return 0;
}
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
max_unique_id = (uint32_t) sqlite3_column_int64(res, 0);
}
@@ -584,7 +584,7 @@ void sql_check_removed_alerts_state(char *uuid_str)
return;
}
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
status = (RRDCALC_STATUS) sqlite3_column_int(res, 0);
unique_id = (uint32_t) sqlite3_column_int64(res, 1);
alarm_id = (uint32_t) sqlite3_column_int64(res, 2);
@@ -634,7 +634,7 @@ void sql_health_alarm_log_load(RRDHOST *host) {
netdata_rwlock_rdlock(&host->health_log.alarm_log_rwlock);
- while (sqlite3_step(res) == SQLITE_ROW) {
+ while (sqlite3_step_monitored(res) == SQLITE_ROW) {
ALARM_ENTRY *ae = NULL;
// check that we have valid ids