# Galera Cluster Recovery Runbook Based on June 27, 2026 recovery of total Galera cluster failure (down since June 24 ~14:46 CEST). ## Timeline 1. **June 24 ~14:46** — All 3 Galera nodes crashed simultaneously. Root cause: likely simultaneous network issue preventing inter-node communication → "Failed to reach primary view" → all nodes aborted. 2. **June 27 13:00** — Recovery began. db1 bootstrapped, db2/db3 stopped to resolve SST deadlock. 3. **June 27 13:07** — db2 SST started (mariabackup, ~18GB) 4. **June 27 13:17** — db2 SST completed (~40 min), state=Synced, cluster_size=2 5. **June 27 13:17** — db3 SST started 6. **June 27 ~13:50** — db3 SST completed, cluster_size=3 ## Key Decisions Made ### 1. Bootstrap from Node 1 (no grastate.ini) No `grastate.ini` existed on any node, so no `safe_to_bootstrap` flag. Any node can be chosen. Picked db1 (10.0.30.71). ### 2. Stop db2/db3 to Resolve SST Deadlock Initially tried starting both db2 and db3 after db1 bootstrap. Both entered SST but deadlocked: `"No donor candidates temporarily available in suitable state"`. Solution: stop both, then start them one at a time. ### 3. MaxScale `available_when_donor=true` Without this, MaxScale refused to route to db1 while it was Donor/Desynced serving SST to db2. HA Recorder got `Lost connection to server during query` errors. Setting this flag fixed routing immediately. ### 4. Two HA Restarts Needed First restart failed because MaxScale wasn't routing yet (before `available_when_donor=true`). Second restart after the fix succeeded — Recorder connected, history/logbook loaded. ## Pitfalls Encountered ### PITFALL: `galera_new_cluster` Appears to Timeout `galera_new_cluster` may appear to hang/timeout in the terminal but actually launches mariadbd in the background successfully. Always verify separately with `systemctl is-active` and `mariadb -e "SHOW STATUS LIKE 'wsrep_%'"`. ### PITFALL: Parallel SST Causes Deadlock Starting 2+ nodes simultaneously when only 1 donor exists → all joiners compete for the same donor → donor can't serve multiple SST streams → deadlock → all abort. ### PITFALL: HA Recorder Retries Exhaust Before DB Recovers With `db_max_retries: 20` and 5-second intervals, Recorder gives up after ~100 seconds. If MaxScale isn't routing by then, Recorder shuts down. Requires HA restart after DB is confirmed accessible. ### PITFALL: MaxScale `set server db1 master` Doesn't Work Monitored servers can only have `maintenance`/`drain` set manually. Role assignment is automatic via the galeramon monitor. Don't waste time trying to force roles. ### PITFALL: HA Takes Long to Reach RUNNING State With ~18GB DB, HA's schema migration check (`pre_migrate_schema`) takes significant time. State stays `NOT_RUNNING` for 2-3 minutes. Don't assume failure — check docker logs for actual errors. ## Post-Recovery Cleanup ```bash # Revert available_when_donor maxctrl alter monitor galera-monitor available_when_donor=false # Verify all nodes maxctrl list servers # All should show: "Synced, Running" with no Donor/Desynced # Test HA curl -s "$HA_URL/api/services" -H "Authorization: Bearer $HA_TOKEN" | python3 -c " import sys,json data=json.load(sys.stdin) services=set(s['domain'] for s in data) for d in ['recorder','history','logbook']: print(f'{d}: {\"✓\" if d in services else \"✗\"}') " # Test history data curl -s "$HA_URL/api/history/period?filter_entity_id=sun.sun" -H "Authorization: Bearer $HA_TOKEN" ```