@camstack/system 1.2.128 → 1.2.129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -223,6 +223,17 @@ export declare class SqliteSettingsBackend implements ISettingsBackend {
|
|
|
223
223
|
* with a number yields 0, which `sqliteOccupancy` reads as "unknown" and
|
|
224
224
|
* reports as an empty file rather than inventing a ratio.
|
|
225
225
|
*/
|
|
226
|
+
/**
|
|
227
|
+
* Name the biggest tables, once, a minute after the connection opens.
|
|
228
|
+
*
|
|
229
|
+
* `dbSizeMb` says how big the file is and `freePct` says how much of it is
|
|
230
|
+
* live; neither says WHOSE. Per-addon scoped collections are created on first
|
|
231
|
+
* write and declared nowhere, so this is the only place the real set can be
|
|
232
|
+
* enumerated. `unref` so it can never hold the process open, and
|
|
233
|
+
* `CAMSTACK_SQLITE_STORAGE_REPORT=off` turns it off without a rebuild.
|
|
234
|
+
*/
|
|
235
|
+
private scheduleStorageReport;
|
|
236
|
+
private logStorageReport;
|
|
226
237
|
private readPragmaNumber;
|
|
227
238
|
private measureDbSizeBytes;
|
|
228
239
|
private getDb;
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which collection IS the database.
|
|
3
|
+
*
|
|
4
|
+
* ## Why this exists
|
|
5
|
+
*
|
|
6
|
+
* The boot line already says how big the file is (`dbSizeMb`) and how much of
|
|
7
|
+
* it is real (`freePct`). Measured on the live hub 2026-08-25 those read
|
|
8
|
+
* `dbSizeMb=858 liveMb=840 freeMb=18 freePct=2` — so the growth from 153 MB
|
|
9
|
+
* (08-08) is not a high-water mark waiting for a VACUUM, it is live rows. That
|
|
10
|
+
* turned "should we VACUUM" into "which table", and nothing in this system
|
|
11
|
+
* could answer it.
|
|
12
|
+
*
|
|
13
|
+
* Nothing could, structurally: per-addon scoped collections
|
|
14
|
+
* (`<addonId>:<canonical>`) are created on the first write and declared in no
|
|
15
|
+
* source file, so the real set only exists on the running node. A reference
|
|
16
|
+
* page cannot list them and a grep cannot find them.
|
|
17
|
+
*
|
|
18
|
+
* ## Why `dbstat` and not `COUNT(*)`
|
|
19
|
+
*
|
|
20
|
+
* `dbstat` reports the pages a table actually occupies, which is the question —
|
|
21
|
+
* a table with few enormous rows and a table with many small ones are the same
|
|
22
|
+
* problem when the file is the thing that grew. It walks the b-tree structure
|
|
23
|
+
* without decoding row payloads, so it costs a page traversal rather than a
|
|
24
|
+
* full table scan. It is still real work on an 840 MB file, which is why the
|
|
25
|
+
* caller runs it ONCE, well after boot, off the critical path — never on the
|
|
26
|
+
* path a config read waits behind.
|
|
27
|
+
*/
|
|
28
|
+
/** One `dbstat` group: a table (or index) and the space it occupies. */
|
|
29
|
+
export interface TableSizeRow {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly bytes: number;
|
|
32
|
+
readonly pages: number;
|
|
33
|
+
}
|
|
34
|
+
/** One line of the report. */
|
|
35
|
+
export interface TableSizeEntry {
|
|
36
|
+
readonly name: string;
|
|
37
|
+
readonly sizeMb: number;
|
|
38
|
+
readonly pages: number;
|
|
39
|
+
/** Share of the whole file, percent. 0 when the file size is unknown. */
|
|
40
|
+
readonly pct: number;
|
|
41
|
+
}
|
|
42
|
+
export interface TableSizeReport {
|
|
43
|
+
readonly tables: readonly TableSizeEntry[];
|
|
44
|
+
/** Megabytes held by everything below the cut. */
|
|
45
|
+
readonly otherMb: number;
|
|
46
|
+
/** How many tables are behind `otherMb`. */
|
|
47
|
+
readonly otherTables: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Rank tables by the space they hold and keep the top `limit`.
|
|
51
|
+
*
|
|
52
|
+
* The tail is REPORTED, never dropped: a top-N that silently discards the rest
|
|
53
|
+
* reads as "these N are the database", which is exactly the wrong conclusion
|
|
54
|
+
* when the remainder is a third of the file.
|
|
55
|
+
*/
|
|
56
|
+
export declare function summariseTableSizes(rows: readonly TableSizeRow[], totalBytes: number, limit: number): TableSizeReport;
|
|
57
|
+
/**
|
|
58
|
+
* How long after opening the connection the report runs.
|
|
59
|
+
*
|
|
60
|
+
* Not zero and not "on every boot forever at startup": boot is already the
|
|
61
|
+
* busiest window this engine sees (`ensureTable` x9, the retired-key purge, the
|
|
62
|
+
* vector registry), and a page traversal of an 840 MB file placed there would
|
|
63
|
+
* be indistinguishable from the stall this whole subsystem was just fixed for.
|
|
64
|
+
* Sixty seconds puts it after the storm, once per process.
|
|
65
|
+
*/
|
|
66
|
+
export declare const STORAGE_REPORT_DELAY_MS = 60000;
|
|
67
|
+
/** Top-N tables named individually; the remainder is reported as a tail. */
|
|
68
|
+
export declare const STORAGE_REPORT_TOP_N = 10;
|
|
69
|
+
/** `dbstat` shape, narrowed without a cast. */
|
|
70
|
+
export declare function toTableSizeRow(value: unknown): TableSizeRow | null;
|