Datenbankschema
Dieses Dokument beschreibt das SQLite-Datenbankschema, das von duplistatus zur Speicherung von Sicherungsvorgangsdaten verwendet wird.
Datenbankstandort
Die Datenbank wird im Anwendungsdatenverzeichnis gespeichert:
- Standard-Speicherort:
/app/data/backups.db - Docker-Volume:
duplistatus_data:/app/data - Dateiname:
backups.db
Datenbankmigrationssystem
duplistatus verwendet ein automatisiertes Migrationssystem, um Datenbankschemaänderungen zwischen Versionen zu verwalten.
Migrationsversionsverlauf
Die folgenden sind historische Migrationsversionenen, die die Datenbank in ihren aktuellen Zustand gebracht haben:
- Schema v1.0 (Application v0.6.x und früher): Initiales Datenbankschema mit Tabellen für Server und Sicherungen
- Schema v2.0 (Application v0.7.x): Fehlende Spalten und Konfigurationstabelle hinzugefügt
- Schema v3.0 (Application v0.7.x): Tabelle „machines" in „servers" umbenannt, Spalte „server_url" hinzugefügt
- Schema v3.1 (Application v0.8.x): Sicherungsdatenfelder erweitert, Spalte „server_password" hinzugefügt
- Schema v4.0 (Application v0.9.x / v1.0.x): Benutzerzugriffskontrolle hinzugefügt (Tabellen „users", „sessions", „audit_log")
Die aktuelle Anwendungsversion (v1.3.x) verwendet Schema v4.0 als neueste Datenbankschema-Version.
Migrationsprozess
- Automatische Sicherung: Erstellt eine Sicherung vor der Migration
- Schema-Update: Aktualisiert die Datenbankstruktur
- Datenmigration: Bewahrt vorhandene Daten
- Überprüfung: Bestätigt die erfolgreiche Migration
Tabellen
Server-Tabelle
Speichert Informationen über überwachte Duplicati-Server.
Felder
| Feld | Typ | Beschreibung |
|---|---|---|
id | TEXT PRIMARY KEY | Eindeutige Server-Kennung |
name | TEXT NOT NULL | Servername aus Duplicati |
server_url | TEXT | Duplicati-Server-URL |
alias | TEXT | Benutzerdefinierten Anzeigename |
note | TEXT | Benutzerdefinierte Notizen/Beschreibung |
server_password | TEXT | Server-Passwort zur Authentifizierung |
created_at | DATETIME | Server-Erstellungs-Zeitstempel |
Sicherungen-Tabelle
Speichert Sicherungsvorgangsdaten, die von Duplicati-Servern empfangen werden.
Schlüsselfelder
| Feld | Typ | Beschreibung |
|---|---|---|
id | TEXT PRIMARY KEY | Eindeutige Sicherungs-ID |
server_id | TEXT NOT NULL | Referenz zur Server-Tabelle |
backup_name | TEXT NOT NULL | Name des Sicherungsauftrags |
backup_id | TEXT NOT NULL | Sicherungs-ID von Duplicati |
date | DATETIME NOT NULL | Ausführungszeit der Sicherung |
status | TEXT NOT NULL | Sicherungsstatus (Erfolg, Warnung, Fehler, Kritisch) |
duration_seconds | INTEGER NOT NULL | Dauer in Sekunden |
size | INTEGER | Größe der Quelldateien |
uploaded_size | INTEGER | Größe der hochgeladenen Daten |
examined_files | INTEGER | Anzahl der untersuchten Dateien |
warnings | INTEGER | Anzahl der Warnungen |
errors | INTEGER | Anzahl der Fehler |
created_at | DATETIME | Zeitstempel der Datensatzerstellung |
Message Arrays (JSON Speicherplatz)
| Feld | Typ | Beschreibung |
|---|---|---|
messages_array | TEXT | JSON-Array von Nachrichten |
warnings_array | TEXT | JSON-Array von Warnungsnachrichten |
errors_array | TEXT | JSON-Array von Fehlernachrichten |
available_backups | TEXT | JSON-Array von verfügbaren Sicherungsversionen |
Dateioperations-Felder
| Feld | Typ | Beschreibung |
|---|---|---|
examined_files | INTEGER | Während der Sicherung geprüfte Dateien |
opened_files | INTEGER | Zur Sicherung geöffnete Dateien |
added_files | INTEGER | Neue Dateien zur Sicherung hinzugefügt |
modified_files | INTEGER | In der Sicherung geänderte Dateien |
deleted_files | INTEGER | Aus der Sicherung gelöschte Dateien |
deleted_folders | INTEGER | Aus der Sicherung gelöschte Ordner |
added_folders | INTEGER | Zur Sicherung hinzugefügte Ordner |
modified_folders | INTEGER | In der Sicherung geänderte Ordner |
not_processed_files | INTEGER | Nicht verarbeitete Dateien |
too_large_files | INTEGER | Zu große Dateien zur Verarbeitung |
files_with_error | INTEGER | Dateien mit Fehler |
added_symlinks | INTEGER | Hinzugefügte symbolische Links |
modified_symlinks | INTEGER | Geänderte symbolische Links |
deleted_symlinks | INTEGER | Gelöschte symbolische Links |
Dateigröße-Felder
| Field | Type | Beschreibung |
|---|---|---|
size_of_examined_files | INTEGER | Größe von Dateien, die während der Sicherung überprüft wurden |
size_of_opened_files | INTEGER | Größe von Dateien, die zur Sicherung geöffnet wurden |
size_of_added_files | INTEGER | Größe neuer Dateien, die zur Sicherung hinzugefügt wurden |
size_of_modified_files | INTEGER | Größe von Dateien, die in der Sicherung geändert wurden |
Felder des Betriebsstatus
| Feld | Typ | Beschreibung |
|---|---|---|
parsed_result | TEXT NOT NULL | Analysiertes Operationsergebnis |
main_operation | TEXT NOT NULL | Hauptoperationstyp |
interrupted | BOOLEAN | Ob die Sicherung unterbrochen wurde |
partial_backup | BOOLEAN | Ob die Sicherung teilweise war |
dryrun | BOOLEAN | Ob die Sicherung ein Testlauf war |
version | TEXT | Verwendete Duplicati-Version |
begin_time | DATETIME NOT NULL | Startzeit der Sicherung |
end_time | DATETIME NOT NULL | Endzeit der Sicherung |
warnings_actual_length | INTEGER | Tatsächliche Anzahl der Warnungen |
errors_actual_length | INTEGER | Tatsächliche Anzahl der Fehler |
messages_actual_length | INTEGER | Tatsächliche Anzahl der Nachrichten |
Backend-Statistiken-Felder
| Feld | Typ | Beschreibung |
|---|---|---|
bytes_downloaded | INTEGER | Von Ziel heruntergeladene Bytes |
known_file_size | INTEGER | Bekannte Dateigröße am Ziel |
last_backup_date | DATETIME | Datum der letzten Sicherung am Ziel |
backup_list_count | INTEGER | Anzahl von Sicherungsversionen |
reported_quota_error | BOOLEAN | Kontingentfehler gemeldet |
reported_quota_warning | BOOLEAN | Kontingentwarnung gemeldet |
backend_main_operation | TEXT | Backend-Hauptoperation |
backend_parsed_result | TEXT | Backend-Analyseergebnis |
backend_interrupted | BOOLEAN | Backend-Operation unterbrochen |
backend_version | TEXT | Backend-Version |
backend_begin_time | DATETIME | Startzeit der Backend-Operation |
backend_duration | TEXT | Dauer der Backend-Operation |
backend_warnings_actual_length | INTEGER | Anzahl von Backend-Warnungen |
backend_errors_actual_length | INTEGER | Anzahl von Backend-Fehlern |
Konfigurationstabelle
Speichert Anwendungskonfigurationseinstellungen.
Felder
| Feld | Typ | Beschreibung |
|---|---|---|
key | TEXT PRIMARY KEY NOT NULL | Konfigurationsschlüssel |
value | TEXT | Konfigurationswert (JSON) |
Allgemeine Konfigurationsschlüssel
email_config: E-Mail-Benachrichtigungseinstellungenntfy_config: NTFY-Benachrichtigungseinstellungenoverdue_tolerance: Toleranzeinstellungen für überfällige Sicherungennotification_templates: Vorlagen für Benachrichtigungsmeldungenaudit_retention_days: Aufbewahrungszeitraum für Audit-Logs (Standard: 90 Tage)
Datenbankversionstabelle
Verfolgt die Datenbankschema-Version für Migrationszwecke.
Felder
| Feld | Typ | Beschreibung |
|---|---|---|
version | TEXT PRIMARY KEY | Datenbankversion |
applied_at | DATETIME | Wann die Migration angewendet wurde |
Benutzer-Tabelle
Speichert Benutzerkonteninformationen für Authentifizierung und Zugriffskontrolle.
Felder
| Feld | Typ | Beschreibung |
|---|---|---|
id | TEXT PRIMARY KEY | Eindeutige Benutzerkennung |
username | TEXT UNIQUE NOT NULL | Benutzername zum Anmelden |
password_hash | TEXT NOT NULL | Bcrypt-verschlüsseltes Passwort |
is_admin | BOOLEAN NOT NULL | Ob der Benutzer Admin-Berechtigungen hat |
must_change_password | BOOLEAN | Ob eine Passwortänderung erforderlich ist |
created_at | DATETIME | Zeitstempel der Kontoerstellung |
updated_at | DATETIME | Zeitstempel der letzten Aktualisierung |
last_login_at | DATETIME | Zeitstempel der letzten erfolgreichen Anmeldung |
last_login_ip | TEXT | IP-Adresse der letzten Anmeldung |
failed_login_attempts | INTEGER | Anzahl fehlgeschlagener Anmeldeversuche |
locked_until | DATETIME | Sperrablauf des Kontos (falls gesperrt) |
Sitzungstabelle
Speichert Benutzersitzungsdaten für Authentifizierung und Sicherheit.
Felder
| Feld | Typ | Beschreibung |
|---|---|---|
id | TEXT PRIMARY KEY | Sitzungskennung |
user_id | TEXT | Verweis auf Benutzertabelle (nullable für nicht authentifizierte Sitzungen) |
created_at | DATETIME | Sitzungserstellungs-Zeitstempel |
last_accessed | DATETIME | Letzte Zugriffs-Zeitstempel |
expires_at | DATETIME NOT NULL | Sitzungsablauf-Zeitstempel |
ip_address | TEXT | IP-Adresse des Sitzungsursprungs |
user_agent | TEXT | User-Agent-String |
csrf_token | TEXT | CSRF-Token für die Sitzung |
csrf_expires_at | DATETIME | CSRF-Token-Ablauf |
Audit-Log-Tabelle
Speichert ein Audit-Trail von Benutzeraktionen und Systemereignissen.
Felder
| Feld | Typ | Beschreibung |
|---|---|---|
id | INTEGER PRIMARY KEY AUTOINCREMENT | Eindeutige Audit-Log-Eintrags-ID |
timestamp | DATETIME | Ereigniszeitstempel |
user_id | TEXT | Referenz zur Benutzertabelle (optional) |
username | TEXT | Benutzername zum Zeitpunkt der Aktion |
action | TEXT NOT NULL | Durchgeführte Aktion |
category | TEXT NOT NULL | Kategorie der Aktion (z. B. 'authentication', 'settings', 'backup') |
target_type | TEXT | Zieltyp (z. B. 'server', 'backup', 'user') |
target_id | TEXT | Kennung des Ziels |
details | TEXT | Zusätzliche Details (JSON) |
ip_address | TEXT | IP-Adresse des Anforderers |
user_agent | TEXT | User-Agent-String |
status | TEXT NOT NULL | Status der Aktion ('success', 'failure', 'error') |
error_message | TEXT | Fehlermeldung bei fehlgeschlagener Aktion |
Sitzungsverwaltung
Datenbankgestützter Speicherplatz für Sitzungen
Sitzungen werden in der Datenbank mit In-Memory-Fallback gespeichert:
- Primary Storage: Datenbankgestützte Sitzungstabelle
- Fallback: In-Memory-Speicherplatz (Legacy-Unterstützung oder Fehlerfälle)
- Session ID: Kryptographisch sichere Zufallszeichenkette
- Expiration: Konfigurierbare Sitzungs-Zeitüberschreitung
- CSRF Protection: Cross-Site-Request-Forgery-Schutz
- Automatic Cleanup: Abgelaufene Sitzungen werden automatisch entfernt
Session-API-Endpunkte
POST /api/session: Neue Sitzung erstellenGET /api/session: Vorhandene Sitzung validierenDELETE /api/session: Sitzung beendenGET /api/csrf: CSRF-Token abrufen
Indizes
Die Datenbank enthält mehrere Indizes für optimale Abfrageleistung:
- Primary Keys: Alle Tabellen haben Primary-Key-Indizes
- Foreign Keys: Server-Referenzen in der Sicherungen-Tabelle, Benutzer-Referenzen in Sessions und audit_log
- Query Optimisation: Indizes auf häufig abgefragten Feldern
- Date Indexes: Indizes auf Datumfeldern für zeitbasierte Abfragen
- User Indexes: Benutzername-Index für schnelle Benutzersuchvorgänge
- Session Indexes: Ablauf- und user_id-Indizes für die Sitzungsverwaltung
- Audit Indexes: Zeitstempel-, user_id-, Aktion-, Kategorie- und Status-Indizes für Audit-Abfragen
Beziehungen
- Server → Sicherungen: 1:n-Beziehung
- Benutzer → Sessions: 1:n-Beziehung (Sessions können ohne Benutzer existieren)
- Benutzer → Audit-Log: 1:n-Beziehung (Audit-Einträge können ohne Benutzer existieren)
- Sicherungen → Nachrichten: Eingebettete JSON-Arrays
- Konfigurationen: Schlüssel-Wert-Speicherung
Datentypen
- TEXT: Zeichenkettendaten, JSON-Arrays
- INTEGER: Numerische Daten, Dateizählungen, Größen
- REAL: Gleitkommazahlen, Dauern
- DATETIME: Zeitstempeldaten
- BOOLEAN: Wahr/Falsch-Werte
Sicherungsstatus-Werte
- Erfolg: Sicherung erfolgreich abgeschlossen
- Warnung: Sicherung abgeschlossen mit Warnungen
- Fehler: Sicherung abgeschlossen mit Fehlern
- Kritisch: Sicherung fehlgeschlagen kritisch
Häufig gestellte Anfragen
Neueste Sicherung für einen Server abrufen
SELECT * FROM backups
WHERE server_id = ?
ORDER BY date DESC
LIMIT 1;
Alle Sicherungen für einen Server abrufen
SELECT * FROM backups
WHERE server_id = ?
ORDER BY date DESC;
Server-Zusammenfassung abrufen
SELECT
s.name,
s.alias,
COUNT(b.id) as backup_count,
MAX(b.date) as last_backup,
b.status as last_status
FROM servers s
LEFT JOIN backups b ON s.id = b.server_id
GROUP BY s.id;
Gesamtzusammenfassung abrufen
SELECT
COUNT(DISTINCT s.id) as total_servers,
COUNT(b.id) as total_backups_runs,
COUNT(DISTINCT s.id || ':' || b.backup_name) as total_backups,
COALESCE(SUM(b.uploaded_size), 0) as total_uploaded_size,
(
SELECT COALESCE(SUM(b2.known_file_size), 0)
FROM backups b2
INNER JOIN (
SELECT server_id, MAX(date) as max_date
FROM backups
GROUP BY server_id
) latest ON b2.server_id = latest.server_id AND b2.date = latest.max_date
) as total_storage_used,
(
SELECT COALESCE(SUM(b2.size_of_examined_files), 0)
FROM backups b2
INNER JOIN (
SELECT server_id, MAX(date) as max_date
FROM backups
GROUP BY server_id
) latest ON b2.server_id = latest.server_id AND b2.date = latest.max_date
) as total_backuped_size
FROM servers s
LEFT JOIN backups b ON b.server_id = s.id;
Datenbankbereinigung
-- Delete old backups (older than 30 days)
DELETE FROM backups
WHERE date < datetime('now', '-30 days');
-- Delete servers with no backups
DELETE FROM servers
WHERE id NOT IN (SELECT DISTINCT server_id FROM backups);
JSON-zu-Datenbank-Zuordnung
API-Anforderungstext zu Datenbankspalten-Zuordnung
Wenn Duplicati Sicherungsdaten über HTTP POST sendet, wird die JSON-Struktur auf Datenbankspalten abgebildet:
{
"Data": {
"ExaminedFiles": 15399, // → examined_files
"OpenedFiles": 1861, // → opened_files
"AddedFiles": 1861, // → added_files
"SizeOfExaminedFiles": 11086692615, // → size_of_examined_files
"SizeOfOpenedFiles": 13450481, // → size_of_opened_files
"SizeOfAddedFiles": 13450481, // → size_of_added_files
"SizeOfModifiedFiles": 0, // → size_of_modified_files
"ParsedResult": "Success", // → status
"BeginTime": "2025-04-21T23:45:46.9712217Z", // → begin_time and date
"Duration": "00:00:51.3856057", // → duration_seconds (calculated)
"WarningsActualLength": 0, // → warnings_actual_length
"ErrorsActualLength": 0 // → errors_actual_length
},
"Extra": {
"machine-id": "66f5ffc7ff474a73a3c9cba4ac7bfb65", // → server_id
"machine-name": "WSJ-SER5", // → server name
"backup-name": "WSJ-SER5 Local files", // → backup_name
"backup-id": "DB-2" // → backup_id
}
}
Hinweis: Das Feld size in der Sicherungstabelle speichert SizeOfExaminedFiles und uploaded_size speichert die tatsächliche hochgeladene/übertragene Größe aus dem Sicherungsvorgang.