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:

  • Esquema v1.0 (Aplicación v0.6.x y anteriores): Esquema inicial de la base de datos con tablas de máquinas y copias de seguridad
  • Esquema v2.0 (Aplicación v0.7.x): Se agregaron columnas faltantes y la tabla de configuraciones
  • Esquema v3.0 (Aplicación v0.7.x): Se cambió el nombre de la tabla de máquinas a servidores, se agregó la columna server_url
  • Esquema v3.1 (Aplicación v0.8.x): Se mejoraron los campos de datos de copia de seguridad, se agregó la columna server_password
  • Esquema v4.0 (Aplicación v0.9.x / v1.0.x): Se agregó el 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 de Duplicati
server_urlTEXTURL del servidor Duplicati
aliasTEXTNombre descriptivo definido por el usuario
noteTEXTNotas o descripción definida 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 la copia de seguridad
server_idTEXT NOT NULLReferencia a la tabla de servidores
backup_nameTEXT NOT NULLNombre del trabajo de respaldo
backup_idTEXT NOT NULLID de respaldo de Duplicati
dateDATETIME NOT NULLHora de ejecución del respaldo
statusTEXT NOT NULLEstado del respaldo (Éxito, Advertencia, Error, Fatal)
duration_secondsINTEGER NOT NULLDuración en segundos
sizeINTEGERTamaño de los archivos de origen
uploaded_sizeINTEGERTamaño de los datos subidos
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_arrayTEXTMatriz JSON de mensajes de registro
warnings_arrayTEXTMatriz JSON de mensajes de advertencia
errors_arrayTEXTMatriz JSON de mensajes de error
available_backupsTEXTMatriz JSON de versiones de respaldo disponibles

Campos de Operación de Archivos

CampoTipoDescripción
examined_filesINTEGERArchivos examinados durante el respaldo
opened_filesINTEGERArchivos abiertos para respaldo
added_filesINTEGERArchivos nuevos agregados a la copia de seguridad
modified_filesINTEGERArchivos modificados en la copia de seguridad
deleted_filesINTEGERArchivos eliminados de la copia de seguridad
deleted_foldersINTEGERCarpetas eliminadas de la copia de seguridad
added_foldersINTEGERCarpetas agregadas a la copia de seguridad
modified_foldersINTEGERCarpetas modificadas en la copia de seguridad
not_processed_filesINTEGERArchivos no procesados
too_large_filesINTEGERArchivos demasiado grandes para procesar
files_with_errorINTEGERArchivos con errores
added_symlinksINTEGEREnlaces simbólicos agregados
modified_symlinksINTEGEREnlaces simbólicos modificados
deleted_symlinksINTEGEREnlaces simbólicos eliminados

Campos de Tamaño de archivos

CampoTipoDescripción
size_of_examined_filesINTEGERTamaño de los archivos examinados durante la copia de seguridad
size_of_opened_filesINTEGERTamaño de los archivos abiertos para la copia de seguridad
size_of_added_filesINTEGERTamaño de los archivos nuevos agregados a la copia de seguridad
size_of_modified_filesINTEGERTamaño de los archivos modificados en la copia de seguridad

Campos de Estado de Operación

CampoTipoDescripción
parsed_resultTEXT NOT NULLResultado de la operación analizado
main_operationTEXT NOT NULLTipo principal de operación
interruptedBOOLEANIndica si la copia de seguridad se interrumpió
partial_backupBOOLEANIndica si la copia de seguridad fue parcial
dryrunBOOLEANIndica si la copia de seguridad fue una prueba (dry run)
versionTEXTVersión de Duplicati utilizada
begin_timeDATETIME NOT NULLHora de inicio de la copia de seguridad
end_timeDATETIME NOT NULLHora de finalización de la copia de seguridad
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 del archivo conocido en el destino
last_backup_dateDATETIMEFecha del último respaldo en el destino
backup_list_countINTEGERNúmero de versiones de copia de seguridad
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 para copia de seguridad retrasada
  • notification_templates: Plantillas de mensajes de notificación
  • audit_retention_days: Periodo de retención del registro 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 del usuario
usernameTEXT UNIQUE NOT NULLNombre de usuario para inicio de sesión
password_hashTEXT NOT NULLContraseña hasheada con Bcrypt
is_adminBOOLEAN NOT NULLSi el usuario tiene privilegios de administrador
must_change_passwordBOOLEANSi se requiere el cambio de contraseña
created_atDATETIMEMarca de tiempo de creación de la cuenta
updated_atDATETIMEMarca de tiempo de la ú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_attemptsINTEGERCantidad de intentos fallidos de inicio de sesión
locked_untilDATETIMEExpiración del bloqueo de la cuenta (si está bloqueada)

Tabla de Sesiones

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

Campos

CampoTipoDescripción
idTEXT PRIMARY KEYIdentificador de la sesión
user_idTEXTReferencia a la tabla de usuarios (nulo para sesiones no autenticadas)
created_atDATETIMEMarca de tiempo de creación de la sesión
last_accessedDATETIMEMarca de tiempo del último acceso
expires_atDATETIME NOT NULLMarca de tiempo de expiración de la sesión
ip_addressTEXTDirección IP de origen de la sesión
user_agentTEXTCadena del agente de usuario
csrf_tokenTEXTToken CSRF para la sesión
csrf_expires_atDATETIMEExpiración del 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 la entrada en el registro de auditoría
timestampDATETIMEMarca de tiempo del evento
user_idTEXTReferencia a la tabla de usuarios (nullable)
usernameTEXTNombre de usuario en el momento de la acción
actionTEXT NOT NULLAcción realizada
categoryTEXT NOT NULLCategoría de la acción (por ejemplo, 'authentication', 'settings', 'backup')
target_typeTEXTTipo de destino (por ejemplo, 'server', 'backup', 'user')
target_idTEXTIdentificador del destino
detailsTEXTDetalles adicionales (JSON)
ip_addressTEXTDirección IP del solicitante
user_agentTEXTCadena del 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
  • Expiración: Tiempo de espera de sesión configurable
  • Protección CSRF: Protección contra falsificación de solicitudes entre sitios
  • Limpieza automática: Las sesiones expiradas 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: Todas las tablas tienen índices de clave primaria
  • Claves externas: Referencias de servidores en la tabla de copias de seguridad, referencias de usuarios en sesiones y registro_de_auditoría
  • Optimización de consultas: Índices en campos consultados con frecuencia
  • Í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 y user_id para la gestión de sesiones
  • Índices de auditoría: Índices de marca de tiempo, user_id, acción, categoría y estado para consultas de auditoría

Relaciones

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

Tipos de Datos

  • TEXT: Datos de cadena, arrays JSON
  • INTEGER: Datos numéricos, conteos 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.