Dominik
2ac91560e7
database: Guard query-count counters against uint64_t underflow
...
memdb_queries_count and diskdb_queries_count are declared as uint64_t.
In delete_old_queries_from_db(), both counters are decremented by
`deleted` (int64_t from sqlite3_changes64). If the counter is already
at 0 — which can happen when import_queries_from_disk() fails and
resets the counter to 0 mid-import — subtracting any positive `deleted`
value wraps the counter to UINT64_MAX (≈1.84×10¹⁹).
db_counts() returns these counters as sqlite3_int64 (signed), so
UINT64_MAX becomes -1. The /api/queries endpoint then casts -1 to
unsigned long for recordsTotal, producing the observed
1.8446744073709552E+19 value and making the query log appear to have
millions of pages.
Fix: clamp the subtraction to 0 instead of allowing underflow, using
a guarded conditional assignment.
Signed-off-by: Dominik <dl6er@dl6er.de >
2026-03-20 15:56:30 +01:00
Dominik
5dbeeb8e60
Always mark database import as done even when database.DBimport = false or on database errors. Otherwise, garbage collection will never run, causing the memory allocation to always grow and overtime information to be incorrect (handled in GC code as well)
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2026-02-26 07:22:53 +01:00
Dominik
0789ad27bd
Merge branch 'development' into tweak/async_import
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2026-02-09 19:10:42 +01:00
Dominik
a8872e636a
Cache earliest timestamp in both databases (mem and disk) as well
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2026-02-08 10:04:33 +01:00
Dominik
ba2db9c10f
Keep track of number of queries in the database ourselves. No need to fully count the number of queries in the disk after startup. Even though this is happening using a covering index, it turned out to be very slow on heavily I/O limited devices when the index tree does not fit into available cache memory (scanning can take upwards of one minute for a simple SELECT COUNT(*) FROM query_storage)
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2026-01-10 17:33:20 +01:00
Dominik
6ef8b074c4
Simplify delete_old_queries_in_DB() algorithm and reduce nesting in disk filesize getting
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2026-01-07 19:36:02 +01:00
Dominik
9aa6daf84d
Warn if too few queries were imported
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-13 11:37:04 +01:00
Dominik
d63247b067
Remove the compile-time option to batch locking during import. We are not using it. It adds unecessary maintainance workload
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-13 09:59:32 +01:00
Dominik
a3d0abaf55
Do not use a long open transaction as it may have side-effects on really slow machines when other threads are trying to work with the database
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-13 09:35:15 +01:00
Dominik
f8643a8f3d
Rearrange initial database interactions to avoid blocking. Also, move some uncritical parts into the corresponding threads for more parallelism.
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-11 17:47:00 +01:00
Dominik
4d3bae5c4f
Ensure stmt2 cannot be uninitialized upon failure
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-08 19:52:33 +01:00
Dominik
a690bee3d2
Fix a few possible SQLite3-related memory leaks on user errors and simplify code by removing unnecessary reset calls
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-08 17:22:12 +01:00
Dominik
07e1e4b07c
Also make the actual importing from disk into memory (happening before the parsing) taking place asynchronously.
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-08 17:14:52 +01:00
Dominik
6f436651c1
Queries already imported from disk should not be re-exported as these queries cannot receive any further updates. This is a performance optimization mostly relevant for very active (= many queries per second) systems.
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-08 17:02:57 +01:00
Dominik
cfcef205ac
Do not filter on the history windows twice. This can lead to missing queries in the second run, causing "empty" query slots. They are - themselves - entirely harmless, however, they will cuase "memory error" warnings until they are garbage collected away after a few minutes.
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-08 17:01:44 +01:00
Dominik
80e14ec11d
Queries are not recycled so we also don't need to check against a query having been recycled
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-07 22:08:58 +01:00
Dominik
184f80a2bf
Queries should not be counted twice during async import
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-05 19:49:22 +01:00
Dominik
b8bdf7f2df
Log when queries are imported based on the really imported queries
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-02 20:32:02 +01:00
Dominik
fd6eaabfe8
Remove pre-allocation of domains, clients, and upstreams as we will not import all of them from disk during import. This will make the SHM objects unnecessarily large - they can grow naturally during importing
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-01 20:18:16 +01:00
Dominik
6cd4622b60
Optionally batch querys during import to reduce locking overhead. This is experimental and disabled for now as it will reduce the time being unlocked, i.e., it reduces the number of ocassions where normal query handling could take place (which is the entire point about implementing async importing)
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-01 20:17:47 +01:00
Dominik
a27b105d3b
Postpose GC runs until async database import is done
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-12-01 20:11:14 +01:00
Dominik
dd4e4af691
Ensure commiting the transaction to the in-memory database is happening outside of the SHM lock. This is not really needed for the in-memory database, however, it may be an issue when users use the new forceDisk feature
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-11-28 19:14:36 +01:00
Dominik
f5b401a46e
Add database.forceDisk to force FTL into a low-memory mode
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-11-28 18:59:11 +01:00
Dominik
5e49b8ba5a
Implement look-ahead shared memory resizing and move database initialization into a dedicated asynchronous thread
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-11-25 19:41:10 +01:00
Dominik
144e0d9adf
Merge branch 'development' into tweak/db_performance
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-11-25 19:40:11 +01:00
Dominik
5d20b9f97d
Merge pull request #2700 from pi-hole/tweak/dont-lock-on-export
...
Reduce DNS resolver locking during database interaction
2025-11-21 16:49:03 +01:00
Michael Woolweaver
0b2b6dff0b
Increase buffer length for query string
...
Signed-off-by: Michael Woolweaver <michael@woolweaver.bid >
2025-11-11 06:53:33 -06:00
Adam Warner
5df02b5578
Expands the get_number_of_queries_in_DB() function to optionally return
...
the earliest timestamp found in the database.
Also gets number of queries/earliest timestamp in on-disk database
Useful for determining the "All Time" range on the web interface
Signed-off-by: Adam Warner <me@adamwarner.co.uk >
2025-11-09 14:37:43 +00:00
Dominik
719eb57f44
Limit the scan table size when exporting queries to disk. This will mean speedup espectially when only few entries are exported (typical case)
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-11-08 14:03:18 +01:00
Dominik
6a141f620d
We do not need to lock the SHM objects during export to disk database inside a TRANSACTION
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-11-08 14:02:53 +01:00
Dominik
9423573404
We do not need to loch the SHM objects during export to disk database inside a TRANSACTION
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-11-08 12:16:01 +01:00
DL6ER
d6c56f5f64
Configure a database busy handler giving us control (and debugging capabilities) of what happens while the database is busy.
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2025-10-04 09:15:46 +02:00
Dominik
92d4383e36
Merge branch 'development' into fix/insertion_counting
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-09-26 19:37:47 +02:00
Dominik
95fdc34e76
Automatic code review
...
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Signed-off-by: Dominik <DL6ER@users.noreply.github.com >
2025-09-24 19:58:12 +02:00
Dominik
f8d9b5ea42
Update outdated CodeQL dependencies to allow running them
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-09-24 19:58:12 +02:00
Dominik
f34058fd4c
Ensure queries with ID 0 are stored to the long-term queries database
...
Signed-off-by: Dominik <dl6er@dl6er.de >
2025-09-24 19:58:12 +02:00
Dominik
5e6fe84f30
Apply suggestions from code review
...
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com >
Signed-off-by: Dominik <DL6ER@users.noreply.github.com >
2025-09-17 09:15:03 +02:00
DL6ER
8413b161a2
Sunset last_disk_db_idx and instead realize the same with a subquery
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2025-07-27 11:41:44 +02:00
DL6ER
00c520190a
Reuse prepared SQLite3 statements instead of repeating the ever-same compilation steps over and over. So far, this was not an issue as this doesn't happen often but - anyway - it is needlessly duplicated work.
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2025-07-25 18:39:54 +02:00
DL6ER
dc16d6c4b7
Avoid double-incrementing the last_disk_db_idx counter. This leads to a situation where some queries are not stored in the on-disk database. How much this affects you depends on the activity of the aforegoing database storing interval and, hence, is rather subtle.
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2025-07-25 18:35:11 +02:00
DL6ER
b96e5294d6
Do not store queries when database.maxDBdays is == 0, however, we still want to store the remaining meta-tables for the network table to work
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2025-03-11 04:59:11 +01:00
DL6ER
4c98b5d33d
Non-queries are not worth warnings during database importing / history restoration
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2025-02-06 06:04:55 +01:00
DL6ER
1eaa9ea0f0
Improve handling of non-queries. This has recently been fixed in dnsmasq (see commit 8132969, Dec, 19, 2024)
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2025-01-24 05:13:12 +01:00
DL6ER
a47c35e971
Prevent a few code paths from running when we know the disk database is not available (e.g. broken or more recent than this particular FTL binary can handle (like checking out a very old branch))
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2025-01-03 22:14:27 +01:00
DL6ER
dd39c5eb0c
Expose EDE information via API if available
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2024-12-18 10:58:44 +01:00
DL6ER
787021b1cf
Try to use DNS cache ID if known to avoid searching when possible
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2024-10-21 20:05:11 +02:00
DL6ER
9a9615ad78
Set lastQuery property of CNAME child domains
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2024-10-19 19:05:49 +02:00
DL6ER
93a06c0124
Remove unused code segments
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2024-10-15 21:36:43 +02:00
DL6ER
2f8355ed25
Further code maintainance (adding "const", etc.)
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2024-10-14 19:27:52 +02:00
DL6ER
33645777e9
Add basic lookup table implementation and create new SHM objects for them. Also simplify code by changing index counters to unsigned types.
...
Signed-off-by: DL6ER <dl6er@dl6er.de >
2024-10-12 22:01:57 +02:00