169 lines
5.1 KiB
Bash
Executable File
169 lines
5.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# consolidate-clavitor-db-production.sh
|
|
# PRODUCTION VERSION - More conservative than local dev
|
|
# Only removes truly unused tables, keeps operational data
|
|
|
|
set -e
|
|
|
|
DB="${1:-/opt/clavitor-web/clavitor.db}"
|
|
BACKUP="${DB}.backup.$(date +%Y%m%d_%H%M%S)"
|
|
|
|
echo "=== Clavitor DB Production Consolidation ==="
|
|
echo "Target: $DB"
|
|
echo ""
|
|
|
|
# Pre-flight check - show current state
|
|
echo "=== Current State ==="
|
|
sqlite3 "$DB" <<'EOF'
|
|
SELECT "=== Row Counts ===";
|
|
SELECT "accounts: " || COUNT(*) FROM accounts;
|
|
SELECT "domain_scopes: " || COUNT(*) || " (KEEP - used)" FROM domain_scopes;
|
|
SELECT "incidents: " || COUNT(*) FROM incidents;
|
|
SELECT "incident_updates: " || COUNT(*) FROM incident_updates;
|
|
SELECT "login_codes: " || COUNT(*) || " (DROP - ephemeral)" FROM login_codes;
|
|
SELECT "maintenance: " || COUNT(*) || " (KEEP - 149 records)" FROM maintenance;
|
|
SELECT "outages: " || COUNT(*) || " (KEEP - 1 record)" FROM outages;
|
|
SELECT "pops: " || COUNT(*) || " (KEEP - source of truth)" FROM pops;
|
|
SELECT "sessions: " || COUNT(*) || " (DROP - ephemeral)" FROM sessions;
|
|
SELECT "telemetry: " || COUNT(*) || " (KEEP - 676k records)" FROM telemetry;
|
|
SELECT "uptime: " || COUNT(*) || " (KEEP - status page)" FROM uptime;
|
|
SELECT "uptime_daily: " || COUNT(*) || " (KEEP - 351 records)" FROM uptime_daily;
|
|
SELECT "uptime_spans: " || COUNT(*) || " (KEEP - 66 records)" FROM uptime_spans;
|
|
SELECT "vaults: " || COUNT(*) || " (DROP - obsolete)" FROM vaults;
|
|
EOF
|
|
|
|
echo ""
|
|
read -p "Continue with backup and consolidation? (y/N) " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
echo "Aborted."
|
|
exit 1
|
|
fi
|
|
|
|
# Create backup
|
|
echo ""
|
|
echo "=== Creating Backup ==="
|
|
cp "$DB" "$BACKUP"
|
|
echo "✓ Backup: $BACKUP"
|
|
|
|
echo ""
|
|
echo "=== Phase 1: Drop Only Truly Unused Tables ==="
|
|
|
|
# Only drop tables that are definitely not used in production
|
|
# accounts (2 rows) - might be referenced, keep for now
|
|
# login_codes (0 rows) - safe to drop (ephemeral)
|
|
# sessions (3 rows) - safe to drop (ephemeral)
|
|
# vaults (1 row) - obsolete hosted vaults
|
|
|
|
sqlite3 "$DB" <<'EOF'
|
|
PRAGMA foreign_keys = OFF;
|
|
|
|
-- Safe drops (no production data or ephemeral)
|
|
DROP TABLE IF EXISTS login_codes;
|
|
DROP TABLE IF EXISTS sessions;
|
|
DROP TABLE IF EXISTS vaults;
|
|
|
|
PRAGMA foreign_keys = ON;
|
|
EOF
|
|
|
|
echo "✓ Dropped ephemeral tables (login_codes, sessions, vaults)"
|
|
|
|
echo ""
|
|
echo "=== Phase 2: Consolidate Status Tables (Optional) ==="
|
|
|
|
# Check if we should merge maintenance/outages into incidents
|
|
MAINT_COUNT=$(sqlite3 "$DB" "SELECT COUNT(*) FROM maintenance")
|
|
OUTAGE_COUNT=$(sqlite3 "$DB" "SELECT COUNT(*) FROM outages")
|
|
INCIDENT_COUNT=$(sqlite3 "$DB" "SELECT COUNT(*) FROM incidents")
|
|
|
|
echo "Maintenance records: $MAINT_COUNT"
|
|
echo "Outage records: $OUTAGE_COUNT"
|
|
echo "Incident records: $INCIDENT_COUNT"
|
|
|
|
if [[ $INCIDENT_COUNT -eq 0 && ($MAINT_COUNT -gt 0 || $OUTAGE_COUNT -gt 0) ]]; then
|
|
read -p "Merge maintenance ($MAINT_COUNT) and outages ($OUTAGE_COUNT) into incidents? (y/N) " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
|
sqlite3 "$DB" <<'EOF'
|
|
PRAGMA foreign_keys = OFF;
|
|
|
|
-- Migrate maintenance windows to incidents
|
|
INSERT INTO incidents (title, status, date, node_ids, created_at)
|
|
SELECT
|
|
'Maintenance: ' || COALESCE(reason, 'Scheduled'),
|
|
CASE WHEN end_at IS NULL THEN 'active' ELSE 'resolved' END,
|
|
datetime(start_at, 'unixepoch'),
|
|
'',
|
|
COALESCE(start_at, strftime('%s', 'now'))
|
|
FROM maintenance;
|
|
|
|
-- Migrate outages to incidents
|
|
INSERT INTO incidents (title, status, date, node_ids, created_at)
|
|
SELECT
|
|
COALESCE(description, 'Service Outage'),
|
|
CASE
|
|
WHEN status = 'resolved' THEN 'resolved'
|
|
WHEN end_at = '' THEN 'investigating'
|
|
ELSE 'monitoring'
|
|
END,
|
|
start_at,
|
|
node_id,
|
|
COALESCE(strftime('%s', start_at), strftime('%s', 'now'))
|
|
FROM outages;
|
|
|
|
DROP TABLE IF EXISTS maintenance;
|
|
DROP TABLE IF EXISTS outages;
|
|
|
|
PRAGMA foreign_keys = ON;
|
|
EOF
|
|
echo "✓ Merged into incidents"
|
|
else
|
|
echo "Skipped status table merge"
|
|
fi
|
|
else
|
|
echo "Skipped (incidents table has data or no maintenance/outage data)"
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Phase 3: Vacuum and Optimize ==="
|
|
|
|
sqlite3 "$DB" <<'EOF'
|
|
VACUUM;
|
|
ANALYZE;
|
|
EOF
|
|
|
|
echo "✓ Database optimized"
|
|
|
|
echo ""
|
|
echo "=== Final State ==="
|
|
sqlite3 "$DB" ".tables"
|
|
|
|
echo ""
|
|
echo "=== Remaining Tables ==="
|
|
cat <<'TABLEDOCS'
|
|
CORE TABLES:
|
|
- pops: 21 regional POPs (source of truth)
|
|
- telemetry: 676k+ metrics records (operational data)
|
|
- uptime: Daily status per POP (status page)
|
|
- uptime_daily: Aggregated daily uptime (351 records)
|
|
- uptime_spans: Continuous uptime spans (66 records)
|
|
- domain_scopes: 634 domain mappings (feature in use)
|
|
- maintenance: Maintenance windows (149 records) OR merged
|
|
- outages: Outage records (1 record) OR merged
|
|
- incidents: Consolidated incidents
|
|
- incident_updates: Incident timeline
|
|
- accounts: 2 accounts (evaluate if needed)
|
|
|
|
DROPPED:
|
|
- login_codes - ephemeral verification codes
|
|
- sessions - ephemeral web sessions
|
|
- vaults - obsolete hosted vault feature
|
|
|
|
TABLEDOCS
|
|
|
|
echo ""
|
|
echo "=== Done ==="
|
|
echo "Backup: $BACKUP"
|
|
echo ""
|
|
echo "To restore: cp $BACKUP $DB"
|