--- name: backup-strategies description: Backup strategy planning and implementation. Creates backup plans for databases, files, and configurations. Use when user mentions "backup", "backup strategy", "disaster recovery", "backup plan", "restore strategy". author: Descomplicar® Crescimento Digital version: 2.0.0 quality_score: 75 user_invocable: true desk_task: 1463 allowed-tools: Edit --- # /backup-strategies - Backup e Disaster Recovery Implementação de estratégias de backup completas seguindo best practices de RPO/RTO e regra 3-2-1. --- ## Quando Usar - Planear estratégia de backup para novo projecto - Implementar backup automatizado - Configurar disaster recovery - Definir políticas de retenção - Testar procedimentos de restore - Auditar backups existentes - Recuperar de falha/corrupção --- ## Conceitos Core ### RPO vs RTO ``` ┌─────────────────────────────────────────────────┐ │ │ │ INCIDENTE │ │ │ │ │ ├─────────► RPO ◄────┤ │ │ │ (Dados │ │ │ │ perdidos) │ │ │ │ │ │ │ ├─────────────────────►RTO◄────┤ │ │ (Downtime) │ │ │ │ │ │ RECOVERY │ │ COMPLETO │ └─────────────────────────────────────────────────┘ RPO (Recovery Point Objective) = Máximo de dados que pode perder = Frequência mínima de backups RTO (Recovery Time Objective) = Tempo máximo para restaurar = Define tipo de solução DR ``` **Tabela de Decisão:** | Criticidade | RPO | RTO | Solução | Custo | |-------------|-----|-----|---------|-------| | **Crítico** | 0 | <1h | Replicação real-time + hot standby | €€€€ | | **Alto** | 1h | <4h | Backup horário + warm standby | €€€ | | **Médio** | 24h | <24h | Backup diário + cold backup | €€ | | **Baixo** | 7d | <72h | Backup semanal | € | ### Regra 3-2-1 ``` ┌────────────────────────────────────────────────┐ │ REGRA 3-2-1 │ ├────────────────────────────────────────────────┤ │ │ │ 3 → Três cópias dos dados │ │ ├─ Original (produção) │ │ ├─ Backup 1 (local) │ │ └─ Backup 2 (offsite) │ │ │ │ 2 → Dois tipos de media diferentes │ │ ├─ Disco local (NAS/SSD) │ │ └─ Cloud storage (S3/Drive) │ │ │ │ 1 → Uma cópia offsite │ │ └─ Protege contra desastres locais │ │ (incêndio, inundação, roubo) │ │ │ └────────────────────────────────────────────────┘ ``` **Exemplo Implementação:** 1. **Produção:** Servidor CWP (176.9.3.158) 2. **Backup Local:** NAS Synology ou disco externo 3. **Backup Offsite:** Google Drive + S3 (Wasabi) --- ## Estratégias por Tipo de Dados ### 1. Bases de Dados (MySQL/PostgreSQL) #### MySQL - Dump com Compressão ```bash #!/bin/bash # backup-mysql.sh - Backup consistente de BD MySQL # Configuração DB_NAME="ealmeida_desk24" DB_USER="root" DB_PASS="PASSWORD" # Usar ficheiro .my.cnf na prática BACKUP_DIR="/backups/mysql" DATE=$(date +%Y%m%d_%H%M%S) RETENTION_DAYS=7 # Criar directório se não existe mkdir -p "$BACKUP_DIR" # Backup com single-transaction (consistência InnoDB) mysqldump \ --single-transaction \ --routines \ --triggers \ --events \ --hex-blob \ -u "$DB_USER" \ -p"$DB_PASS" \ "$DB_NAME" | gzip -9 > "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz" # Verificar sucesso if [ $? -eq 0 ]; then echo "✅ Backup $DB_NAME concluído: ${BACKUP_DIR}/${DB_NAME}_${DATE}.sql.gz" # Calcular tamanho SIZE=$(du -h "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz" | cut -f1) echo "📦 Tamanho: $SIZE" else echo "❌ ERRO ao fazer backup de $DB_NAME" exit 1 fi # Rotação (eliminar backups >7 dias) find "$BACKUP_DIR" -name "${DB_NAME}_*.sql.gz" -mtime +$RETENTION_DAYS -delete echo "🗑️ Backups antigos eliminados (>$RETENTION_DAYS dias)" # Upload para cloud (opcional) # rclone copy "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz" gdrive:backups/mysql/ ``` **Opções Críticas:** - `--single-transaction`: Consistência sem lock de tabelas (InnoDB) - `--routines`: Incluir stored procedures - `--triggers`: Incluir triggers - `--events`: Incluir events agendados - `--hex-blob`: Formato binário seguro para BLOBs **Anti-Patterns:** - ❌ `mysqldump database > backup.sql` - Sem single-transaction (inconsistente) - ❌ Backup sem compressão (desperdiça espaço) - ❌ Password na linha de comando (inseguro) #### PostgreSQL - pg_dump ```bash # Backup PostgreSQL com compressão máxima pg_dump -Fc -Z9 -d database_name > backup_$(date +%Y%m%d_%H%M%S).dump # Backup de cluster completo pg_dumpall -c | gzip > cluster_backup_$(date +%Y%m%d).sql.gz ``` #### Backup Incremental com Binlog (MySQL) ```bash # Activar binlog (my.cnf) # [mysqld] # log-bin=/var/log/mysql/mysql-bin.log # expire_logs_days=7 # Backup incremental desde último full backup mysqlbinlog --read-from-remote-server --host=localhost \ --start-datetime="2026-02-03 00:00:00" \ mysql-bin.000001 > incremental_backup.sql ``` ### 2. Ficheiros WordPress #### Backup Completo ```bash #!/bin/bash # backup-wordpress.sh - Backup completo de site WordPress SITE_NAME="emanuelalmeida" SITE_PATH="/home/ealmeida/emanuelalmeida.pt" BACKUP_DIR="/backups/wordpress" DATE=$(date +%Y%m%d_%H%M%S) mkdir -p "$BACKUP_DIR" # Backup com exclusões inteligentes tar -czf "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" \ --exclude='wp-content/cache' \ --exclude='wp-content/uploads/cache' \ --exclude='wp-content/upgrade' \ --exclude='wp-content/backup-*' \ --exclude='*.log' \ -C "$(dirname $SITE_PATH)" \ "$(basename $SITE_PATH)" # Validar arquivo criado if [ -f "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" ]; then SIZE=$(du -h "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" | cut -f1) echo "✅ Backup WordPress $SITE_NAME: $SIZE" # Testar integridade tar -tzf "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" > /dev/null 2>&1 if [ $? -eq 0 ]; then echo "✅ Integridade verificada" else echo "❌ Arquivo corrompido!" exit 1 fi else echo "❌ Falha ao criar backup" exit 1 fi # Rotação find "$BACKUP_DIR" -name "${SITE_NAME}_*.tar.gz" -mtime +7 -delete ``` #### Backup Incremental com rsync ```bash #!/bin/bash # backup-incremental-rsync.sh SOURCE="/home/ealmeida/emanuelalmeida.pt" BACKUP_BASE="/backups/incremental" DATE=$(date +%Y%m%d) # Backup incremental (apenas alterações) rsync -avz --delete \ --backup --backup-dir="$BACKUP_BASE/delta/$DATE" \ --exclude='wp-content/cache' \ "$SOURCE/" "$BACKUP_BASE/current/" echo "✅ Backup incremental concluído" echo "📁 Alterações em: $BACKUP_BASE/delta/$DATE" ``` #### Apenas Ficheiros Alterados (Últimas 24h) ```bash # Backup apenas ficheiros modificados hoje find /var/www/html -mtime -1 -type f | \ tar -czf changes_$(date +%Y%m%d).tar.gz -T - ``` ### 3. Servidor CWP Completo #### Backup Conta CWP ```bash # Usar ferramenta nativa CWP /usr/local/cwpsrv/htdocs/resources/scripts/backup_accounts \ --account=username \ --type=full \ --destination=/backups/cwp # Lista de contas cat /etc/passwd | grep '/home/' | cut -d: -f1 ``` #### Backup Configurações Servidor ```bash #!/bin/bash # backup-server-config.sh BACKUP_DIR="/backups/config" DATE=$(date +%Y%m%d_%H%M%S) # Backup de todas as configurações críticas tar -czf "$BACKUP_DIR/server_config_${DATE}.tar.gz" \ /etc/nginx \ /etc/apache2 \ /etc/httpd \ /etc/mysql \ /etc/my.cnf \ /etc/php* \ /usr/local/cwpsrv/conf \ /root/.acme.sh/cwp_certs \ /etc/cron* \ /etc/fstab \ /etc/hosts \ /etc/sysconfig/network-scripts echo "✅ Backup configurações servidor: ${BACKUP_DIR}/server_config_${DATE}.tar.gz" ``` --- ## Retenção Recomendada (GFS - Grandfather-Father-Son) | Tipo | Retenção | Frequência | Slot | |------|----------|------------|------| | **Horário** | 24h | A cada hora | 24 slots | | **Diário** | 7 dias | 1x/dia (00:00) | 7 slots | | **Semanal** | 4 semanas | 1x/semana (domingo) | 4 slots | | **Mensal** | 12 meses | 1x/mês (dia 1) | 12 slots | | **Anual** | 7 anos | 1x/ano (1 janeiro) | 7 slots | **Total slots:** 24 + 7 + 4 + 12 + 7 = **54 backups simultâneos** ### Script de Rotação GFS ```bash #!/bin/bash # backup-rotation-gfs.sh BACKUP_DIR="/backups" # Definir retenção HOURLY_KEEP=24 DAILY_KEEP=7 WEEKLY_KEEP=4 MONTHLY_KEEP=12 # Rotação por tipo echo "🔄 Rotação de backups..." # Horários (manter 24h) find "$BACKUP_DIR/hourly" -mtime +1 -delete echo " Horários: mantidos últimas 24h" # Diários (manter 7 dias) find "$BACKUP_DIR/daily" -mtime +$DAILY_KEEP -delete echo " Diários: mantidos $DAILY_KEEP dias" # Semanais (manter 4 semanas) find "$BACKUP_DIR/weekly" -mtime +$((WEEKLY_KEEP * 7)) -delete echo " Semanais: mantidos $WEEKLY_KEEP semanas" # Mensais (manter 12 meses) find "$BACKUP_DIR/monthly" -mtime +$((MONTHLY_KEEP * 30)) -delete echo " Mensais: mantidos $MONTHLY_KEEP meses" echo "✅ Rotação concluída" # Relatório de espaço du -sh "$BACKUP_DIR"/* ``` --- ## Disaster Recovery ### Checklist DR - [ ] Backups testados (restore funciona?) - [ ] Documentação actualizada (runbook) - [ ] Runbook de recovery acessível offline - [ ] Contactos de emergência definidos - [ ] Acesso offsite confirmado (credenciais) - [ ] Teste DR trimestral agendado - [ ] RTO/RPO documentados - [ ] Plano de comunicação (clientes/equipa) ### Runbook de Recovery ```markdown # 🚨 DISASTER RECOVERY RUNBOOK ## Cenário: Servidor CWP Inoperacional ### Passo 1: Avaliação (5 min) - [ ] Confirmar que servidor não responde (ping, SSH) - [ ] Identificar tipo de falha (hardware, software, ataque) - [ ] Activar equipa de recovery - [ ] Comunicar clientes afectados (se downtime >1h) ### Passo 2: Decisão (10 min) - [ ] Tentar recovery no servidor actual? - [ ] Provisionar novo servidor? - [ ] Activar failover (se existir)? ### Passo 3: Provisionar Servidor (30 min) - [ ] Servidor novo: Ubuntu 22.04 ou CentOS 7 - [ ] Instalar CWP: `sh cwp-el7-latest.sh` - [ ] Configurar firewall e SSH - [ ] Configurar DNS (apontar para novo IP) ### Passo 4: Restore Bases de Dados (1-2h) ```bash # Descomprimir backup mais recente gunzip ealmeida_desk24_20260203_120000.sql.gz # Criar BD mysql -e "CREATE DATABASE ealmeida_desk24;" # Restore mysql ealmeida_desk24 < ealmeida_desk24_20260203_120000.sql # Verificar mysql -e "USE ealmeida_desk24; SHOW TABLES;" ``` ### Passo 5: Restore Ficheiros (1-2h) ```bash # Descomprimir backup sites tar -xzf wordpress_sites_20260203.tar.gz -C /tmp/ # Copiar para CWP cp -r /tmp/emanuelalmeida.pt /home/ealmeida/ # Corrigir permissões chown -R ealmeida:ealmeida /home/ealmeida/emanuelalmeida.pt chmod 755 /home/ealmeida/emanuelalmeida.pt ``` ### Passo 6: Restore Configurações (30 min) ```bash # Descomprimir backup config tar -xzf server_config_20260203.tar.gz -C /tmp/ # Restaurar Nginx/Apache cp -r /tmp/etc/nginx/* /etc/nginx/ cp -r /tmp/etc/httpd/* /etc/httpd/ # Restaurar MySQL config cp /tmp/etc/my.cnf /etc/my.cnf # Restaurar SSL cp -r /tmp/root/.acme.sh/cwp_certs/* /root/.acme.sh/cwp_certs/ ``` ### Passo 7: Validação (30 min) - [ ] Testar acesso SSH - [ ] MySQL a responder - [ ] Apache/Nginx a correr - [ ] Sites WordPress a carregar - [ ] SSL activo - [ ] Email a funcionar (se aplicável) ### Passo 8: DNS Update (2-24h propagação) - [ ] Actualizar DNS A records para novo IP - [ ] Aguardar propagação (verificar: `dig +short domain.pt`) - [ ] Monitorizar logs de acesso ### Passo 9: Comunicação - [ ] Notificar equipa: recovery completo - [ ] Notificar clientes: serviços restaurados - [ ] Documentar lições aprendidas **RTO Total Estimado:** 4-6 horas **RPO:** Depende de frequência de backup (diário = 24h) ``` ### Restore Testing (OBRIGATÓRIO) ```bash #!/bin/bash # test-restore.sh - Testar restore em ambiente isolado TEST_DB="test_restore_$(date +%Y%m%d)" BACKUP_FILE="/backups/mysql/ealmeida_desk24_latest.sql.gz" echo "🧪 TESTE DE RESTORE" echo "===================" # 1. Criar BD de teste mysql -e "CREATE DATABASE $TEST_DB;" echo "✅ BD de teste criada: $TEST_DB" # 2. Restore do backup gunzip < "$BACKUP_FILE" | mysql "$TEST_DB" echo "✅ Backup restaurado" # 3. Validar integridade TABLES=$(mysql -Nse "SELECT COUNT(*) FROM information_schema.TABLES WHERE table_schema='$TEST_DB';") echo "📊 Tabelas restauradas: $TABLES" # 4. Check de tabelas mysqlcheck --check "$TEST_DB" | grep -i error if [ $? -ne 0 ]; then echo "✅ Sem erros detectados" else echo "❌ Erros encontrados!" fi # 5. Verificar dados (exemplo) ROWS=$(mysql -Nse "SELECT COUNT(*) FROM $TEST_DB.tbltasks;") echo "📝 Registos tbltasks: $ROWS" # 6. Tempo de restore echo "⏱️ Tempo restore: calculado acima" # 7. Limpar mysql -e "DROP DATABASE $TEST_DB;" echo "🗑️ BD de teste eliminada" echo "" echo "✅ TESTE CONCLUÍDO - Backup válido e funcional" ``` **Frequência:** Mensal (mínimo) --- ## Automação com Cron ```bash # Editar crontab crontab -e ``` **Exemplo de Schedule:** ```cron # Backup MySQL (diário às 02:00) 0 2 * * * /root/scripts/backup-mysql.sh >> /var/log/backup-mysql.log 2>&1 # Backup WordPress (diário às 03:00) 0 3 * * * /root/scripts/backup-wordpress.sh >> /var/log/backup-wp.log 2>&1 # Backup configurações (semanal, domingo 04:00) 0 4 * * 0 /root/scripts/backup-server-config.sh >> /var/log/backup-config.log 2>&1 # Rotação backups (diário às 05:00) 0 5 * * * /root/scripts/backup-rotation-gfs.sh >> /var/log/backup-rotation.log 2>&1 # Teste de restore (mensal, dia 1 às 06:00) 0 6 1 * * /root/scripts/test-restore.sh >> /var/log/test-restore.log 2>&1 # Sync para cloud (diário às 07:00) 0 7 * * * rclone sync /backups gdrive:backups >> /var/log/rclone-sync.log 2>&1 ``` **Monitorização:** ```bash # Ver últimas execuções tail -50 /var/log/backup-mysql.log # Alertas de falha (adicionar ao script) if [ $? -ne 0 ]; then echo "ERRO: Backup falhou" | mail -s "BACKUP FAILED" admin@domain.com fi ``` --- ## Cloud Sync com rclone ### Configuração ```bash # Instalar rclone curl https://rclone.org/install.sh | sudo bash # Configurar Google Drive rclone config # Nome: gdrive # Tipo: drive # Seguir wizard de autenticação ``` ### Sync Automático ```bash #!/bin/bash # sync-backups-cloud.sh LOCAL_DIR="/backups" REMOTE="gdrive:backups" # Sync (mantém estrutura) rclone sync "$LOCAL_DIR" "$REMOTE" \ --exclude "*.tmp" \ --exclude "*.log" \ --progress echo "✅ Sync para cloud concluído" ``` --- ## Anti-Patterns (EVITAR) | Anti-Pattern | Problema | Solução Correcta | |--------------|----------|------------------| | **Backup sem teste** | Pode falhar no restore | Teste mensal obrigatório | | **Apenas local** | Perda em desastre | Regra 3-2-1 (offsite obrigatório) | | **Sem encriptação** | Dados expostos | Encriptar backups sensíveis | | **Manual** | Esquecimento humano | Automatizar via cron | | **Sem alertas** | Falhas não detectadas | Monitorização + notificações | | **Password no comando** | Inseguro (history, ps) | Usar .my.cnf ou variáveis ENV | | **Backup sem rotação** | Disco cheio | Script de rotação automático | | **Sem documentação** | Caos em emergência | Runbook DR actualizado | --- ## Checklist Implementação Completa ### Planeamento - [ ] RPO/RTO definidos por sistema - [ ] Regra 3-2-1 implementada - [ ] Política de retenção GFS - [ ] Budget aprovado (storage, cloud) ### Automação - [ ] Scripts de backup criados - [ ] Cron jobs configurados - [ ] Rotação automática activa - [ ] Cloud sync activo (rclone) ### Segurança - [ ] Encriptação em backups sensíveis - [ ] Permissões correctas (600/700) - [ ] Passwords em .my.cnf - [ ] Offsite com autenticação 2FA ### Monitorização - [ ] Logs de backup centralizados - [ ] Alertas de falha (email/Slack) - [ ] Dashboard de status (opcional) - [ ] Relatório semanal automático ### Disaster Recovery - [ ] Runbook DR criado e testado - [ ] Teste restore mensal agendado - [ ] Documentação offline acessível - [ ] Equipa treinada - [ ] Contactos de emergência definidos ### Validação - [ ] Primeiro restore teste executado - [ ] RTO medido (tempo real) - [ ] RPO validado (dados perdidos) - [ ] Runbook ajustado conforme teste --- ## Datasets Dify (Consulta Obrigatória) Consultar para aprofundar conhecimento ou resolver casos específicos: | Dataset | ID | Uso | |---------|----|----| | **TI (Tecnologia da Informação)** | `7f63ec0c-6321-488c-b107-980140199850` | Estratégias backup gerais | | **Linux** | `bde4eddd-4618-402c-8bfb-bb947ed9219d` | Scripts rsync, tar, cron | | **CWP Centos Web Panel** | `b2a4d2c5-fe55-412c-bc28-74dbd611905d` | Backup contas CWP | | **AWS (Amazon Web Services)** | `cc7f000a-ad86-49b6-b59b-179e65f8a229` | S3, Glacier, EBS snapshots | **Consultar quando:** - Implementar estratégia backup em nova plataforma - Optimizar scripts de backup existentes - Configurar replicação de dados - Disaster recovery multi-datacenter ```javascript // Exemplo: pesquisar backup incremental MySQL mcp__notebooklm__notebook_query, mcp__dify-kb__dify_kb_retrieve_segments({ dataset_id: "7f63ec0c-6321-488c-b107-980140199850", query: "mysql binlog incremental backup recovery", top_k: 3 }) ``` --- ## Changelog ### v2.0.0 (2026-02-03) - **ENHANCED:** Workflows detalhados para cada tipo de backup - Scripts completos prontos a usar (MySQL, WordPress, CWP) - Runbook DR completo passo-a-passo - GFS retention policy implementada - Automação com cron documentada - Cloud sync com rclone - Teste de restore automatizado - Anti-patterns identificados - Checklist de implementação completa ### v1.0.0 (2026-01-27) - Versão inicial - Conceitos RPO/RTO e regra 3-2-1 - Estratégias básicas por tipo de dados --- **Versão:** 2.0.0 | **Autor:** Descomplicar® **Última actualização:** 2026-02-03 (Scripts prontos + DR Runbook + Automação) --- ## Quando NÃO Usar - Para tarefas fora do domínio de especialização desta skill - Quando outra skill mais específica está disponível - Para operações que requerem aprovação manual obrigatória - Quando os requisitos não estão claramente definidos ## Protocolo de Execução 1. **Análise Inicial** - Verificar requisitos e contexto - Identificar ferramentas necessárias 2. **Preparação** - Validar acesso a recursos - Preparar ambiente de trabalho 3. **Execução** - Executar operações de forma incremental - Validar cada passo antes de prosseguir 4. **Validação** - Verificar resultados obtidos - Confirmar sucesso da operação 5. **Conclusão** - Documentar alterações realizadas - Reportar status final e próximos passos ## Exemplos de Uso ### Exemplo 1: Caso Básico ``` User: [requisição simples relacionada com backup-strategies] Skill: [execução directa com validação] Output: [resultado conciso e accionável] ``` ### Exemplo 2: Caso Complexo ``` User: [requisição multi-passo ou complexa] Skill: 1. Análise dos requisitos 2. Planeamento da abordagem 3. Execução faseada 4. Validação contínua Output: [resultado detalhado com próximos passos] ``` ### Exemplo 3: Caso com Dependências ``` User: [requisição que depende de outros sistemas] Skill: 1. Verificar dependências disponíveis 2. Coordenar com skills/MCPs necessários 3. Executar workflow integrado Output: [resultado completo com referências] ```