Ir al contenido principal

Esquema de Base de Datos

Este documento describe el esquema de base de datos SQLite utilizado por duplistatus para almacenar datos de operaciones de backup.

Ubicación de la Base de Datos

La base de datos se almacena en el directorio de datos de la aplicación:

  • Ubicación por defecto: /app/data/backups.db
  • Volumen Docker: duplistatus_data:/app/data
  • Nombre de archivo: backups.db

Sistema de Migración de Base de Datos

duplistatus utiliza un sistema de migración automatizado para gestionar cambios en el esquema de la base de datos entre versiones.

Historial de Versiones de Migración

Las siguientes son versiones históricas de migración que llevaron la base de datos a su estado actual:

  • Schema v1.0 (Aplicación v0.6.x y anteriores): Esquema de base de datos inicial con tablas de máquinas y backups
  • Schema v2.0 (Aplicación v0.7.x): Se añadieron columnas faltantes y tabla de configuraciones
  • Schema v3.0 (Aplicación v0.7.x): Se renombró la tabla de máquinas a servidores, se añadió columna server_url
  • Schema v3.1 (Aplicación v0.8.x): Se mejoraron los campos de datos de backup, se añadió columna server_password
  • Schema v4.0 (Aplicación v0.9.x / v1.0.x): Se añadió Control de Acceso de Usuarios (tablas users, sessions, audit_log)

La versión actual de la aplicación (v1.3.x) utiliza Schema v4.0 como la última versión del esquema de base de datos.

Proceso de Migración

  1. Backup Automático: Crea un backup antes de la migración
  2. Actualización de Esquema: Actualiza la estructura de la base de datos
  3. Migración de Datos: Preserva los datos existentes
  4. Verificación: Confirma la migración exitosa

Tablas

Tabla de Servidores

Almacena información sobre los servidores Duplicati que se están monitoreando.

Campos

CampoTipoDescripción
idTEXT PRIMARY KEYIdentificador único del servidor
nameTEXT NOT NULLNombre del servidor desde Duplicati
server_urlTEXTURL del servidor Duplicati
aliasTEXTNombre descriptivo definido por el usuario
noteTEXTNotas/Descripción definidas por el usuario
server_passwordTEXTContraseña del servidor para autenticación
created_atDATETIMEMarca de tiempo de creación del servidor

Tabla de Backups

Almacena datos de operaciones de backup recibidos de servidores Duplicati.

Campos Clave

CampoTipoDescripción
idTEXT PRIMARY KEYIdentificador único de backup
server_idTEXT NOT NULLReferencia a la tabla de servidores
backup_nameTEXT NOT NULLNombre del trabajo de backup
backup_idTEXT NOT NULLID de backup de Duplicati
dateDATETIME NOT NULLHora de ejecución del backup
statusTEXT NOT NULLEstado del backup (Éxito, Advertencia, Error, Fatal)
duration_secondsINTEGER NOT NULLDuración en segundos
sizeINTEGERTamaño de archivos de origen
uploaded_sizeINTEGERTamaño de datos enviados
examined_filesINTEGERNúmero de archivos examinados
warningsINTEGERNúmero de advertencias
errorsINTEGERNúmero de errores
created_atDATETIMEMarca de tiempo de creación del registro

Matrices de Mensajes (Almacenamiento JSON)

CampoTipoDescripción
messages_arrayTEXTArray JSON de mensajes de registro
warnings_arrayTEXTArray JSON de mensajes de advertencia
errors_arrayTEXTArray JSON de mensajes de error
available_backupsTEXTArray JSON de versiones de backup disponibles

Campos de Operación de Archivos

CampoTipoDescripción
examined_filesINTEGERArchivos examinados durante backup
opened_filesINTEGERArchivos abiertos para backup
added_filesINTEGERArchivos nuevos añadidos a backup
modified_filesINTEGERArchivos modificados en backup
deleted_filesINTEGERArchivos eliminados de backup
deleted_foldersINTEGERCarpetas eliminadas de backup
added_foldersINTEGERCarpetas añadidas a backup
modified_foldersINTEGERCarpetas modificadas en backup
not_processed_filesINTEGERArchivos no procesados
too_large_filesINTEGERArchivos demasiado grandes para procesar
files_with_errorINTEGERArchivos con errores
added_symlinksINTEGEREnlaces simbólicos añadidos
modified_symlinksINTEGEREnlaces simbólicos modificados
deleted_symlinksINTEGEREnlaces simbólicos eliminados

Campos de Tamaño de archivos

CampoTipoDescripción
size_of_examined_filesINTEGERTamaño de archivos examinados durante el backup
size_of_opened_filesINTEGERTamaño de archivos abiertos para el backup
size_of_added_filesINTEGERTamaño de archivos nuevos añadidos al backup
size_of_modified_filesINTEGERTamaño de archivos modificados en el backup

Campos de Estado de Operación

CampoTipoDescripción
parsed_resultTEXT NOT NULLResultado de operación analizado
main_operationTEXT NOT NULLTipo de operación principal
interruptedBOOLEANSi el backup fue interrumpido
partial_backupBOOLEANSi el backup fue parcial
dryrunBOOLEANSi el backup fue una ejecución de prueba
versionTEXTVersión de Duplicati utilizada
begin_timeDATETIME NOT NULLHora de inicio del backup
end_timeDATETIME NOT NULLHora de fin del backup
warnings_actual_lengthINTEGERCantidad real de advertencias
errors_actual_lengthINTEGERCantidad real de errores
messages_actual_lengthINTEGERCantidad real de mensajes

Campos de Estadísticas del Backend

CampoTipoDescripción
bytes_downloadedINTEGERBytes descargados del destino
known_file_sizeINTEGERTamaño de archivos conocido en el destino
last_backup_dateDATETIMEFecha del último backup en el destino
backup_list_countINTEGERNúmero de versiones de backup
reported_quota_errorBOOLEANError de cuota reportado
reported_quota_warningBOOLEANAdvertencia de cuota reportada
backend_main_operationTEXTOperación principal del backend
backend_parsed_resultTEXTResultado analizado del backend
backend_interruptedBOOLEANOperación del backend interrumpida
backend_versionTEXTVersión del backend
backend_begin_timeDATETIMEHora de inicio de la operación del backend
backend_durationTEXTDuración de la operación del backend
backend_warnings_actual_lengthINTEGERCantidad de advertencias del backend
backend_errors_actual_lengthINTEGERCantidad de errores del backend

Tabla de Configuraciones

Almacena la configuración de la aplicación.

Campos

CampoTipoDescripción
keyTEXT PRIMARY KEY NOT NULLClave de configuración
valueTEXTValor de configuración (JSON)

Claves de Configuración Comunes

  • email_config: Configuración de notificaciones por correo electrónico
  • ntfy_config: Configuración de notificaciones NTFY
  • overdue_tolerance: Configuración de tolerancia de backup retrasado
  • notification_templates: Plantillas de mensajes de notificación
  • audit_retention_days: Período de retención del log de auditoría (por defecto: 90 días)

Tabla de Versión de Base de Datos

Realiza un seguimiento de la versión del esquema de la base de datos con fines de migración.

Campos

CampoTipoDescripción
versionTEXT PRIMARY KEYVersión de la base de datos
applied_atDATETIMECuándo se aplicó la migración

Tabla de Usuarios

Almacena información de cuenta de usuario para autenticación y control de acceso.

Campos

CampoTipoDescripción
idTEXT PRIMARY KEYIdentificador único de usuario
usernameTEXT UNIQUE NOT NULLNombre de usuario para iniciar sesión
password_hashTEXT NOT NULLContraseña cifrada con Bcrypt
is_adminBOOLEAN NOT NULLSi el usuario tiene privilegios de admin
must_change_passwordBOOLEANSi el cambio de contraseña es requerido
created_atDATETIMEMarca de tiempo de creación de cuenta
updated_atDATETIMEMarca de tiempo de última actualización
last_login_atDATETIMEMarca de tiempo del último inicio de sesión exitoso
last_login_ipTEXTDirección IP del último inicio de sesión
failed_login_attemptsINTEGERRecuento de intentos de inicio de sesión fallidos
locked_untilDATETIMEExpiración del bloqueo de cuenta (si está bloqueado)

Tabla de Sesiones

Almacena datos de sesión del usuario para autenticación y seguridad.

Campos

CampoTipoDescripción
idTEXT PRIMARY KEYIdentificador de sesión
user_idTEXTReferencia a la tabla de usuarios (anulable para sesiones no autenticadas)
created_atDATETIMEMarca de tiempo de creación de sesión
last_accessedDATETIMEMarca de tiempo de última acceso
expires_atDATETIME NOT NULLMarca de tiempo de expiración de sesión
ip_addressTEXTDirección IP de origen de sesión
user_agentTEXTCadena de agente de usuario
csrf_tokenTEXTToken CSRF para la sesión
csrf_expires_atDATETIMEExpiración de token CSRF

Log de Auditoría

Almacena un registro de auditoría de acciones de usuario y eventos del sistema.

Campos

CampoTipoDescripción
idINTEGER PRIMARY KEY AUTOINCREMENTIdentificador único de entrada del log de auditoría
timestampDATETIMEMarca de tiempo del evento
user_idTEXTReferencia a la tabla de usuarios (anulable)
usernameTEXTNombre de usuario en el momento de la acción
actionTEXT NOT NULLAcción realizada
categoryTEXT NOT NULLCategoría de la acción (p. ej., 'authentication', 'settings', 'backup')
target_typeTEXTTipo de objetivo (p. ej., 'server', 'backup', 'user')
target_idTEXTIdentificador del objetivo
detailsTEXTDetalles adicionales (JSON)
ip_addressTEXTDirección IP del solicitante
user_agentTEXTCadena de agente de usuario
statusTEXT NOT NULLEstado de la acción ('success', 'failure', 'error')
error_messageTEXTMensaje de error si la acción falló

Gestión de Sesiones

Almacenamiento de Sesiones Respaldado por Base de Datos

Las sesiones se almacenan en la base de datos con respaldo en memoria:

  • Almacenamiento Principal: Tabla de sesiones respaldada por base de datos
  • Respaldo: Almacenamiento en memoria (soporte heredado o casos de error)
  • ID de Sesión: Cadena aleatoria criptográficamente segura
  • Vencimiento: Tiempo de espera agotado configurable
  • Protección CSRF: Protección contra falsificación de solicitudes entre sitios
  • Limpieza Automática: Las sesiones vencidas se eliminan automáticamente

Puntos finales de la API de sesión

  • POST /api/session: Crear nueva sesión
  • GET /api/session: Validar sesión existente
  • DELETE /api/session: Destruir sesión
  • GET /api/csrf: Obtener token CSRF

Índices

La base de datos incluye varios índices para un rendimiento óptimo de las consultas:

  • Claves Primarias: Todos los tablas tienen índices de clave primaria
  • Claves Foráneas: Referencias de Servidor en tabla de backups, referencias de Usuario en sesiones y audit_log
  • Optimización de Consultas: Índices en campos consultados frecuentemente
  • Índices de Fecha: Índices en campos de fecha para consultas basadas en tiempo
  • Índices de Usuario: Índice de nombre de usuario para búsquedas rápidas de usuarios
  • Índices de Sesión: Índices de expiración e ID de usuario para gestión de sesiones
  • Índices de Auditoría: Índices de marca de tiempo, ID de usuario, acción, categoría y estado para consultas de auditoría

Relaciones

  • Servidores → Backups: Relación uno a muchos
  • Usuarios → Sesiones: Relación uno a muchos (las sesiones pueden existir sin usuarios)
  • Usuarios → Log de Auditoría: Relación uno a muchos (las entradas de auditoría pueden existir sin usuarios)
  • Backups → Mensajes: Arreglos JSON incrustados
  • Configuraciones: Almacenamiento de clave-valor

Tipos de Datos

  • TEXT: Datos de cadena, matrices JSON
  • INTEGER: Datos numéricos, recuentos de archivos, tamaños
  • REAL: Números de punto flotante, duraciones
  • DATETIME: Datos de marca de tiempo
  • BOOLEAN: Valores verdadero/falso

Estados de Backup

  • Éxito: Backup completado exitosamente
  • Advertencia: Backup completado con advertencias
  • Error: Backup completado con errores
  • Fatal: Backup fallido fatalmente

Consultas Comunes

Obtener el Último Backup para un Servidor

SELECT * FROM backups 
WHERE server_id = ?
ORDER BY date DESC
LIMIT 1;

Obtener Todos los Backups para un Servidor

SELECT * FROM backups 
WHERE server_id = ?
ORDER BY date DESC;

Obtener Resumen del Servidor

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;

Obtener Resumen General

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;

Limpieza de Base de Datos

-- 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);

Asignación de JSON a Base de Datos

Asignación de Cuerpo de Solicitud de API a Columnas de Base de Datos

Cuando Duplicati envía datos de backup a través de HTTP POST, la estructura JSON se asigna a columnas de base de datos:

{
"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
}
}

Nota: El campo size en la tabla de backups almacena SizeOfExaminedFiles y uploaded_size almacena el tamaño real enviado/transferido desde la operación de backup.