Skip to content

Commit 27bea5b

Browse files
authored
Merge pull request #2367 from pi-hole/fix/maxDBdays_networktbl
Still save clients when database.maxDBdays is 0
2 parents b42ef53 + b96e529 commit 27bea5b

File tree

4 files changed

+107
-105
lines changed

4 files changed

+107
-105
lines changed

src/database/database-thread.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,7 @@ void *DB_thread(void *val)
131131
break;
132132

133133
// Store queries in on-disk database
134-
if(config.database.maxDBdays.v.ui > 0 &&
135-
now - lastDBsave >= (time_t)config.database.DBinterval.v.ui)
134+
if(now - lastDBsave >= (time_t)config.database.DBinterval.v.ui)
136135
{
137136
// Update lastDBsave timer
138137
lastDBsave = now - now%config.database.DBinterval.v.ui;

src/database/query-table.c

+102-96
Original file line numberDiff line numberDiff line change
@@ -586,88 +586,129 @@ bool import_queries_from_disk(void)
586586
// seconds. This is to give queries some time to complete before they are
587587
// exported to disk. When final is true, we export all queries (nothing is going
588588
// to be added to the in-memory database anymore).
589-
bool export_queries_to_disk(bool final)
589+
bool export_queries_to_disk(const bool final)
590590
{
591+
int rc = 0;
591592
bool okay = false;
593+
unsigned int insertions = 0;
592594
const double time = double_time() - (final ? 0.0 : REPLY_TIMEOUT);
593595

594596
// Only try to export to database if it is known to not be broken
595597
if(FTLDBerror())
596-
return false;
597-
598-
const char *querystr = "INSERT INTO disk.query_storage SELECT * FROM query_storage WHERE id > ? AND timestamp < ?";
599-
600-
log_debug(DEBUG_DATABASE, "Storing queries on disk WHERE id > %lu (max is %lu) and timestamp < %f",
601-
last_disk_db_idx, last_mem_db_idx, time);
598+
return false;
602599

603600
// Start database timer
604601
timer_start(DATABASE_WRITE_TIMER);
605602

606603
// Start transaction
607604
sqlite3 *memdb = get_memdb();
608-
SQL_bool(memdb, "BEGIN TRANSACTION");
609-
610-
// Prepare SQLite3 statement
611605
sqlite3_stmt *stmt = NULL;
612-
log_debug(DEBUG_DATABASE, "Accessing in-memory database");
613-
int rc = sqlite3_prepare_v2(memdb, querystr, -1, &stmt, NULL);
614-
if( rc != SQLITE_OK ){
615-
log_err("export_queries_to_disk(): SQL error prepare: %s", sqlite3_errstr(rc));
616-
return false;
617-
}
606+
SQL_bool(memdb, "BEGIN TRANSACTION");
618607

619-
// Bind index
620-
if((rc = sqlite3_bind_int64(stmt, 1, last_disk_db_idx)) != SQLITE_OK)
608+
// Only store queries if database.maxDBdays > 0
609+
if(config.database.maxDBdays.v.ui > 0)
621610
{
622-
log_err("export_queries_to_disk(): Failed to bind id: %s", sqlite3_errstr(rc));
623-
return false;
624-
}
611+
const char *querystr = "INSERT INTO disk.query_storage SELECT * FROM query_storage WHERE id > ? AND timestamp < ?";
625612

626-
// Bind upper time limit
627-
// This prevents queries from the last 30 seconds from being stored
628-
// immediately on-disk to give them some time to complete before finally
629-
// exported. We do not limit anything when storing during termination.
630-
if((rc = sqlite3_bind_double(stmt, 2, time)) != SQLITE_OK)
631-
{
632-
log_err("export_queries_to_disk(): Failed to bind time: %s", sqlite3_errstr(rc));
633-
return false;
634-
}
613+
log_debug(DEBUG_DATABASE, "Storing queries on disk WHERE id > %lu (max is %lu) and timestamp < %f",
614+
last_disk_db_idx, last_mem_db_idx, time);
635615

636-
// Perform step
637-
if((rc = sqlite3_step(stmt)) == SQLITE_DONE)
638-
okay = true;
639-
else
640-
{
641-
log_err("export_queries_to_disk(): Failed to export queries: %s", sqlite3_errstr(rc));
642-
log_info(" SQL query was: \"%s\"", querystr);
643-
log_info(" with parameters: id = %lu, timestamp = %f", last_disk_db_idx, time);
644-
}
616+
// Prepare SQLite3 statement
617+
log_debug(DEBUG_DATABASE, "Accessing in-memory database");
618+
if((rc = sqlite3_prepare_v2(memdb, querystr, -1, &stmt, NULL)) != SQLITE_OK)
619+
{
620+
log_err("export_queries_to_disk(): SQL error prepare: %s", sqlite3_errstr(rc));
621+
return false;
622+
}
645623

646-
// Get number of queries actually inserted by the INSERT INTO ... SELECT * FROM ...
647-
const unsigned int insertions = sqlite3_changes(memdb);
624+
// Bind index
625+
if((rc = sqlite3_bind_int64(stmt, 1, last_disk_db_idx)) != SQLITE_OK)
626+
{
627+
log_err("export_queries_to_disk(): Failed to bind id: %s", sqlite3_errstr(rc));
628+
return false;
629+
}
648630

649-
// Finalize statement
650-
sqlite3_finalize(stmt);
631+
// Bind upper time limit
632+
// This prevents queries from the last 30 seconds from being stored
633+
// immediately on-disk to give them some time to complete before finally
634+
// exported. We do not limit anything when storing during termination.
635+
if((rc = sqlite3_bind_double(stmt, 2, time)) != SQLITE_OK)
636+
{
637+
log_err("export_queries_to_disk(): Failed to bind time: %s", sqlite3_errstr(rc));
638+
return false;
639+
}
651640

652-
// Update last_disk_db_idx
653-
// Prepare SQLite3 statement
654-
log_debug(DEBUG_DATABASE, "Accessing in-memory database");
655-
rc = sqlite3_prepare_v2(memdb, "SELECT MAX(id) FROM disk.query_storage;", -1, &stmt, NULL);
656-
if(rc != SQLITE_OK)
657-
{
658-
log_err("export_queries_to_disk(): SQL error prepare: %s", sqlite3_errstr(rc));
659-
return false;
660-
}
641+
// Perform step
642+
if((rc = sqlite3_step(stmt)) == SQLITE_DONE)
643+
okay = true;
644+
else
645+
{
646+
log_err("export_queries_to_disk(): Failed to export queries: %s", sqlite3_errstr(rc));
647+
log_info(" SQL query was: \"%s\"", querystr);
648+
log_info(" with parameters: id = %lu, timestamp = %f", last_disk_db_idx, time);
649+
}
661650

662-
// Perform step
663-
if((rc = sqlite3_step(stmt)) == SQLITE_ROW)
664-
last_disk_db_idx = sqlite3_column_int64(stmt, 0);
665-
else
666-
log_err("Failed to get MAX(id) from query_storage: %s",
667-
sqlite3_errstr(rc));
651+
// Get number of queries actually inserted by the INSERT INTO ... SELECT * FROM ...
652+
insertions = sqlite3_changes(memdb);
668653

669-
// Finalize statement
670-
sqlite3_finalize(stmt);
654+
// Finalize statement
655+
sqlite3_finalize(stmt);
656+
657+
658+
// Update last_disk_db_idx
659+
// Prepare SQLite3 statement
660+
rc = sqlite3_prepare_v2(memdb, "SELECT MAX(id) FROM disk.query_storage;", -1, &stmt, NULL);
661+
if(rc != SQLITE_OK)
662+
{
663+
log_err("export_queries_to_disk(): SQL error prepare: %s", sqlite3_errstr(rc));
664+
return false;
665+
}
666+
667+
// Perform step
668+
if((rc = sqlite3_step(stmt)) == SQLITE_ROW)
669+
last_disk_db_idx = sqlite3_column_int64(stmt, 0);
670+
else
671+
log_err("Failed to get MAX(id) from query_storage: %s",
672+
sqlite3_errstr(rc));
673+
674+
// Finalize statement
675+
sqlite3_finalize(stmt);
676+
677+
/*
678+
* If there are any insertions, we:
679+
* 1. Insert (or replace) the last timestamp into the `disk.ftl` table.
680+
* 2. Update the total queries counter in the `disk.counters` table.
681+
* 3. Update the blocked queries counter in the `disk.counters` table.
682+
*
683+
* Note that new_total does not need to match the total number of
684+
* insertions here as storing queries to the database happens
685+
* time-delayed. In the end, the total number of queries will be
686+
* correct (after final synchronization during FTL shutdown).
687+
*/
688+
if(insertions > 0)
689+
{
690+
if((rc = dbquery(memdb, "INSERT OR REPLACE INTO disk.ftl (id, value) VALUES ( %i, %f );", DB_LASTTIMESTAMP, new_last_timestamp)) != SQLITE_OK)
691+
log_err("export_queries_to_disk(): Cannot update timestamp: %s", sqlite3_errstr(rc));
692+
693+
if((rc = dbquery(memdb, "UPDATE disk.counters SET value = value + %u WHERE id = %i;", new_total, DB_TOTALQUERIES)) != SQLITE_OK)
694+
log_err("export_queries_to_disk(): Cannot update total queries counter: %s", sqlite3_errstr(rc));
695+
else
696+
// Success
697+
new_total = 0;
698+
699+
if((rc = dbquery(memdb, "UPDATE disk.counters SET value = value + %u WHERE id = %i;", new_blocked, DB_BLOCKEDQUERIES)) != SQLITE_OK)
700+
log_err("export_queries_to_disk(): Cannot update blocked queries counter: %s", sqlite3_errstr(rc));
701+
else
702+
// Success
703+
new_blocked = 0;
704+
}
705+
706+
// Update number of queries in the disk database
707+
disk_db_num = get_number_of_queries_in_DB(memdb, "disk.query_storage");
708+
709+
// All temp queries were stored to disk, update the IDs
710+
last_disk_db_idx += insertions;
711+
}
671712

672713
// Export linking tables and current AUTOINCREMENT values to the disk database
673714
const char *subtable_names[] = {
@@ -694,50 +735,15 @@ bool export_queries_to_disk(bool final)
694735
log_debug(DEBUG_DATABASE, "Exported %i rows to disk.%s", sqlite3_changes(memdb), subtable_names[i]);
695736
}
696737

697-
/*
698-
* If there are any insertions, we:
699-
* 1. Insert (or replace) the last timestamp into the `disk.ftl` table.
700-
* 2. Update the total queries counter in the `disk.counters` table.
701-
* 3. Update the blocked queries counter in the `disk.counters` table.
702-
*
703-
* Note that new_total does not need to match the total number of
704-
* insertions here as storing queries to the database happens
705-
* time-delayed. In the end, the total number of queries will be
706-
* correct (after final synchronization during FTL shutdown).
707-
*/
708-
if(insertions > 0)
709-
{
710-
if((rc = dbquery(memdb, "INSERT OR REPLACE INTO disk.ftl (id, value) VALUES ( %i, %f );", DB_LASTTIMESTAMP, new_last_timestamp)) != SQLITE_OK)
711-
log_err("export_queries_to_disk(): Cannot update timestamp: %s", sqlite3_errstr(rc));
712-
713-
if((rc = dbquery(memdb, "UPDATE disk.counters SET value = value + %u WHERE id = %i;", new_total, DB_TOTALQUERIES)) != SQLITE_OK)
714-
log_err("export_queries_to_disk(): Cannot update total queries counter: %s", sqlite3_errstr(rc));
715-
else
716-
// Success
717-
new_total = 0;
718-
719-
if((rc = dbquery(memdb, "UPDATE disk.counters SET value = value + %u WHERE id = %i;", new_blocked, DB_BLOCKEDQUERIES)) != SQLITE_OK)
720-
log_err("export_queries_to_disk(): Cannot update blocked queries counter: %s", sqlite3_errstr(rc));
721-
else
722-
// Success
723-
new_blocked = 0;
724-
}
725-
726738
// End transaction
727739
if((rc = sqlite3_exec(memdb, "END TRANSACTION", NULL, NULL, NULL)) != SQLITE_OK)
728740
{
729741
log_err("export_queries_to_disk(): Cannot end transaction: %s", sqlite3_errstr(rc));
730742
return false;
731743
}
732744

733-
// Update number of queries in the disk database
734-
disk_db_num = get_number_of_queries_in_DB(memdb, "disk.query_storage");
735-
736-
// All temp queries were stored to disk, update the IDs
737-
last_disk_db_idx += insertions;
738-
739745
log_debug(DEBUG_DATABASE, "Exported %u rows for disk.query_storage (took %.1f ms, last SQLite ID %lu)",
740-
insertions, timer_elapsed_msec(DATABASE_WRITE_TIMER), last_disk_db_idx);
746+
insertions, timer_elapsed_msec(DATABASE_WRITE_TIMER), last_disk_db_idx);
741747

742748
return okay;
743749
}

src/database/query-table.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ bool import_queries_from_disk(void);
114114
bool attach_database(sqlite3* db, const char **message, const char *path, const char *alias);
115115
bool detach_database(sqlite3* db, const char **message, const char *alias);
116116
int get_number_of_queries_in_DB(sqlite3 *db, const char *tablename);
117-
bool export_queries_to_disk(bool final);
117+
bool export_queries_to_disk(const bool final);
118118
bool delete_old_queries_from_db(const bool use_memdb, const double mintime);
119119
bool add_additional_info_column(sqlite3 *db);
120120
void DB_read_queries(void);

src/main.c

+3-6
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,9 @@ int main (int argc, char *argv[])
149149
// be terminating immediately
150150
sleepms(250);
151151

152-
// Save new queries to database (if database is used)
153-
if(config.database.maxDBdays.v.ui > 0)
154-
{
155-
export_queries_to_disk(true);
156-
log_info("Finished final database update");
157-
}
152+
// Save new queries to database
153+
export_queries_to_disk(true);
154+
log_info("Finished final database update");
158155

159156
cleanup(exit_code);
160157

0 commit comments

Comments
 (0)