Backup & Recovery
This document covers backup procedures for SLOzy's PostgreSQL database and migration management.
PostgreSQL Backup
Using pg_dump
Create a full backup:
bash
pg_dump -h localhost -U slozy_user -d slozy_db -F c -f slozy_backup_$(date +%Y%m%d).dumpFor large databases, use parallel dump with multiple jobs:
bash
pg_dump -h localhost -U slozy_user -d slozy_db -j 4 -F d -f slozy_backup_dir/Using pg_restore
Restore from a custom-format dump:
bash
pg_restore -h localhost -U slozy_user -d slozy_db --clean --if-exists slozy_backup_20260611.dumpRestore with parallel workers:
bash
pg_restore -h localhost -U slozy_user -d slozy_db -j 4 --clean --if-exists slozy_backup_20260611.dumpAutomated Backup Script
bash
#!/bin/bash
BACKUP_DIR="/backups/slozy"
DB_NAME="slozy_db"
DB_USER="slozy_user"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
pg_dump -F c -U $DB_USER -d $DB_NAME -f "$BACKUP_DIR/slozy_$TIMESTAMP.dump"
# Rotate backups older than 30 days
find $BACKUP_DIR -name "slozy_*.dump" -mtime +30 -deleteMigrations
SLOzy uses golang-migrate/migrate for database schema migrations (internal/db/migrations.go).
Running Migrations
go
func RunMigrations(databaseURL string) error {
m, err := migrate.New("file://migrations", databaseURL)
// ...
return m.Up()
}Migration Commands
Apply all pending migrations (handled automatically on application startup):
bash
# Via application startup:
./slozy-web
# Migrations run automatically via RunMigrations()Manual migration commands:
bash
# Apply up migrations
migrate -path migrations/ -database "postgres://slozy_user:password@localhost:5432/slozy_db?sslmode=disable" up
# Rollback one migration
migrate -path migrations/ -database "postgres://slozy_user:password@localhost:5432/slozy_db?sslmode=disable" down 1Migration Files
All 18 migration pairs are located in migrations/:
000001_organizations.up.sql
000001_organizations.down.sql
...
000018_query_cache.up.sql
000018_query_cache.down.sqlSchema Migrations Table
The schema_migrations table tracks applied migration versions. If a migration fails:
- Check the dirty version in
schema_migrations - Manually fix the failing migration SQL
- Mark the migration as applied or force-clean the dirty flag:sql
UPDATE schema_migrations SET dirty = false WHERE version = <version>;
Kubernetes CronJob Backup
From docs/deployment.md — automated backup using a K8s CronJob:
yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: slozy-db-backup
namespace: slozy
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: pg-dump
image: postgres:16-alpine
command:
- /bin/sh
- -c
- |
pg_dump -h postgres-service -U slozy_user \
-d slozy_db -F c \
-f /backups/slozy_$(date +%Y%m%d).dump
env:
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: slozy-secrets
key: database-password
volumeMounts:
- name: backup-storage
mountPath: /backups
restartPolicy: OnFailure
volumes:
- name: backup-storage
persistentVolumeClaim:
claimName: backup-pvcRecovery Checklist
- Stop the application to prevent writes during restore
- Drop and recreate the target database
- Run
pg_restorewith the latest valid backup - Verify the
schema_migrationstable matches expected state - Start the application and run health checks
- Verify SLO data integrity via the dashboard