Database Tooling

This commit is contained in:
Eric Gullickson
2025-11-02 09:37:58 -06:00
parent 7b753f080c
commit a0748ced5b
10 changed files with 1363 additions and 1 deletions

419
docs/DATABASE-MIGRATION.md Normal file
View File

@@ -0,0 +1,419 @@
# 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] <export-file>
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