Enterprise-Backup-, Recovery-, Verification-, Security- und Monitoring-Plattform fuer Proxmox VE, Windows, Linux und Dateisysteme. Der Leitsatz, der fast jede Entscheidung erklaert: Ein Backup gilt erst als vertrauenswuerdig, wenn Integritaet geprueft und Wiederherstellbarkeit nachgewiesen wurde. Deshalb steigt ein Wiederherstellungspunkt erst nach einem tatsaechlich durchgefuehrten Restore-Test auf "recoverable", und Unbekanntes geht in keine Bewertung als "gut" ein. Umfang (Phasen 0-23): - Repository Engine: inhaltsadressierte Bloecke, atomares Commit-Protokoll, Katalogaufbau allein aus den Manifesten — ohne Datenbank - Backup Engine: inhaltsabhaengiges Chunking, Deduplizierung trotz Verschluesselung, zstd, AES-256-GCM, Streaming mit Gegendruck - Agenten fuer Windows und Linux mit Auftragsabholung (Pull-Modell) - Proxmox-Provider mit beiden Zugriffswegen auf die Sicherungsarchive - Scheduler, Recovery Engine mit Pruefpunkt, Verification, Unveraenderlichkeit - Weboberflaeche, Kennzahlen, Meldungen, Berichte, Security Center, Ransomware-Heuristik (meldet, handelt nie) - Disaster Recovery, Haertung, Leistungsmessung, Chaos Testing - Eingefrorene Vertraege fuer API, Migrationen, Backup-Format und Repository - Auslieferungspaket fuer linux/amd64, linux/arm64 und windows/amd64 Nicht enthalten und als solches gekennzeichnet: Kapazitaetsprognose, Backup Copy, Changed Block Tracking bei Proxmox, erweiterte Attribute und ACLs. Gebaut, aber nie auf echter Hardware gefahren: der Windows-Dienst, die systemd-Einheit und der verpflichtende Proxmox-Meilenstein — ob eine wiederhergestellte VM startet, ist ungeprueft. Einzelheiten in CHANGELOG.md und docs/release-candidate.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
85 lines
3.8 KiB
SQL
85 lines
3.8 KiB
SQL
-- Kennzahlen und Verlaufsreihen (Phase 13).
|
|
--
|
|
-- Der Plan verlangt zwoelf Diagramme. Zehn davon lassen sich aus Tabellen
|
|
-- bilden, die es bereits gibt: backup_job_runs traegt Dauer, Durchsatz und
|
|
-- Datenmengen jedes Laufs, backups die Groessen fuer Deduplizierung und
|
|
-- Kompression, restore_jobs und verification_jobs ihre Ergebnisse.
|
|
--
|
|
-- Diese Zahlen ein zweites Mal als Zeitreihe abzulegen waere die uebliche
|
|
-- Loesung und die schlechtere: Zwei Quellen fuer dieselbe Aussage laufen
|
|
-- auseinander, und man merkt es erst, wenn jemand nachrechnet. Aggregiert wird
|
|
-- deshalb aus den Ereignistabellen.
|
|
--
|
|
-- Diese Tabelle nimmt nur auf, was sonst **verloren geht**: Momentaufnahmen, die
|
|
-- beim naechsten Schreiben ueberschrieben werden. repositories.used_bytes ist
|
|
-- genau das — der heutige Stand, ohne jede Erinnerung an gestern.
|
|
|
|
CREATE TABLE metric_samples (
|
|
-- id ist der fortlaufende Bezeichner.
|
|
--
|
|
-- Eine Zeitreihe wird ausschliesslich angehaengt und in Zeitfenstern
|
|
-- gelesen; eine UUID braeuchte hier mehr Platz und brächte nichts.
|
|
id BIGSERIAL PRIMARY KEY,
|
|
-- metric_name benennt die Reihe.
|
|
metric_name TEXT NOT NULL,
|
|
-- subject_type benennt die Art des Gegenstands, etwa 'repository'.
|
|
subject_type TEXT NOT NULL,
|
|
-- subject_id ist der Gegenstand der Messung.
|
|
subject_id UUID NOT NULL,
|
|
-- value ist der gemessene Wert.
|
|
--
|
|
-- DOUBLE PRECISION statt BIGINT: Die Reihe nimmt auch Verhaeltnisse und
|
|
-- Prozentwerte auf, und ein zweiter Wertetyp je Reihe waere eine Fallgrube.
|
|
value DOUBLE PRECISION NOT NULL,
|
|
-- unit ist die Einheit des Werts.
|
|
--
|
|
-- Sie steht an der Messung und nicht in einer Tabelle daneben: Wer eine
|
|
-- Reihe liest, soll nicht raten muessen, ob 400 Bytes, Kilobytes oder
|
|
-- Prozent meint.
|
|
unit TEXT NOT NULL,
|
|
-- measured_at ist der Zeitpunkt der Messung in UTC.
|
|
measured_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
|
|
-- NaN und Unendlich werden abgelehnt.
|
|
--
|
|
-- Ein einziger solcher Wert verseucht jede Summe und jeden Durchschnitt der
|
|
-- Reihe — das Ergebnis ist danach selbst NaN, ohne dass irgendwo ein Fehler
|
|
-- auftaucht. Aus einer geteilten Null wird so eine Kurve, die nichts mehr
|
|
-- aussagt.
|
|
--
|
|
-- Die Pruefung ist ausdruecklich `value <> 'NaN'` und **nicht** das uebliche
|
|
-- `value = value`: PostgreSQL wertet `NaN = NaN` als wahr, anders als
|
|
-- IEEE 754. Der Standardtrick greift hier also nicht — real geprueft.
|
|
CONSTRAINT metric_samples_value_finite CHECK (
|
|
value <> 'NaN'::float8
|
|
AND value <> 'Infinity'::float8
|
|
AND value <> '-Infinity'::float8
|
|
)
|
|
);
|
|
|
|
-- Der Zugriff erfolgt immer als „diese Reihe, dieser Gegenstand, dieses
|
|
-- Zeitfenster". Der Index bildet genau das ab.
|
|
CREATE INDEX metric_samples_series_idx
|
|
ON metric_samples (metric_name, subject_id, measured_at DESC);
|
|
|
|
-- Fuer das Aufraeumen alter Messungen.
|
|
CREATE INDEX metric_samples_age_idx ON metric_samples (measured_at);
|
|
|
|
-- Zwei Messungen derselben Reihe zum selben Zeitpunkt sind eine Doppelung. Sie
|
|
-- entstuende, wenn zwei Control-Server gleichzeitig sammeln — und verfaelschte
|
|
-- jede Summe.
|
|
CREATE UNIQUE INDEX metric_samples_unique_idx
|
|
ON metric_samples (metric_name, subject_id, measured_at);
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- Repositories: Zeitpunkt der letzten Erfassung
|
|
-- ---------------------------------------------------------------------------
|
|
|
|
ALTER TABLE repositories
|
|
-- metrics_collected_at ist der Zeitpunkt der letzten Kennzahlenerfassung.
|
|
--
|
|
-- Getrennt von last_checked_at: Das eine ist eine Zustandspruefung, das
|
|
-- andere eine Messung. Ein Repository kann erreichbar sein, ohne dass
|
|
-- jemand seinen Fuellstand notiert hat.
|
|
ADD COLUMN metrics_collected_at TIMESTAMPTZ;
|