# /backup-strategies - Scripts e Automação Scripts prontos a usar para backup e disaster recovery. ## MySQL - Dump com Compressão ```bash #!/bin/bash # backup-mysql.sh 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 mkdir -p "$BACKUP_DIR" 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" if [ $? -eq 0 ]; then SIZE=$(du -h "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz" | cut -f1) echo "Backup $DB_NAME: $SIZE" else echo "ERRO ao fazer backup de $DB_NAME" exit 1 fi find "$BACKUP_DIR" -name "${DB_NAME}_*.sql.gz" -mtime +$RETENTION_DAYS -delete ``` **Opções Críticas:** - `--single-transaction`: Consistência sem lock (InnoDB) - `--routines`: Incluir stored procedures - `--hex-blob`: Formato binário seguro para BLOBs **Anti-Patterns:** - `mysqldump database > backup.sql` sem `--single-transaction` - Backup sem compressão - Password na linha de comando ## PostgreSQL - pg_dump ```bash # Backup 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 MySQL com Binlog ```bash # Activar binlog (my.cnf): # [mysqld] # log-bin=/var/log/mysql/mysql-bin.log # expire_logs_days=7 mysqlbinlog --read-from-remote-server --host=localhost \ --start-datetime="2026-02-03 00:00:00" \ mysql-bin.000001 > incremental_backup.sql ``` --- ## Backup WordPress ### Backup Completo ```bash #!/bin/bash # backup-wordpress.sh 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" tar -czf "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" \ --exclude='wp-content/cache' \ --exclude='wp-content/uploads/cache' \ --exclude='wp-content/upgrade' \ --exclude='*.log' \ -C "$(dirname $SITE_PATH)" \ "$(basename $SITE_PATH)" if [ -f "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" ]; then tar -tzf "$BACKUP_DIR/${SITE_NAME}_${DATE}.tar.gz" > /dev/null 2>&1 if [ $? -eq 0 ]; then echo "Backup OK e verificado" else echo "Arquivo corrompido!" exit 1 fi fi find "$BACKUP_DIR" -name "${SITE_NAME}_*.tar.gz" -mtime +7 -delete ``` ### Backup Incremental com rsync ```bash #!/bin/bash SOURCE="/home/ealmeida/emanuelalmeida.pt" BACKUP_BASE="/backups/incremental" DATE=$(date +%Y%m%d) rsync -avz --delete \ --backup --backup-dir="$BACKUP_BASE/delta/$DATE" \ --exclude='wp-content/cache' \ "$SOURCE/" "$BACKUP_BASE/current/" ``` --- ## Backup Servidor CWP ### Backup Conta CWP ```bash /usr/local/cwpsrv/htdocs/resources/scripts/backup_accounts \ --account=username \ --type=full \ --destination=/backups/cwp ``` ### Backup Configurações Servidor ```bash #!/bin/bash BACKUP_DIR="/backups/config" DATE=$(date +%Y%m%d_%H%M%S) tar -czf "$BACKUP_DIR/server_config_${DATE}.tar.gz" \ /etc/nginx \ /etc/apache2 \ /etc/mysql \ /etc/my.cnf \ /etc/php* \ /usr/local/cwpsrv/conf \ /root/.acme.sh/cwp_certs \ /etc/cron* \ /etc/fstab \ /etc/hosts ``` --- ## Rotação GFS (Grandfather-Father-Son) ```bash #!/bin/bash BACKUP_DIR="/backups" HOURLY_KEEP=24 DAILY_KEEP=7 WEEKLY_KEEP=4 MONTHLY_KEEP=12 find "$BACKUP_DIR/hourly" -mtime +1 -delete find "$BACKUP_DIR/daily" -mtime +$DAILY_KEEP -delete find "$BACKUP_DIR/weekly" -mtime +$((WEEKLY_KEEP * 7)) -delete find "$BACKUP_DIR/monthly" -mtime +$((MONTHLY_KEEP * 30)) -delete du -sh "$BACKUP_DIR"/* ``` | Tipo | Retenção | Frequência | |------|----------|------------| | Horário | 24h | A cada hora | | Diário | 7 dias | 1x/dia (00:00) | | Semanal | 4 semanas | 1x/semana | | Mensal | 12 meses | 1x/mês | --- ## Cron 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 ``` --- ## Cloud Sync com rclone ```bash # Instalar rclone curl https://rclone.org/install.sh | sudo bash # Configurar Google Drive rclone config # Nome: gdrive | Tipo: drive | Seguir wizard ``` ```bash #!/bin/bash LOCAL_DIR="/backups" REMOTE="gdrive:backups" rclone sync "$LOCAL_DIR" "$REMOTE" \ --exclude "*.tmp" \ --exclude "*.log" \ --progress ``` --- ## Teste de Restore (OBRIGATÓRIO Mensal) ```bash #!/bin/bash TEST_DB="test_restore_$(date +%Y%m%d)" BACKUP_FILE="/backups/mysql/ealmeida_desk24_latest.sql.gz" mysql -e "CREATE DATABASE $TEST_DB;" gunzip < "$BACKUP_FILE" | mysql "$TEST_DB" TABLES=$(mysql -Nse "SELECT COUNT(*) FROM information_schema.TABLES WHERE table_schema='$TEST_DB';") echo "Tabelas restauradas: $TABLES" mysqlcheck --check "$TEST_DB" | grep -i error mysql -e "DROP DATABASE $TEST_DB;" echo "Teste concluído" ``` --- ## Runbook Disaster 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) - [ ] Comunicar clientes afectados (se downtime >1h) ### Passo 2: Provisionar Servidor (30 min) - [ ] Ubuntu 22.04 ou CentOS 7 - [ ] Instalar CWP: `sh cwp-el7-latest.sh` - [ ] Configurar firewall e SSH ### Passo 3: Restore Bases de Dados (1-2h) ```bash gunzip ealmeida_desk24_20260203_120000.sql.gz mysql -e "CREATE DATABASE ealmeida_desk24;" mysql ealmeida_desk24 < ealmeida_desk24_20260203_120000.sql ``` ### Passo 4: Restore Ficheiros (1-2h) ```bash tar -xzf wordpress_sites_20260203.tar.gz -C /tmp/ cp -r /tmp/emanuelalmeida.pt /home/ealmeida/ chown -R ealmeida:ealmeida /home/ealmeida/emanuelalmeida.pt ``` ### Passo 5: Validação (30 min) - [ ] Testar acesso SSH - [ ] MySQL a responder - [ ] Sites WordPress a carregar - [ ] SSL activo **RTO Total Estimado:** 4-6 horas ```