master
c 562 lines 18.8 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "sqlite_functions.h"
4
5 #define MAX_PREPARED_THREAD_STATEMENTS (32)
6
7 static SPINLOCK JudyL_thread_stmt_lock = SPINLOCK_INITIALIZER;
8 static Pvoid_t JudyL_thread_stmt_pool = NULL;
9
10 struct stmt_pool_s {
11 int count;
12 pid_t thread_id;
13 char *name;
14 void *stmt[MAX_PREPARED_THREAD_STATEMENTS];
15 };
16
17 __thread struct stmt_pool_s *thread_stmt_pool = NULL;
18
19 long long def_journal_size_limit = 16777216;
20
21 SPINLOCK sqlite_spinlock = SPINLOCK_INITIALIZER;
22
23 bool sqlite_library_initialized;
24 bool sqlite_databases_closed;
25
26 SQLITE_API int sqlite3_exec_monitored(
27 sqlite3 *db, /* An open database */
28 const char *sql, /* SQL to be evaluated */
29 int (*callback)(void*,int,char**,char**), /* Callback function */
30 void *data, /* 1st argument to callback */
31 char **errmsg /* Error msg written here */
32 ) {
33 internal_fatal(!nd_thread_runs_sql(), "THIS THREAD CANNOT RUN SQL");
34
35 int rc = sqlite3_exec(db, sql, callback, data, errmsg);
36 pulse_sqlite3_query_completed(rc == SQLITE_OK, rc == SQLITE_BUSY, rc == SQLITE_LOCKED);
37 return rc;
38 }
39
40 SQLITE_API int sqlite3_step_monitored(sqlite3_stmt *stmt) {
41 internal_fatal(!nd_thread_runs_sql(), "THIS THREAD CANNOT RUN SQL");
42
43 int rc;
44 int cnt = 0;
45
46 while (cnt++ < SQL_MAX_RETRY) {
47 rc = sqlite3_step(stmt);
48 switch (rc) {
49 case SQLITE_DONE:
50 pulse_sqlite3_query_completed(1, 0, 0);
51 break;
52 case SQLITE_ROW:
53 pulse_sqlite3_row_completed();
54 break;
55 case SQLITE_BUSY:
56 case SQLITE_LOCKED:
57 pulse_sqlite3_query_completed(false, rc == SQLITE_BUSY, rc == SQLITE_LOCKED);
58 sleep_usec(SQLITE_INSERT_DELAY * USEC_PER_MS);
59 continue;
60 default:
61 break;
62 }
63 break;
64 }
65 return rc;
66 }
67
68 static bool mark_database_to_recover(sqlite3_stmt *res, sqlite3 *database, int rc)
69 {
70
71 if (!res && !database)
72 return false;
73
74 if (!database)
75 database = sqlite3_db_handle(res);
76
77 if (db_meta == database) {
78 char recover_file[FILENAME_MAX + 1];
79 snprintfz(recover_file, FILENAME_MAX, "%s/.netdata-meta.db.%s", netdata_configured_cache_dir, SQLITE_CORRUPT == rc ? "recover" : "delete" );
80 int fd = open(recover_file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0600);
81 if (fd >= 0) {
82 close(fd);
83 return true;
84 }
85 }
86 return false;
87 }
88
89 int execute_insert(sqlite3_stmt *res) {
90 int rc;
91 rc = sqlite3_step_monitored(res);
92 if (rc == SQLITE_CORRUPT) {
93 (void)mark_database_to_recover(res, NULL, rc);
94 error_report("SQLite error %d", rc);
95 }
96 return rc;
97 }
98
99 int configure_sqlite_database(sqlite3 *database, int target_version, const char *description)
100 {
101 char buf[1024 + 1] = "";
102 const char *list[2] = { buf, NULL };
103
104 const char *def_auto_vacuum = "INCREMENTAL";
105 const char *def_synchronous = "NORMAL";
106 const char *def_journal_mode = "WAL";
107 const char *def_temp_store = "MEMORY";
108 long long def_cache_size = -2000;
109
110 // https://www.sqlite.org/pragma.html#pragma_auto_vacuum
111 // PRAGMA schema.auto_vacuum = 0 | NONE | 1 | FULL | 2 | INCREMENTAL;
112 snprintfz(buf, sizeof(buf) - 1, "PRAGMA auto_vacuum=%s", def_auto_vacuum);
113 if (inicfg_exists(&netdata_config, CONFIG_SECTION_SQLITE, "auto vacuum"))
114 snprintfz(buf, sizeof(buf) - 1, "PRAGMA auto_vacuum=%s",inicfg_get(&netdata_config, CONFIG_SECTION_SQLITE, "auto vacuum", def_auto_vacuum));
115 if (init_database_batch(database, list, description))
116 return 1;
117
118 // https://www.sqlite.org/pragma.html#pragma_synchronous
119 // PRAGMA schema.synchronous = 0 | OFF | 1 | NORMAL | 2 | FULL | 3 | EXTRA;
120 snprintfz(buf, sizeof(buf) - 1, "PRAGMA synchronous=%s", def_synchronous);
121 if (inicfg_exists(&netdata_config, CONFIG_SECTION_SQLITE, "synchronous"))
122 snprintfz(buf, sizeof(buf) - 1, "PRAGMA synchronous=%s", inicfg_get(&netdata_config, CONFIG_SECTION_SQLITE, "synchronous", def_synchronous));
123 if (init_database_batch(database, list, description))
124 return 1;
125
126 // https://www.sqlite.org/pragma.html#pragma_journal_mode
127 // PRAGMA schema.journal_mode = DELETE | TRUNCATE | PERSIST | MEMORY | WAL | OFF
128 snprintfz(buf, sizeof(buf) - 1, "PRAGMA journal_mode=%s", def_journal_mode);
129 if (inicfg_exists(&netdata_config, CONFIG_SECTION_SQLITE, "journal mode"))
130 snprintfz(buf, sizeof(buf) - 1, "PRAGMA journal_mode=%s", inicfg_get(&netdata_config, CONFIG_SECTION_SQLITE, "journal mode", def_journal_mode));
131 if (init_database_batch(database, list, description))
132 return 1;
133
134 // https://www.sqlite.org/pragma.html#pragma_temp_store
135 // PRAGMA temp_store = 0 | DEFAULT | 1 | FILE | 2 | MEMORY;
136 snprintfz(buf, sizeof(buf) - 1, "PRAGMA temp_store=%s", def_temp_store);
137 if (inicfg_exists(&netdata_config, CONFIG_SECTION_SQLITE, "temp store"))
138 snprintfz(buf, sizeof(buf) - 1, "PRAGMA temp_store=%s", inicfg_get(&netdata_config, CONFIG_SECTION_SQLITE, "temp store", def_temp_store));
139 if (init_database_batch(database, list, description))
140 return 1;
141
142 // https://www.sqlite.org/pragma.html#pragma_journal_size_limit
143 // PRAGMA schema.journal_size_limit = N ;
144 snprintfz(buf, sizeof(buf) - 1, "PRAGMA journal_size_limit=%lld", def_journal_size_limit);
145 if (inicfg_exists(&netdata_config, CONFIG_SECTION_SQLITE, "journal size limit")) {
146 def_journal_size_limit = inicfg_get_number(&netdata_config, CONFIG_SECTION_SQLITE, "journal size limit", def_journal_size_limit);
147 snprintfz(buf, sizeof(buf) - 1, "PRAGMA journal_size_limit=%lld", def_journal_size_limit);
148 }
149 if (init_database_batch(database, list, description))
150 return 1;
151
152 // https://www.sqlite.org/pragma.html#pragma_cache_size
153 // PRAGMA schema.cache_size = pages;
154 // PRAGMA schema.cache_size = -kibibytes;
155 snprintfz(buf, sizeof(buf) - 1, "PRAGMA cache_size=%lld", def_cache_size);
156 if (inicfg_exists(&netdata_config, CONFIG_SECTION_SQLITE, "cache size"))
157 snprintfz(buf, sizeof(buf) - 1, "PRAGMA cache_size=%lld", inicfg_get_number(&netdata_config, CONFIG_SECTION_SQLITE, "cache size", def_cache_size));
158 if (init_database_batch(database, list, description))
159 return 1;
160
161 snprintfz(buf, sizeof(buf) - 1, "PRAGMA user_version=%d", target_version);
162 if (init_database_batch(database, list, description))
163 return 1;
164
165 snprintfz(buf, sizeof(buf) - 1, "PRAGMA optimize=0x10002");
166 if (init_database_batch(database, list, description))
167 return 1;
168
169 return 0;
170 }
171
172 static void finalize_and_free_stmt_list(struct stmt_pool_s *stmt_list)
173 {
174 if (!stmt_list)
175 return;
176
177 int max_keys = stmt_list->count;
178 for (int i = 0; i < max_keys; i++) {
179 if (!stmt_list->stmt[i])
180 continue;
181 int rc = sqlite3_finalize((sqlite3_stmt *)stmt_list->stmt[i]);
182 if (unlikely(rc != SQLITE_OK))
183 error_report("Failed to finalize statement, rc = %d", rc);
184 stmt_list->stmt[i] = NULL;
185 }
186 freez(stmt_list->name);
187 freez(stmt_list);
188 }
189
190 // This must be called when the thread terminates
191 void finalize_self_prepared_sql_statements()
192 {
193 if (__atomic_load_n(&sqlite_databases_closed, __ATOMIC_ACQUIRE))
194 return;
195
196 spinlock_lock(&sqlite_spinlock);
197
198 spinlock_lock(&JudyL_thread_stmt_lock);
199 if (thread_stmt_pool) {
200 Word_t thread_id = thread_stmt_pool->thread_id;
201 finalize_and_free_stmt_list(thread_stmt_pool);
202 thread_stmt_pool = NULL;
203 (void)JudyLDel(&JudyL_thread_stmt_pool, thread_id, PJE0);
204 }
205 spinlock_unlock(&JudyL_thread_stmt_lock);
206
207 spinlock_unlock(&sqlite_spinlock);
208 }
209
210 void finalize_all_prepared_sql_statements()
211 {
212 spinlock_lock(&JudyL_thread_stmt_lock);
213 bool first_then_next = true;
214 Pvoid_t *Pvalue = NULL;
215 Word_t thread_id = 0;
216 if (JudyL_thread_stmt_pool) {
217 while ((Pvalue = JudyLFirstThenNext(JudyL_thread_stmt_pool, &thread_id, &first_then_next))) {
218 struct stmt_pool_s *local_stmt_pool = (struct stmt_pool_s *) *Pvalue;
219 if (!local_stmt_pool)
220 continue;
221 nd_log_daemon(
222 NDLP_WARNING,
223 "SQL: Pending SQL statements for thread %lu (%s), make sure thread does a proper cleanup",
224 thread_id,
225 local_stmt_pool->name);
226 finalize_and_free_stmt_list(local_stmt_pool);
227 }
228 (void)JudyLFreeArray(&JudyL_thread_stmt_pool, PJE0);
229 }
230 spinlock_unlock(&JudyL_thread_stmt_lock);
231 }
232
233 static void init_thread_stmt_pool(void) {
234 thread_stmt_pool = (struct stmt_pool_s *)mallocz(sizeof(struct stmt_pool_s));
235 if (!thread_stmt_pool)
236 fatal("Failed to allocate memory for statement pool");
237
238 thread_stmt_pool->count = 0;
239 thread_stmt_pool->thread_id = gettid_cached();
240 thread_stmt_pool->name = strdupz(nd_thread_tag());
241 memset(thread_stmt_pool->stmt, 0, sizeof(void *) * MAX_PREPARED_THREAD_STATEMENTS);
242
243 // Add it to the JudyL array
244 spinlock_lock(&JudyL_thread_stmt_lock);
245 Pvoid_t *Pvalue = JudyLIns(&JudyL_thread_stmt_pool, (Word_t)thread_stmt_pool->thread_id, PJE0);
246 if (!Pvalue || Pvalue == PJERR)
247 fatal("Failed to allocate memory for JudyL thread statement pool");
248 struct stmt_pool_s *old_pool = *Pvalue;
249 fatal_assert(old_pool == NULL);
250 *Pvalue = thread_stmt_pool;
251 spinlock_unlock(&JudyL_thread_stmt_lock);
252 }
253
254 int simple_prepare_statement(sqlite3 *database, const char *query, sqlite3_stmt **statement)
255 {
256 spinlock_lock(&sqlite_spinlock);
257 if (__atomic_load_n(&sqlite_databases_closed, __ATOMIC_ACQUIRE)) {
258 spinlock_unlock(&sqlite_spinlock);
259 return SQLITE_MISUSE;
260 }
261
262 int rc = sqlite3_prepare_v2(database, query, -1, statement, 0);
263 spinlock_unlock(&sqlite_spinlock);
264 return rc;
265 }
266
267 int prepare_statement(sqlite3 *database, const char *query, sqlite3_stmt **statement)
268 {
269 spinlock_lock(&sqlite_spinlock);
270 if (__atomic_load_n(&sqlite_databases_closed, __ATOMIC_ACQUIRE)) {
271 spinlock_unlock(&sqlite_spinlock);
272 return SQLITE_MISUSE;
273 }
274
275 int rc = sqlite3_prepare_v2(database, query, -1, statement, 0);
276 if (rc == SQLITE_OK) {
277 if (!thread_stmt_pool)
278 init_thread_stmt_pool();
279 int stmt_key = __atomic_fetch_add(&thread_stmt_pool->count, 1, __ATOMIC_RELAXED);
280 if (stmt_key < MAX_PREPARED_THREAD_STATEMENTS)
281 thread_stmt_pool->stmt[stmt_key] = *statement;
282 }
283 spinlock_unlock(&sqlite_spinlock);
284 return rc;
285 }
286
287 char *get_database_extented_error(sqlite3 *database, int i, const char *description)
288 {
289 const char *err = sqlite3_errstr(sqlite3_extended_errcode(database));
290
291 if (!err)
292 return NULL;
293
294 size_t len = strlen(err)+ strlen(description) + 32;
295 char *full_err = mallocz(len);
296
297 snprintfz(full_err, len - 1, "%s: %d: %s", description, i, err);
298 return full_err;
299 }
300
301 int init_database_batch(sqlite3 *database, const char *batch[], const char *description)
302 {
303 int rc;
304 char *err_msg = NULL;
305 for (int i = 0; batch[i]; i++) {
306 rc = sqlite3_exec_monitored(database, batch[i], 0, 0, &err_msg);
307 if (rc != SQLITE_OK) {
308 error_report("SQLite error during database initialization, rc = %d (%s)", rc, err_msg);
309 error_report("SQLite failed statement %s", batch[i]);
310 char *error_str = get_database_extented_error(database, i, description);
311 if (error_str)
312 analytics_set_data_str(&analytics_data.netdata_fail_reason, error_str);
313 sqlite3_free(err_msg);
314 freez(error_str);
315 if (SQLITE_CORRUPT == rc || SQLITE_NOTADB == rc) {
316 if (mark_database_to_recover(NULL, database, rc))
317 error_report("Database is corrupted will attempt to fix");
318 return SQLITE_CORRUPT;
319 }
320 return 1;
321 }
322 }
323 return 0;
324 }
325
326 // Return 0 OK
327 // Return 1 Failed
328 // sqlite_rc - if not NULL, it will be set to the return code of the sqlite3_exec_monitored call
329 int db_execute(sqlite3 *db, const char *cmd, int *sqlite_rc)
330 {
331 int rc;
332 int cnt = 0;
333
334 if (unlikely(!db))
335 return 1;
336
337 while (cnt < SQL_MAX_RETRY) {
338 char *err_msg = NULL;
339 rc = sqlite3_exec_monitored(db, cmd, 0, 0, &err_msg);
340 if (likely(rc == SQLITE_OK))
341 break;
342
343 ++cnt;
344 nd_log_daemon(NDLP_WARNING, "Failed to execute '%s', rc = %d (%s) -- attempt %d", cmd, rc, err_msg ? err_msg : "unknown", cnt);
345 if (err_msg) {
346 sqlite3_free(err_msg);
347 }
348
349 if (likely(rc == SQLITE_BUSY || rc == SQLITE_LOCKED)) {
350 sleep_usec(SQLITE_INSERT_DELAY * USEC_PER_MS);
351 continue;
352 }
353
354 if (rc == SQLITE_CORRUPT)
355 mark_database_to_recover(NULL, db, rc);
356 break;
357 }
358 if (sqlite_rc)
359 *sqlite_rc = rc;
360
361 return (rc != SQLITE_OK);
362 }
363
364 // Utils
365 int bind_text_null(sqlite3_stmt *res, int position, const char *text, bool can_be_null)
366 {
367 if (likely(text))
368 return sqlite3_bind_text(res, position, text, -1, SQLITE_STATIC);
369 if (!can_be_null)
370 return 1;
371 return sqlite3_bind_null(res, position);
372 }
373
374 #define SQL_DROP_TABLE "DROP table %s"
375
376 void sql_drop_table(const char *table)
377 {
378 if (!table)
379 return;
380
381 char wstr[255];
382 snprintfz(wstr, sizeof(wstr) - 1, SQL_DROP_TABLE, table);
383
384 int rc = sqlite3_exec_monitored(db_meta, wstr, 0, 0, NULL);
385 if (rc != SQLITE_OK) {
386 error_report("DES SQLite error during drop table operation for %s, rc = %d", table, rc);
387 }
388 }
389
390 static int get_pragma_value(sqlite3 *database, const char *sql)
391 {
392 sqlite3_stmt *res = NULL;
393 int result = -1;
394 if (PREPARE_STATEMENT(database, sql, &res)) {
395 if (likely(sqlite3_step_monitored(res) == SQLITE_ROW))
396 result = sqlite3_column_int(res, 0);
397 SQLITE_FINALIZE(res);
398 }
399 return result;
400 }
401
402 int get_free_page_count(sqlite3 *database)
403 {
404 return get_pragma_value(database, "PRAGMA freelist_count");
405 }
406
407 int get_database_page_count(sqlite3 *database)
408 {
409 return get_pragma_value(database, "PRAGMA page_count");
410 }
411
412 uint64_t sqlite_get_db_space(sqlite3 *db)
413 {
414 if (!db)
415 return 0;
416
417 uint64_t page_size = (uint64_t) get_pragma_value(db, "PRAGMA page_size");
418 uint64_t page_count = (uint64_t) get_pragma_value(db, "PRAGMA page_count");
419
420 return page_size * page_count;
421 }
422
423 /*
424 * Close the sqlite database
425 */
426
427 void sql_close_database(sqlite3 *database, const char *database_name)
428 {
429 int rc;
430 if (unlikely(!database))
431 return;
432
433 (void)db_execute(database, "PRAGMA optimize", NULL);
434
435 netdata_log_info("%s: Closing sqlite database", database_name);
436
437 #ifdef NETDATA_DEV_MODE
438 int t_count_used,t_count_hit,t_count_miss,t_count_full, dummy;
439 (void) sqlite3_db_status(database, SQLITE_DBSTATUS_LOOKASIDE_USED, &dummy, &t_count_used, 0);
440 (void) sqlite3_db_status(database, SQLITE_DBSTATUS_LOOKASIDE_HIT, &dummy,&t_count_hit, 0);
441 (void) sqlite3_db_status(database, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &dummy,&t_count_miss, 0);
442 (void) sqlite3_db_status(database, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &dummy,&t_count_full, 0);
443
444 netdata_log_info("%s: Database lookaside allocation statistics: Used slots %d, Hit %d, Misses due to small slot size %d, Misses due to slots full %d", database_name,
445 t_count_used,t_count_hit, t_count_miss, t_count_full);
446
447 (void) sqlite3_db_release_memory(database);
448 #endif
449
450 rc = sqlite3_close_v2(database);
451 if (unlikely(rc != SQLITE_OK))
452 error_report("%s: Error while closing the sqlite database: rc %d, error \"%s\"", database_name, rc, sqlite3_errstr(rc));
453 database = NULL;
454 }
455
456 extern sqlite3 *db_context_meta;
457
458 // Close a thread-local sqlite3 handle while serializing against sqlite_library_shutdown().
459 // If the SQLite library is no longer initialized, the handle is leaked deliberately; the OS
460 // will reclaim it at process exit, which is strictly safer than crashing inside pcache1.
461 void sql_close_thread_db_safe(sqlite3 **database)
462 {
463 if (unlikely(!database || !*database))
464 return;
465
466 spinlock_lock(&sqlite_spinlock);
467 if (sqlite_library_initialized)
468 (void) sqlite3_close_v2(*database);
469 spinlock_unlock(&sqlite_spinlock);
470
471 *database = NULL;
472 }
473
474 void sqlite_close_databases(void)
475 {
476 // In case we have statements in the main thread (we should not)
477 finalize_self_prepared_sql_statements();
478
479 __atomic_store_n(&sqlite_databases_closed, true, __ATOMIC_RELEASE);
480
481 spinlock_lock(&sqlite_spinlock);
482
483 // Finalize pending statements and report any thread that failed
484 // to do it properly
485 finalize_all_prepared_sql_statements();
486
487 sql_close_database(db_context_meta, "CONTEXT");
488 sql_close_database(db_meta, "METADATA");
489 spinlock_unlock(&sqlite_spinlock);
490 }
491
492 uint64_t get_total_database_space(void)
493 {
494 return 0;
495
496 /*
497 if (!new_dbengine_defaults)
498 return 0;
499
500 uint64_t database_space = sqlite_get_meta_space() + sqlite_get_context_space();
501 #ifdef ENABLE_ML
502 database_space += sqlite_get_ml_space();
503 #endif
504 return database_space;
505 */
506 }
507
508 #define SQLITE_HEAP_HARD_LIMIT (256 * 1024 * 1024)
509 #define SQLITE_HEAP_SOFT_LIMIT (32 * 1024 * 1024)
510
511 int sqlite_library_init(void)
512 {
513 spinlock_lock(&sqlite_spinlock);
514
515 int rc = sqlite3_initialize();
516 if (rc == SQLITE_OK) {
517
518 (void )sqlite3_hard_heap_limit64(SQLITE_HEAP_HARD_LIMIT);
519 int64_t hard_limit_bytes = sqlite3_hard_heap_limit64(-1);
520
521 (void) sqlite3_soft_heap_limit64(SQLITE_HEAP_SOFT_LIMIT);
522 int64_t soft_limit_bytes = sqlite3_soft_heap_limit64(-1);
523
524 const char sqlite_hard_limit_mb[32];
525 size_snprintf_bytes((char *)sqlite_hard_limit_mb, sizeof(sqlite_hard_limit_mb), hard_limit_bytes);
526
527 const char sqlite_soft_limit_mb[32];
528 size_snprintf_bytes((char *)sqlite_soft_limit_mb, sizeof(sqlite_soft_limit_mb), soft_limit_bytes);
529
530 nd_log_daemon(
531 NDLP_INFO, "SQLITE: heap memory hard limit %s, soft limit %s", sqlite_hard_limit_mb, sqlite_soft_limit_mb);
532 }
533 __atomic_store_n(&sqlite_databases_closed, false, __ATOMIC_RELEASE);
534 sqlite_library_initialized = true;
535 spinlock_unlock(&sqlite_spinlock);
536
537 return (SQLITE_OK != rc);
538 }
539
540 int sqlite_release_memory(int bytes)
541 {
542 return sqlite3_release_memory(bytes);
543 }
544
545 void sqlite_library_shutdown(void)
546 {
547 #ifdef NETDATA_INTERNAL_CHECKS
548 int bytes;
549 do {
550 bytes = sqlite_release_memory(1024 * 1024);
551 netdata_log_info("SQLITE: Released %d bytes of memory", bytes);
552 } while (bytes);
553 #endif
554 spinlock_lock(&sqlite_spinlock);
555 if (!sqlite_library_initialized) {
556 spinlock_unlock(&sqlite_spinlock);
557 return;
558 }
559 sqlite_library_initialized = false;
560 (void) sqlite3_shutdown();
561 spinlock_unlock(&sqlite_spinlock);
562 }