@cryptotaxi247 / netdata-1 / commits / e46a29a04

Detect on startup if the netdata-meta.db file is not a valid database file (#17924)

* Detect on startup if the netdata-meta.db file is not a database and move it aside * Log error

Stelios Fragkakis committed Jun 25, 2024 at 16:35 UTC e46a29a04585c32711da6d2d02add6a010c0d878
2 files changed +18 -6
src/database/sqlite/sqlite_functions.c
+6 -6
@@ -43,7 +43,7 @@ SQLITE_API int sqlite3_step_monitored(sqlite3_stmt *stmt) {
43 return rc;
44 }
45
46 -static bool mark_database_to_recover(sqlite3_stmt *res, sqlite3 *database)
46 +static bool mark_database_to_recover(sqlite3_stmt *res, sqlite3 *database, int rc)
47 {
48
49 if (!res && !database)
@@ -54,7 +54,7 @@ static bool mark_database_to_recover(sqlite3_stmt *res, sqlite3 *database)
54
55 if (db_meta == database) {
56 char recover_file[FILENAME_MAX + 1];
57 - snprintfz(recover_file, FILENAME_MAX, "%s/.netdata-meta.db.recover", netdata_configured_cache_dir);
57 + snprintfz(recover_file, FILENAME_MAX, "%s/.netdata-meta.db.%s", netdata_configured_cache_dir, SQLITE_CORRUPT == rc ? "recover" : "delete" );
58 int fd = open(recover_file, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 444);
59 if (fd >= 0) {
60 close(fd);
@@ -69,7 +69,7 @@ int execute_insert(sqlite3_stmt *res)
69 int rc;
70 rc = sqlite3_step_monitored(res);
71 if (rc == SQLITE_CORRUPT) {
72 - (void)mark_database_to_recover(res, NULL);
72 + (void)mark_database_to_recover(res, NULL, rc);
73 error_report("SQLite error %d", rc);
74 }
75 return rc;
@@ -229,8 +229,8 @@ int init_database_batch(sqlite3 *database, const char *batch[], const char *desc
229 analytics_set_data_str(&analytics_data.netdata_fail_reason, error_str);
230 sqlite3_free(err_msg);
231 freez(error_str);
232 - if (SQLITE_CORRUPT == rc) {
233 - if (mark_database_to_recover(NULL, database))
232 + if (SQLITE_CORRUPT == rc || SQLITE_NOTADB == rc) {
233 + if (mark_database_to_recover(NULL, database, rc))
234 error_report("Database is corrupted will attempt to fix");
235 return SQLITE_CORRUPT;
236 }
@@ -263,7 +263,7 @@ int db_execute(sqlite3 *db, const char *cmd)
263 }
264
265 if (rc == SQLITE_CORRUPT)
266 - mark_database_to_recover(NULL, db);
266 + mark_database_to_recover(NULL, db, rc);
267 break;
268 }
269 return (rc != SQLITE_OK);
src/database/sqlite/sqlite_metadata.c
+12
@@ -668,6 +668,18 @@ int sql_init_meta_database(db_check_action_type_t rebuild, int memory)
668 if (rebuild & DB_CHECK_RECOVER)
669 return 0;
670 }
671 +
672 + snprintfz(sqlite_database, sizeof(sqlite_database) - 1, "%s/.netdata-meta.db.delete", netdata_configured_cache_dir);
673 + rc = unlink(sqlite_database);
674 + snprintfz(sqlite_database, FILENAME_MAX, "%s/netdata-meta.db", netdata_configured_cache_dir);
675 + if (rc == 0) {
676 + char new_sqlite_database[FILENAME_MAX + 1];
677 + snprintfz(new_sqlite_database, sizeof(new_sqlite_database) - 1, "%s/netdata-meta.bad", netdata_configured_cache_dir);
678 + rc = rename(sqlite_database, new_sqlite_database);
679 + if (rc)
680 + error_report("Failed to rename %s to %s", sqlite_database, new_sqlite_database);
681 + }
682 + // note: sqlite_database contains the right name
683 }
684 else
685 strncpyz(sqlite_database, ":memory:", sizeof(sqlite_database) - 1);