Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions backend/RECOVERY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# PetChain Database Recovery Procedures

This document outlines the steps for full restore and Point-In-Time Recovery (PITR) for the PetChain PostgreSQL database.

## 1. Prerequisites
- Access to the backup storage (Base backups and WAL archives).
- Docker environment with `petchain_postgres` container.

## 2. Full Restore (Latest Backup)

Use these steps to restore the database to the state of the most recent base backup.

1. **Stop the Application**:
```bash
docker-compose stop
```

2. **Clear Existing Data**:
```bash
docker volume rm backend_postgres_data
```

3. **Restore Base Backup**:
- Start the postgres container (it will recreate the volume).
- Extract the latest base backup into `/var/lib/postgresql/data`.
```bash
tar -xzf /var/lib/postgresql/data/backups/base_backup_YYYYMMDD_HHMMSS.tar.gz -C /var/lib/postgresql/data
```

4. **Restart Container**:
```bash
docker-compose up -d postgres
```

## 3. Point-In-Time Recovery (PITR)

Use these steps to restore the database to a specific point in time.

1. **Stop the Application and Clear Data** (as above).

2. **Restore Latest Base Backup** (as above).

3. **Create Recovery Configuration**:
- Create a `recovery.signal` file in the data directory.
- Update `postgresql.conf` or add `restore_command`:
```ini
restore_command = 'cp /var/lib/postgresql/data/archive/%f %p'
recovery_target_time = 'YYYY-MM-DD HH:MM:SS'
```

4. **Start PostgreSQL**:
PostgreSQL will read the WAL files from the archive and apply them until it reaches the target time.

5. **Verify Data**:
Once recovery is complete, PostgreSQL will rename `recovery.signal` to `recovery.done` (or just start accepting connections). Verify the data integrity.

## 4. Verification

After any restore operation, run the following:
- Check PostgreSQL logs: `docker logs petchain_postgres`.
- Run application health checks.
- Verify data consistency via the Admin portal.
4 changes: 4 additions & 0 deletions backend/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ services:
- '5432:5432'
volumes:
- postgres_data:/var/lib/postgresql/data
- ./postgresql.conf:/etc/postgresql/postgresql.conf
- postgres_archive:/var/lib/postgresql/data/archive
command: postgres -c 'config_file=/etc/postgresql/postgresql.conf'
networks:
- petchain_network

Expand Down Expand Up @@ -65,6 +68,7 @@ services:

volumes:
postgres_data:
postgres_archive:
redis_data:
clamav_data:

Expand Down
6 changes: 6 additions & 0 deletions backend/postgresql.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Enable WAL archiving for PITR
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /var/lib/postgresql/data/archive/%f && cp %p /var/lib/postgresql/data/archive/%f'
max_wal_senders = 10
archive_timeout = 60
36 changes: 36 additions & 0 deletions backend/scripts/backup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/bash
# Database Backup Script for PetChain

# Configuration
BACKUP_DIR="/var/lib/postgresql/data/backups"
ARCHIVE_DIR="/var/lib/postgresql/data/archive"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="base_backup_${TIMESTAMP}"
RETENTION_DAYS=7

# Ensure backup directory exists
mkdir -p ${BACKUP_DIR}

echo "Starting base backup: ${BACKUP_NAME}..."

# Perform base backup
pg_basebackup -D ${BACKUP_DIR}/${BACKUP_NAME} -Ft -z -X fetch -P

if [ $? -eq 0 ]; then
echo "Base backup successful: ${BACKUP_NAME}"

# Calculate checksum for integrity verification
sha256sum ${BACKUP_DIR}/${BACKUP_NAME}.tar.gz > ${BACKUP_DIR}/${BACKUP_NAME}.sha256

# Cleanup old backups
find ${BACKUP_DIR} -name "base_backup_*" -mtime +${RETENTION_DAYS} -delete

# In production, sync to S3:
# aws s3 sync ${BACKUP_DIR} s3://petchain-backups/
# aws s3 sync ${ARCHIVE_DIR} s3://petchain-wal-archive/
else
echo "Base backup failed!"
exit 1
fi

echo "Backup process complete."
31 changes: 31 additions & 0 deletions backend/scripts/verify-backup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# Backup Integrity Verification Script

BACKUP_DIR="/var/lib/postgresql/data/backups"

echo "Verifying latest backups..."

# Find the most recent backup
LATEST_BACKUP=$(ls -t ${BACKUP_DIR}/base_backup_*.tar.gz | head -n 1)

if [ -z "$LATEST_BACKUP" ]; then
echo "No backups found to verify."
exit 1
fi

CHECKsum_FILE="${LATEST_BACKUP%.tar.gz}.sha256"

if [ ! -f "$CHECKsum_FILE" ]; then
echo "Checksum file missing for ${LATEST_BACKUP}"
exit 1
fi

# Verify checksum
sha256sum -c "$CHECKsum_FILE"

if [ $? -eq 0 ]; then
echo "Integrity verification successful for ${LATEST_BACKUP}"
else
echo "Integrity verification FAILED for ${LATEST_BACKUP}!"
exit 1
fi