Pular para o conteúdo principal

Esquema do Banco de Dados

Este documento descreve o esquema do banco de dados SQLite usado pelo duplistatus para armazenar dados de operações de backup.

Localização do Banco de Dados​

O banco de dados fica armazenado no diretório de dados da aplicação:

  • Localização Padrão: /app/data/backups.db
  • Volume Docker: duplistatus_data:/app/data
  • Nome do Arquivo: backups.db

Sistema de Migração do Banco de Dados​

O duplistatus usa um sistema de migração automatizado para lidar com alterações no esquema do banco de dados entre versões.

Histórico de Versões de Migração​

A seguir estão as versões históricas de migração que levaram o banco de dados ao seu estado atual:

  • Esquema v1.0 (Aplicação v0.6.x e anteriores): Esquema inicial do banco de dados com as tabelas machines e backups
  • Esquema v2.0 (Aplicação v0.7.x): Adição de colunas ausentes e da tabela configurations
  • Esquema v3.0 (Aplicação v0.7.x): Renomeação da tabela machines para servers, adição da coluna server_url
  • Esquema v3.1 (Aplicação v0.8.x): Aprimoramento dos campos de dados de backup, adição da coluna server_password
  • Esquema v4.0 (Aplicação v0.9.x / v1.0.x): Adição de controle de acesso de usuários (tabelas users, sessions, audit_log)
  • Esquema v4.1 (Aplicação v1.5.x): Adição de api_keys e chaves de configuração padrão para autenticação opcional por chave de API, listas de permissão de IP e limites de upload
  • Esquema v4.2 (Aplicação v1.5.x): Adição do livro-razão daily_summary_deliveries e da configuração padrão daily_summary para notificações opcionais de resumo diário

A versão atual da aplicação (v1.5.x) usa o Esquema v4.2 como a versão mais recente do esquema do banco de dados.

Processo de Migração​

  1. Backup Automático: Cria um backup antes da migração
  2. Atualização do Esquema: Atualiza a estrutura do banco de dados
  3. Migração de Dados: Preserva os dados existentes
  4. Verificação: Confirma o sucesso da migração

Tabelas​

Tabela de Servidores​

Armazena informações sobre os servidores Duplicati monitorados.

Campos​

CampoTipoDescrição
idTEXT PRIMARY KEYIdentificador exclusivo do servidor
nameTEXT NOT NULLNome do Servidor a partir do Duplicati
server_urlTEXTURL do servidor Duplicati
aliasTEXTNome amigável definido pelo usuário
noteTEXTNotas/descrição definidas pelo usuário
server_passwordTEXTSenha do servidor para autenticação
created_atDATETIMETimestamp de criação do servidor

Tabela de Backups​

Armazena dados de operações de backup recebidos dos servidores Duplicati.

Campos principais​

CampoTipoDescrição
idTEXT PRIMARY KEYIdentificador exclusivo do backup
server_idTEXT NOT NULLReferência à tabela de servidores
backup_nameTEXT NOT NULLNome da tarefa de backup
backup_idTEXT NOT NULLID do backup do Duplicati
dateDATETIME NOT NULLHora de execução do backup
statusTEXT NOT NULLStatus do backup (Sucesso, Aviso, Erro, Fatal)
duration_secondsINTEGER NOT NULLDuração em segundos
sizeINTEGERTamanho dos arquivos de origem
uploaded_sizeINTEGERTamanho de dados carregados
examined_filesINTEGERNúmero de arquivos examinados
warningsINTEGERNúmero de avisos
errorsINTEGERNúmero de erros
created_atDATETIMETimestamp de criação do registro

Arrays de mensagens (armazenamento em JSON)​

CampoTipoDescrição
messages_arrayTEXTMatriz JSON de mensagens de log
warnings_arrayTEXTMatriz JSON de mensagens de aviso
errors_arrayTEXTMatriz JSON de mensagens de erro
available_backupsTEXTMatriz JSON de Versões de Backup Disponíveis

Campos de operação de arquivo​

CampoTipoDescrição
examined_filesINTEGERArquivos examinados durante o Backup
opened_filesINTEGERArquivos abertos para Backup
added_filesINTEGERNovos arquivos adicionados ao Backup
modified_filesINTEGERArquivos modificados no Backup
deleted_filesINTEGERArquivos excluídos do Backup
deleted_foldersINTEGERPastas excluídas do Backup
added_foldersINTEGERPastas adicionadas ao Backup
modified_foldersINTEGERPastas modificadas no Backup
not_processed_filesINTEGERArquivos não processados
too_large_filesINTEGERArquivos grandes demais para processar
files_with_errorINTEGERArquivos com erros
added_symlinksINTEGERLinks simbólicos adicionados
modified_symlinksINTEGERLinks simbólicos modificados
deleted_symlinksINTEGERLinks simbólicos excluídos

Campos de Tamanho do Arquivo​

CampoTipoDescrição
size_of_examined_filesINTEGERTamanho dos arquivos examinados durante o backup
size_of_opened_filesINTEGERTamanho dos arquivos abertos para backup
size_of_added_filesINTEGERTamanho dos novos arquivos adicionados ao backup
size_of_modified_filesINTEGERTamanho dos arquivos modificados no backup

Campos de Status da Operação​

CampoTipoDescrição
parsed_resultTEXT NOT NULLResultado analisado da operação
main_operationTEXT NOT NULLTipo principal de operação
interruptedBOOLEANSe o backup foi interrompido
partial_backupBOOLEANSe o backup foi parcial
dryrunBOOLEANSe o backup foi uma simulação
versionTEXTVersão do Duplicati utilizada
begin_timeDATETIME NOT NULLHora de início do backup
end_timeDATETIME NOT NULLHora de término do backup
warnings_actual_lengthINTEGERContagem real de avisos
errors_actual_lengthINTEGERContagem real de erros
messages_actual_lengthINTEGERContagem real de mensagens

Campos de Estatísticas do Backend​

CampoTipoDescrição
bytes_downloadedINTEGERBytes baixados do destino
known_file_sizeINTEGERTamanho de arquivo conhecido no destino
last_backup_dateDATETIMEData do Último Backup no destino
backup_list_countINTEGERNúmero de versões de backup
reported_quota_errorBOOLEANErro de cota relatado
reported_quota_warningBOOLEANAviso de cota relatado
backend_main_operationTEXTOperação principal do backend
backend_parsed_resultTEXTResultado analisado do backend
backend_interruptedBOOLEANOperação do backend interrompida
backend_versionTEXTVersão do backend
backend_begin_timeDATETIMEHora de início da operação do backend
backend_durationTEXTDuração da operação do backend
backend_warnings_actual_lengthINTEGERContagem de Avisos do backend
backend_errors_actual_lengthINTEGERContagem de Erros do backend

Tabela Configurations​

Armazena as definições de configuração do aplicativo.

Campos​

CampoTipoDescrição
keyTEXT PRIMARY KEY NOT NULLChave de configuração
valueTEXTValor de configuração (JSON)

Chaves de Configuração Comuns​

  • email_config: Configurações de notificação por E-mail
  • ntfy_config: Configurações de notificação por NTFY
  • overdue_tolerance: Configurações de tolerância de Backup Atrasado
  • notification_templates: Modelos de mensagens de notificação
  • daily_summary: Modo do Resumo Diário, agendamento, fuso horário, URL do painel público opcional e substituição opcional de Destinatário SMTP (smtpRecipient; se vazio, usa as Configurações de E-mail)
  • cron_service: Agendamentos de tarefas cron, incluindo daily-summary-dispatch (minute hour * * * de daily_summary.utcTime)
  • audit_retention_days: Período de Retenção de Log de Auditoria (Padrão: 90 dias)

Tabela de Versão do Banco de Dados​

Rastreia a versão do esquema do banco de dados para fins de migração.

Campos​

CampoTipoDescrição
versionTEXT PRIMARY KEYVersão do banco de dados
applied_atDATETIMEQuando a migração foi aplicada

Tabela de Usuários​

Armazena informações de conta de usuário para autenticação e controle de acesso.

Campos​

CampoTipoDescrição
idTEXT PRIMARY KEYIdentificador único de usuário
usernameTEXT UNIQUE NOT NULLNome de usuário para login
password_hashTEXT NOT NULLSenha com hash Bcrypt
is_adminBOOLEAN NOT NULLSe o usuário possui privilégios de administrador
must_change_passwordBOOLEANSe a alteração de senha é obrigatória
created_atDATETIMETimestamp de criação da conta
updated_atDATETIMETimestamp de última atualização
last_login_atDATETIMETimestamp do último login bem-sucedido
last_login_ipTEXTEndereço IP do último login
failed_login_attemptsINTEGERContagem de tentativas de login com falha
locked_untilDATETIMEExpiração do bloqueio da conta (se bloqueado)

Tabela de Sessões​

Armazena dados de sessão do usuário para autenticação e segurança.

Campos​

CampoTipoDescrição
idTEXT PRIMARY KEYIdentificador da sessão
user_idTEXTReferência à tabela de usuários (anulável para sessões não autenticadas)
created_atDATETIMETimestamp de criação da sessão
last_accessedDATETIMETimestamp do último acesso
expires_atDATETIME NOT NULLTimestamp de expiração da sessão
ip_addressTEXTEndereço IP de origem da sessão
user_agentTEXTString de Agente do Usuário
csrf_tokenTEXTToken CSRF para a sessão
csrf_expires_atDATETIMEExpiração do token CSRF

Tabela de Log de Auditoria​

Armazena a trilha de auditoria de ações do usuário e eventos do sistema.

Campos​

CampoTipoDescrição
idINTEGER PRIMARY KEY AUTOINCREMENTIdentificador exclusivo da entrada do log de auditoria
timestampDATETIMETimestamp do evento
user_idTEXTReferência à tabela de usuários (anulável)
usernameTEXTNome de usuário na hora da ação
actionTEXT NOT NULLAção realizada
categoryTEXT NOT NULLCategoria da ação (ex.: 'authentication', 'settings', 'backup')
target_typeTEXTTipo de destino (por exemplo, 'server', 'backup', 'user')
target_idTEXTIdentificador do destino
detailsTEXTDetalhes adicionais (JSON)
ip_addressTEXTEndereço IP do solicitante
user_agentTEXTString de Agente do Usuário
statusTEXT NOT NULLStatus da ação ('success', 'failure', 'error')
error_messageTEXTMensagem de erro se a ação falhou

Tabela de Chaves de API​

Armazena chaves de API com hash para as APIs HTTP externas. O segredo em texto simples é exibido uma vez na criação e nunca é armazenado.

Campos​

CampoTipoDescrição
idTEXT PRIMARY KEYIdentificador exclusivo de chave
nameTEXT NOT NULLNome de exibição
key_hashTEXT UNIQUEHash SHA-256 do segredo
key_prefixTEXTQuatro primeiros caracteres do segredo (para impressões digitais)
key_suffixTEXTQuatro últimos caracteres do segredo (para impressões digitais)
scopeTEXT NOT NULLupload ou read
descriptionTEXTDescrição opcional
enabledINTEGER1 quando a chave estiver ativa
created_atDATETIMETimestamp de criação
created_byTEXTID de usuário do administrador que criou a chave
expires_atDATETIMEExpiração opcional
last_used_atDATETIMEÚltimo uso bem-sucedido
usage_countINTEGERContagem de usos bem-sucedidos

Chaves de configuração relacionadas na tabela configurations: external_api_require_api_key, ip_trusted_proxies, admin_ip_allowlist, external_api_ip_allowlist, upload_limits.

Tabela de Entregas do Resumo Diário​

Registro por canal para a entrega de e-mail do Resumo Diário. Linhas legadas podem incluir um canal ntfy de versões anteriores. Cada ocorrência agendada (ou envio manual exclusivo) tem no máximo uma linha por canal. Os payloads renderizados são armazenados antes do envio para que as novas tentativas mantenham o mesmo snapshot. Linhas com mais de 30 dias são removidas.

Se o processo for encerrado após um provedor aceitar uma mensagem, mas antes de o sucesso ser registrado, esse canal poderá ser tentado novamente (pelo menos uma vez).

Campos​

CampoTipoDescrição
idTEXT PRIMARY KEYIdentificador exclusivo de entrega
occurrence_keyTEXT NOT NULLChave agendada scheduled:UTC:{date}:{HH:mm} ou manual:{uuid}
channelTEXT NOT NULLemail ou ntfy
triggerTEXT NOT NULLscheduled, manual ou retry
summary_dateTEXT NOT NULLData do calendário local para o snapshot
time_zoneTEXT NOT NULLFuso horário IANA salvo
payload_jsonTEXTCampos renderizados de assunto, HTML, texto e NTFY
stateTEXT NOT NULLpending, sending, sent ou failed
attempt_countINTEGERTentativas de entrega
next_retry_atDATETIMEQuando um canal com falha pode ser reivindicado novamente
lease_expires_atDATETIMEConcessão de reivindicação; uma concessão obsoleta pode ser recuperada
errorTEXTÚltimo erro, se houver
created_atDATETIMETimestamp de criação da linha
updated_atDATETIMETimestamp de última atualização
sent_atDATETIMETimestamp de sucesso

Um índice exclusivo em (occurrence_key, channel) evita envios duplicados da mesma ocorrência no mesmo canal.

Gerenciamento de Sessão​

Armazenamento de Sessão Baseado em Banco de Dados​

As sessões são armazenadas no banco de dados com fallback em memória:

  • Armazenamento Primário: Tabela de sessões baseada em banco de dados
  • Fallback: Armazenamento em memória (suporte a legado ou casos de erro)
  • ID de Sessão: Cadeia de caracteres aleatória criptograficamente segura
  • Expiração: Tempo limite de sessão configurável
  • Proteção contra CSRF: Proteção contra cross-site request forgery
  • Limpeza Automática: Sessões expiradas são removidas automaticamente

Endpoints da API de Sessão​

  • POST /api/session: Cria uma nova sessão
  • GET /api/session: Valida a sessão existente
  • DELETE /api/session: Destrói a sessão
  • GET /api/csrf: Obtém o token CSRF

Índices​

O banco de dados inclui vários índices para otimizar o desempenho das consultas:

  • Chaves Primárias: Todas as tabelas possuem índices de chave primária
  • Chaves Estrangeiras: Referências de servidor na tabela de backups, referências de usuário em sessions e audit_log
  • Otimização de Consultas: Índices em campos consultados com frequência
  • Índices de Data: Índices em campos de data para consultas baseadas em tempo
  • Índices de Usuário: Índice de nome de usuário para buscas rápidas de usuários
  • Índices de Sessão: Índices de expiração e user_id para gerenciamento de sessões
  • Índices de Auditoria: Índices de timestamp, user_id, action, category e status para consultas de auditoria
  • Índices de Chave de API: Hash exclusivo, além de buscas por habilitado/escopo para autenticação

Relacionamentos​

  • Servidores → Backups: Relacionamento de um para muitos
  • Usuários → Sessões: Relacionamento de um para muitos (as sessões podem existir sem usuários)
  • Usuários → Log de Auditoria: Relacionamento de um para muitos (entradas de auditoria podem existir sem usuários)
  • Usuários → Chaves de API: Relacionamento de um para muitos via created_by (as chaves permanecem após a exclusão do usuário)
  • Backups → Mensagens: Matrizes JSON incorporadas
  • Configurações: Armazenamento chave-valor

Tipos de Dados​

  • TEXT: Dados de cadeia de caracteres, matrizes JSON
  • INTEGER: Dados numéricos, contagens de arquivos, tamanhos
  • REAL: Números de ponto flutuante, durações
  • DATETIME: Dados de timestamp
  • BOOLEAN: Valores true/false

Valores de Status de Backup​

  • Sucesso: Backup concluído com sucesso
  • Aviso: Backup concluído com avisos
  • Erro: Backup concluído com erros
  • Fatal: Backup falhou fatalmente

Consultas Comuns​

Obter o Backup Mais Recente de um Servidor​

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

Obter todos os backups de um Servidor​

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

Obter Resumo do 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;

Obter Resumo Geral​

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;

Limpeza do Banco de Dados​

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

Mapeamento de JSON para o Banco de Dados​

Mapeamento do Corpo da Requisição da API para Colunas do Banco de Dados​

Quando o Duplicati envia dados de backup via HTTP POST, a estrutura JSON é mapeada para as colunas do banco de dados:

{
"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: O campo size na tabela de backups armazena SizeOfExaminedFiles e uploaded_size armazena o tamanho real enviado/transferido da operação de backup.