# Database Migration Guide This guide explains how to export and import the MotoVaultPro database for deployment migration, backups, and disaster recovery. ## Quick Start ### Export Database ```bash # Full database export (compressed SQL) ./scripts/export-database.sh # Schema only (for creating new environments) ./scripts/export-database.sh --schema-only # Specific tables only ./scripts/export-database.sh --include-table vehicles --include-table fuel_logs ``` ### Import Database ```bash # Import into new deployment ./scripts/import-database.sh --create-db database-exports/motovaultpro_export_20250101_120000.sql.gz # Import with existing database backup ./scripts/import-database.sh database-exports/backup.sql.gz # Replace existing database (DANGER!) ./scripts/import-database.sh --drop-existing --force backup.sql.gz ``` ## Export Script ### Location `scripts/export-database.sh` ### Features - Multiple export formats (SQL, custom, directory) - Automatic compression - Schema-only or data-only exports - Table filtering (include/exclude) - Metadata generation - Import instructions generation ### Options ```bash ./scripts/export-database.sh [options] Options: -h, --help Show help message -f, --format FORMAT Export format: sql, custom, directory (default: sql) -o, --output NAME Custom export filename (without extension) -n, --no-compress Don't compress the export --schema-only Export schema only (no data) --data-only Export data only (no schema) --exclude-table TABLE Exclude specific table(s) --include-table TABLE Include only specific table(s) -c, --container NAME Container name (default: mvp-postgres) ``` ### Export Formats #### SQL Format (Default) - Plain text SQL dump - Human-readable - Automatically compressed with gzip - Best for version control and manual review ```bash ./scripts/export-database.sh --format sql ``` #### Custom Format - PostgreSQL custom format - Binary and compressed - Fastest for large databases - Supports parallel restore ```bash ./scripts/export-database.sh --format custom ``` #### Directory Format - Each table in separate file - Best for selective restore - Supports parallel processing ```bash ./scripts/export-database.sh --format directory ``` ### Examples #### Full Production Backup ```bash ./scripts/export-database.sh --output production_backup_$(date +%Y%m%d) ``` #### Schema for New Environment ```bash ./scripts/export-database.sh --schema-only --output schema_template ``` #### Specific Feature Data ```bash ./scripts/export-database.sh \ --include-table vehicles \ --include-table fuel_logs \ --include-table maintenance_records \ --output vehicle_data_backup ``` #### Exclude Large Tables ```bash ./scripts/export-database.sh \ --exclude-table audit_logs \ --exclude-table system_events \ --output core_data_backup ``` ### Output Files Each export creates three files: 1. **Export File** (`.sql.gz`, `.dump`, or `.dir/`) - The actual database dump 2. **Metadata File** (`*_metadata.json`) ```json { "export_timestamp": "2025-01-01T12:00:00Z", "database_name": "motovaultpro", "export_format": "sql", "compressed": true, "schema_included": true, "data_included": true, "postgresql_version": "PostgreSQL 15.x", "file_path": "/path/to/export.sql.gz", "file_size": "5.2M" } ``` 3. **Import Instructions** (`*_import_instructions.txt`) - Step-by-step import guide - Format-specific commands - Database preparation steps ## Import Script ### Location `scripts/import-database.sh` ### Features - Auto-detects export format - Automatic backup before import - Safety confirmations - Database creation - Import verification ### Options ```bash ./scripts/import-database.sh [options] Options: -h, --help Show help message -c, --container NAME Container name (default: mvp-postgres) -d, --database NAME Database name (default: motovaultpro) --create-db Create database if it doesn't exist --drop-existing Drop existing database before import (DANGER!) --no-backup Skip backup of existing database --force Skip confirmation prompts -f, --format FORMAT Import format (auto-detected if not specified) ``` ### Safety Features 1. **Automatic Backup** - Creates backup of existing database before destructive operations - Backup stored in `database-exports/` 2. **Confirmation Prompts** - Requires explicit "yes" for dangerous operations - Can be bypassed with `--force` for automation 3. **Validation** - Verifies export file exists - Checks PostgreSQL container is running - Confirms successful import ### Examples #### Import into New Deployment ```bash # Ensure database doesn't exist ./scripts/import-database.sh --create-db backup.sql.gz ``` #### Import with Backup ```bash # Automatically backs up existing database ./scripts/import-database.sh backup.sql.gz ``` #### Replace Existing Database ```bash # Interactive confirmation required ./scripts/import-database.sh --drop-existing backup.sql.gz # Automated (use with caution!) ./scripts/import-database.sh --drop-existing --force backup.sql.gz ``` #### Import Different Format ```bash # Custom format ./scripts/import-database.sh --format custom backup.dump # Directory format ./scripts/import-database.sh --format directory backup.dir/ ``` ## Deployment Migration Workflow ### 1. Export from Source ```bash # On source server cd /path/to/motovaultpro ./scripts/export-database.sh --output migration_$(date +%Y%m%d) ``` ### 2. Transfer to Target ```bash # Copy export files scp database-exports/migration_*.{sql.gz,json,txt} user@target:/path/to/motovaultpro/database-exports/ ``` ### 3. Import on Target ```bash # On target server cd /path/to/motovaultpro # First time setup ./scripts/import-database.sh --create-db database-exports/migration_20250101.sql.gz # Subsequent imports ./scripts/import-database.sh --drop-existing database-exports/migration_20250101.sql.gz ``` ### 4. Verify Import ```bash # Check table count docker exec mvp-postgres psql -U postgres -d motovaultpro -c "\dt" # Check row counts docker exec mvp-postgres psql -U postgres -d motovaultpro -c " SELECT schemaname, tablename, n_live_tup as rows FROM pg_stat_user_tables ORDER BY n_live_tup DESC; " ``` ## Automated Backups ### Daily Backup Cron Job ```bash # Add to crontab (crontab -e) 0 2 * * * cd /path/to/motovaultpro && ./scripts/export-database.sh --output daily_backup_$(date +%Y%m%d) >> /var/log/motovaultpro-backup.log 2>&1 ``` ### Weekly Full Backup ```bash # Weekly on Sunday at 3 AM 0 3 * * 0 cd /path/to/motovaultpro && ./scripts/export-database.sh --format custom --output weekly_backup_$(date +%Y%m%d) >> /var/log/motovaultpro-backup.log 2>&1 ``` ### Retention Script ```bash # Keep last 7 daily backups and 4 weekly backups find database-exports/ -name "daily_backup_*.sql.gz" -mtime +7 -delete find database-exports/ -name "weekly_backup_*.dump" -mtime +28 -delete ``` ## Troubleshooting ### Export Issues #### Container Not Running ```bash Error: PostgreSQL container 'mvp-postgres' is not running Solution: docker compose up -d mvp-postgres ``` #### Permission Denied ```bash Error: Permission denied: /database-exports/ Solution: chmod +x scripts/export-database.sh mkdir -p database-exports chmod 755 database-exports ``` ### Import Issues #### Database Already Exists ```bash Error: Database 'motovaultpro' does not exist. Use --create-db to create it Solution: ./scripts/import-database.sh --create-db backup.sql.gz ``` #### Import Failed Mid-Way ```bash # Restore from automatic backup ./scripts/import-database.sh --drop-existing database-exports/motovaultpro_backup_*.sql.gz ``` ## Best Practices ### Production Exports 1. **Schedule during low-traffic periods** 2. **Use custom format for large databases** (faster, compressed) 3. **Store exports offsite** (S3, backup server) 4. **Test restores regularly** (monthly verification) 5. **Keep multiple generations** (daily, weekly, monthly) ### Development Imports 1. **Use schema-only for clean environments** 2. **Sanitize production data** before importing to dev 3. **Keep test data exports** for consistent testing 4. **Document data dependencies** between tables ### Security 1. **Encrypt exports in transit** (SCP with SSH keys) 2. **Encrypt exports at rest** (filesystem encryption) 3. **Limit export access** (sudo/docker group only) 4. **Audit export operations** (log all exports) 5. **Rotate encryption keys** regularly ## Advanced Usage ### Incremental Backups For very large databases, use PostgreSQL WAL archiving: ```bash # Enable WAL archiving in postgresql.conf wal_level = replica archive_mode = on archive_command = 'cp %p /path/to/archive/%f' # Base backup docker exec mvp-postgres pg_basebackup -D /backup/base -Ft -z -P # Restore with WAL replay # See PostgreSQL documentation for WAL restore process ``` ### Selective Table Restore ```bash # Export specific table ./scripts/export-database.sh --include-table vehicles --output vehicles_only # Import into existing database (appends data) gunzip -c database-exports/vehicles_only.sql.gz | \ docker exec -i mvp-postgres psql -U postgres -d motovaultpro ``` ### Data Migration Between Versions ```bash # Export from old version ./scripts/export-database.sh --format custom --output migration_v1_to_v2 # Run migrations on target docker exec mvp-backend node dist/_system/migrations/run-all.js # Import data ./scripts/import-database.sh migration_v1_to_v2.dump ``` ## Monitoring ### Export Size Tracking ```bash # Track export sizes over time ls -lh database-exports/*.sql.gz | awk '{print $5, $9}' >> backup-sizes.log ``` ### Import Duration The import script automatically logs duration. For detailed monitoring: ```bash time ./scripts/import-database.sh backup.sql.gz ``` ## Support For issues or questions: 1. Check the import instructions file generated with each export 2. Review logs in `docker logs mvp-postgres` 3. Consult PostgreSQL documentation for pg_dump/pg_restore 4. Create an issue in the project repository