Upload files to "/"
This commit is contained in:
@@ -0,0 +1,594 @@
|
||||
# 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.**
|
||||
Reference in New Issue
Block a user