# WebGIS Poverty Mapping - Backup & Recovery Plan **Version:** 1.0 **Last Updated:** May 2026 **Classification:** Important ## Executive Summary This document outlines the backup and recovery strategy for the WebGIS Poverty Mapping application. It ensures business continuity, data protection, and rapid recovery from data loss or system failures. ### Key Objectives - **Prevent Data Loss:** Regular backups at multiple intervals - **Ensure Business Continuity:** Rapid recovery procedures - **Minimize Downtime:** RTO ≤ 4 hours, RPO ≤ 1 day - **Compliance:** Maintain audit trail and regulatory requirements --- ## 1. Backup Strategy ### 1.1 Backup Schedule | Backup Type | Frequency | Retention | Storage | |-------------|-----------|-----------|---------| | **Full Daily** | Every day at 2:00 AM | 7 days | Local + Network Drive | | **Weekly** | Every Sunday at 3:00 AM | 4 weeks | Local + External HDD | | **Monthly** | First day of month at 4:00 AM | 1 year | External HDD Archive | | **Transaction Log** | Hourly (if available) | 3 days | Local | ### 1.2 Backup Methods #### Method 1: MySQL Dump (Recommended) ```bash # Full database backup mysqldump -u root -p --single-transaction --result-file=/backup/webgis_full_$(date +%Y%m%d).sql webgis_unified # With compression (smaller file) mysqldump -u root -p webgis_unified | gzip > /backup/webgis_full_$(date +%Y%m%d).sql.gz ``` #### Method 2: Scheduled Backup Script Create `/backup/backup.sh`: ```bash #!/bin/bash # Configuration DB_NAME="webgis_unified" DB_USER="root" DB_PASSWORD="YourPassword" BACKUP_DIR="/backup" DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="$BACKUP_DIR/webgis_backup_$DATE.sql" # Create backup echo "Starting backup: $DATE" mysqldump -u $DB_USER -p$DB_PASSWORD $DB_NAME > $BACKUP_FILE # Compress gzip $BACKUP_FILE BACKUP_FILE="${BACKUP_FILE}.gz" # Check file size SIZE=$(du -h $BACKUP_FILE | cut -f1) echo "Backup completed: $BACKUP_FILE ($SIZE)" # Remove old backups (keep 7 days) find $BACKUP_DIR -name "webgis_backup_*.sql.gz" -mtime +7 -delete # Copy to network drive (optional) cp $BACKUP_FILE /mnt/network_backup/ # Verify backup if gzip -t $BACKUP_FILE; then echo "Backup verification: SUCCESS" else echo "Backup verification: FAILED" | mail -s "Backup Failed" admin@example.com fi ``` #### Method 3: Automated Cron Job Edit crontab: ```bash crontab -e ``` Add: ```cron # Daily backup at 2:00 AM 0 2 * * * /backup/backup.sh # Weekly backup (Sunday 3:00 AM) 0 3 * * 0 /backup/backup_weekly.sh # Monthly backup (1st day 4:00 AM) 0 4 1 * * /backup/backup_monthly.sh ``` ### 1.3 Backup Storage #### Local Storage ``` /backup/ ├── webgis_backup_20260520_020000.sql.gz ├── webgis_backup_20260519_020000.sql.gz ├── webgis_backup_20260518_020000.sql.gz └── ... (7 days of daily backups) ``` #### Network Storage ``` /mnt/network_backup/ ├── Daily/ (7 copies) ├── Weekly/ (4 copies) └── Monthly/ (12 copies) ``` #### External HDD - Store weekly and monthly backups - Keep in secure location (fire-proof safe recommended) - Update quarterly ### 1.4 File-Level Backup ```bash # Backup application files tar -czf /backup/webgis_files_$(date +%Y%m%d).tar.gz /var/www/html/webgis/ # Backup PHP configuration tar -czf /backup/php_config_$(date +%Y%m%d).tar.gz /etc/php/ # Backup Apache configuration tar -czf /backup/apache_config_$(date +%Y%m%d).tar.gz /etc/apache2/ ``` --- ## 2. Recovery Procedures ### 2.1 Full Recovery (Complete Restore) **Scenario:** Database completely corrupted or lost **Time to Recover:** 30-60 minutes **Steps:** 1. **Stop Application** ```bash sudo systemctl stop apache2 ``` 2. **Backup Current Database** (if possible) ```bash mysqldump -u root -p webgis_unified > current_backup_$(date +%Y%m%d).sql ``` 3. **Drop Current Database** ```bash mysql -u root -p DROP DATABASE webgis_unified; ``` 4. **Restore from Backup** ```bash # Unzip if compressed gunzip /backup/webgis_backup_20260520.sql.gz # Restore mysql -u root -p < /backup/webgis_backup_20260520.sql ``` 5. **Verify Recovery** ```bash mysql -u root -p USE webgis_unified; SHOW TABLES; SELECT COUNT(*) FROM data_unified; ``` 6. **Restart Application** ```bash sudo systemctl start apache2 ``` 7. **Test Application** - Access http://localhost/webgis/ - Verify data is present - Check recent data ### 2.2 Partial Recovery (Selective Tables) **Scenario:** Only specific tables corrupted **Time to Recover:** 15-30 minutes **Steps:** 1. **Export Specific Table from Backup** ```bash # Extract table from backup gunzip -c /backup/webgis_backup_20260520.sql.gz | \ mysql -u root -p -e "USE webgis_unified; SOURCE /dev/stdin" ``` 2. **Or Restore Specific Table** ```bash # Create temporary database mysql -u root -p -e "CREATE DATABASE temp_restore" # Restore backup to temporary DB mysql -u root -p temp_restore < /backup/webgis_backup_20260520.sql # Copy specific table mysql -u root -p -e " USE webgis_unified; DROP TABLE IF EXISTS data_unified; RENAME TABLE temp_restore.data_unified TO webgis_unified.data_unified; " # Drop temporary DB mysql -u root -p -e "DROP DATABASE temp_restore" ``` ### 2.3 Point-in-Time Recovery (Specific Date/Time) **Scenario:** Need to recover data from specific point in time **Requirements:** Transaction logs or multiple daily backups **Steps:** 1. **Identify Target Point in Time** ```bash # Example: Recover to May 18, 2:00 PM TARGET_DATE="2026-05-18 14:00:00" ``` 2. **Restore Latest Backup Before Target** ```bash # Find appropriate backup ls -la /backup/webgis_backup_20260518*.sql.gz ``` 3. **Restore Full Backup** ```bash mysql -u root -p webgis_unified < /backup/webgis_backup_20260518_020000.sql ``` 4. **Apply Transaction Log** (if available) ```bash # Apply changes up to target time # Requires binary logging to be enabled ``` ### 2.4 Disaster Recovery (System-Wide Failure) **Scenario:** Entire server lost **Time to Recover:** 2-4 hours **Steps:** 1. **Provision New Server** - Install Ubuntu 18.04 LTS - Install Apache, PHP, MySQL 2. **Restore Application Files** ```bash cd /var/www/html/ tar -xzf /external_storage/webgis_files_20260520.tar.gz ``` 3. **Restore Database** ```bash mysql -u root -p < /external_storage/webgis_backup_20260520.sql ``` 4. **Restore Configurations** ```bash tar -xzf /external_storage/apache_config_20260520.tar.gz -C / tar -xzf /external_storage/php_config_20260520.tar.gz -C / ``` 5. **Update Network Configuration** - Update DNS records - Configure IP addresses - Update firewall rules 6. **Start Services** ```bash sudo systemctl start apache2 sudo systemctl start mysql ``` 7. **Verify Everything** - Test website - Check database connectivity - Verify data integrity --- ## 3. Backup Verification ### 3.1 Regular Testing **Monthly Backup Test:** (1st Sunday of each month) ```bash #!/bin/bash # Test backup by restoring to test database echo "Starting monthly backup test..." # Create test database mysql -u root -p -e "DROP DATABASE IF EXISTS webgis_test; CREATE DATABASE webgis_test;" # Restore latest backup LATEST_BACKUP=$(ls -t /backup/webgis_backup_*.sql.gz | head -1) gunzip -c $LATEST_BACKUP | mysql -u root -p webgis_test # Verify RECORD_COUNT=$(mysql -u root -p -e "USE webgis_test; SELECT COUNT(*) FROM data_unified;") if [ "$RECORD_COUNT" -gt 0 ]; then echo "Backup test PASSED - Restored $RECORD_COUNT records" mail -s "Backup Test Passed" admin@example.com else echo "Backup test FAILED" mail -s "ALERT: Backup Test Failed" admin@example.com fi # Cleanup mysql -u root -p -e "DROP DATABASE webgis_test;" ``` ### 3.2 Integrity Checks ```bash # Check backup file integrity gzip -t /backup/webgis_backup_20260520.sql.gz # Verify backup size du -h /backup/webgis_backup_20260520.sql.gz # Test restore to temporary location mysql -u root -p -e "CREATE DATABASE test_restore" gunzip -c /backup/webgis_backup_20260520.sql.gz | mysql -u root -p test_restore mysql -u root -p test_restore -e "SELECT COUNT(*) FROM data_unified" mysql -u root -p -e "DROP DATABASE test_restore" ``` ### 3.3 Audit Trail Verification ```sql -- Verify audit log is being populated SELECT COUNT(*) FROM audit_log; -- Check recent activity SELECT * FROM audit_log ORDER BY changed_at DESC LIMIT 10; -- Verify data consistency SELECT COUNT(*) FROM data_unified; SELECT COUNT(DISTINCT tipe) FROM data_unified; ``` --- ## 4. Retention Policy ### 4.1 Backup Retention | Backup Type | Retention Period | Storage Location | |-------------|-----------------|-----------------| | Daily | 7 days | Local server | | Weekly | 4 weeks | Network drive | | Monthly | 1 year | External HDD | | Quarterly Archive | 7 years | Off-site (optional) | ### 4.2 Data Retention ```sql -- Archive old audit logs (older than 1 year) DELETE FROM audit_log WHERE changed_at < DATE_SUB(NOW(), INTERVAL 1 YEAR); -- Archive old statistics DELETE FROM data_statistics WHERE stat_date < DATE_SUB(CURDATE(), INTERVAL 1 YEAR); ``` ### 4.3 Cleanup Script ```bash #!/bin/bash # Remove backups older than 7 days find /backup -name "webgis_backup_*.sql.gz" -mtime +7 -exec rm {} \; # Remove backups older than 30 days from network drive find /mnt/network_backup -name "webgis_backup_*.sql.gz" -mtime +30 -exec rm {} \; # Archive monthly backups to external HDD (optional) find /backup -name "webgis_backup_*.sql.gz" -mtime +30 -exec cp {} /mnt/external_hdd/archive/ \; ``` --- ## 5. Recovery Time Objectives (RTO/RPO) ### 5.1 Service Level Agreements | Scenario | RTO | RPO | Priority | |----------|-----|-----|----------| | Single record loss | 1 hour | 24 hours | Medium | | Table corruption | 2 hours | 24 hours | High | | Database corruption | 4 hours | 24 hours | Critical | | Complete server failure | 4 hours | 24 hours | Critical | | Ransomware attack | 8 hours | 24 hours | Critical | ### 5.2 Target Metrics - **RTO** (Recovery Time Objective): Max 4 hours to restore full service - **RPO** (Recovery Point Objective): Max 24 hours of data loss acceptable --- ## 6. Disaster Recovery Plan ### 6.1 Contact List | Role | Name | Phone | Email | |------|------|-------|-------| | IT Manager | John Doe | +62-xxx-xxxx | john@example.com | | DBA | Jane Smith | +62-xxx-xxxx | jane@example.com | | System Admin | Bob Johnson | +62-xxx-xxxx | bob@example.com | ### 6.2 Escalation Procedure **Level 1:** System Admin (30 min response) **Level 2:** DBA (1 hour response) **Level 3:** IT Manager (2 hour response) ### 6.3 Communication Plan 1. **Alert Detection** → Automated monitoring system 2. **Notification** → Alert team via email, SMS, Slack 3. **Incident Assessment** → Determine impact and scope 4. **Recovery Execution** → Execute appropriate recovery procedure 5. **Post-Recovery Testing** → Verify system integrity 6. **Communication Update** → Notify stakeholders of status --- ## 7. Backup Checklist - [ ] Daily backup script runs successfully - [ ] Weekly backup performed - [ ] Monthly backup archived - [ ] Backup files are compressed - [ ] Backups are copied to network drive - [ ] Backup verification test passes - [ ] Audit logs are being recorded - [ ] Retention policy enforced - [ ] Off-site backups updated - [ ] Team trained on recovery procedures - [ ] Documentation is current - [ ] Backup location is secure - [ ] Power backup for backup storage - [ ] Network connectivity stable - [ ] External HDD checked monthly --- ## 8. Monitoring & Alerts ### 8.1 Backup Monitoring ```bash #!/bin/bash # Monitor backup completion and send alert BACKUP_DIR="/backup" YESTERDAY=$(date -d '1 day ago' +%Y%m%d) BACKUP_FILE="$BACKUP_DIR/webgis_backup_${YESTERDAY}_*.sql.gz" if [ -f $BACKUP_FILE ]; then SIZE=$(du -h $BACKUP_FILE | cut -f1) echo "Backup found: $BACKUP_FILE ($SIZE)" | mail -s "Backup Status: OK" admin@example.com else echo "ERROR: Backup file not found for $YESTERDAY" | mail -s "ALERT: Backup Failed" admin@example.com fi ``` ### 8.2 Health Checks ```bash # Check database size mysql -u root -p -e " SELECT table_schema as 'Database', ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) as 'Size in MB' FROM information_schema.tables WHERE table_schema = 'webgis_unified' GROUP BY table_schema; " # Check free disk space df -h /backup # Check backup file count ls -1 /backup/webgis_backup_*.sql.gz | wc -l ``` --- ## 9. Documentation ### 9.1 Backup Log Keep record of all backups: ``` Date | Time | Size | Status | Notes 2026-05-20 | 02:00 | 125 MB | SUCCESS | Daily backup 2026-05-19 | 02:00 | 124 MB | SUCCESS | Daily backup 2026-05-18 | 02:00 | 123 MB | SUCCESS | Daily backup 2026-05-17 | 03:00 | 256 MB | SUCCESS | Weekly backup ``` ### 9.2 Recovery Log Record all recovery attempts: ``` Date | Time | Reason | Duration | Result | Notes 2026-05-15 | 10:30 | Test | 45 min | SUCCESS | Monthly test successful 2026-04-15 | 09:00 | Test | 40 min | SUCCESS | Monthly test successful ``` --- ## 10. Revision History | Version | Date | Author | Changes | |---------|------|--------|---------| | 1.0 | May 2026 | Admin | Initial backup plan | --- ## 11. Appendix ### A. Quick Reference ```bash # Create backup mysqldump -u root -p webgis_unified | gzip > backup_$(date +%Y%m%d).sql.gz # Restore backup gunzip -c backup_20260520.sql.gz | mysql -u root -p webgis_unified # List backups ls -lh /backup/webgis_backup_*.sql.gz # Check latest backup ls -t /backup/webgis_backup_*.sql.gz | head -1 # Test backup gzip -t /backup/webgis_backup_20260520.sql.gz # Backup size du -h /backup/webgis_backup_20260520.sql.gz ``` ### B. Resources - MySQL Documentation: https://dev.mysql.com/doc/ - Backup Best Practices: https://dev.mysql.com/doc/refman/5.7/en/backup-and-recovery.html - Linux Backup Tools: man tar, man mysqldump --- **Document Status:** APPROVED **Last Review:** May 20, 2026 **Next Review:** August 20, 2026 **For questions or updates, contact the IT Administrator.**