{"id":46491945,"url":"https://github.com/afleonardo/failover-bd","last_synced_at":"2026-03-06T11:01:25.961Z","repository":{"id":324609029,"uuid":"1097797726","full_name":"AFLeonardo/FailOver-BD","owner":"AFLeonardo","description":"FailOver automatico con python utilizando contenedores en Docker.","archived":false,"fork":false,"pushed_at":"2025-11-25T18:50:28.000Z","size":34,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-29T00:35:30.703Z","etag":null,"topics":["docker","docker-compose","failover-automation","mysql","python"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AFLeonardo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-16T20:52:06.000Z","updated_at":"2025-11-22T01:21:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/AFLeonardo/FailOver-BD","commit_stats":null,"previous_names":["afleonardo/failover-bd"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/AFLeonardo/FailOver-BD","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AFLeonardo%2FFailOver-BD","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AFLeonardo%2FFailOver-BD/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AFLeonardo%2FFailOver-BD/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AFLeonardo%2FFailOver-BD/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AFLeonardo","download_url":"https://codeload.github.com/AFLeonardo/FailOver-BD/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AFLeonardo%2FFailOver-BD/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30173345,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T07:56:45.623Z","status":"ssl_error","status_checked_at":"2026-03-06T07:55:55.621Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-compose","failover-automation","mysql","python"],"created_at":"2026-03-06T11:01:17.402Z","updated_at":"2026-03-06T11:01:25.952Z","avatar_url":"https://github.com/AFLeonardo.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📘 Sistema de Failover + Resync Automático para MySQL con Docker\n\n**Autor:** Leonardo  \n**Objetivo del proyecto:** Implementar un sistema de Alta Disponibilidad (HA) para MySQL utilizando Docker Compose, con:  \n- Failover automático  \n- Replicación asíncrona  \n- Resincronización cuando un nodo vuelve  \n- Watcher en Python  \n- Servicio de resync dedicado  \n- API con FastAPI + dashboard web\n\n\n\n## 🛠 Tech Stack\n\n\u003cdiv align=\"center\"\u003e\n\n| Docker | MySQL | Python | FastAPI | Bash | TailwindCSS | JavaScript | HTML5 |\n|--------|--------|---------|---------|--------|--------------|------------|--------|\n| \u003cimg src=\"https://cdn.jsdelivr.net/gh/devicons/devicon/icons/docker/docker-original.svg\" width=\"60\"/\u003e | \u003cimg src=\"https://cdn.jsdelivr.net/gh/devicons/devicon/icons/mysql/mysql-original.svg\" width=\"60\"/\u003e | \u003cimg src=\"https://cdn.jsdelivr.net/gh/devicons/devicon/icons/python/python-original.svg\" width=\"60\"/\u003e | \u003cimg src=\"https://cdn.jsdelivr.net/gh/devicons/devicon/icons/fastapi/fastapi-original.svg\" width=\"55\"/\u003e | \u003cimg src=\"https://cdn.jsdelivr.net/gh/devicons/devicon/icons/bash/bash-original.svg\" width=\"60\"/\u003e | \u003cimg src=\"https://www.vectorlogo.zone/logos/tailwindcss/tailwindcss-icon.svg\" width=\"60\"/\u003e | \u003cimg src=\"https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg\" width=\"60\"/\u003e | \u003cimg src=\"https://cdn.jsdelivr.net/gh/devicons/devicon/icons/html5/html5-original.svg\" width=\"60\"/\u003e |\n\n\n\n\n\u003c/div\u003e\n\n\n\n## 🏗 Arquitectura General\n\nEl sistema está formado por **contenedores Docker** definidos en `docker-compose.yml`:\n\n- **mysql-primary** → Nodo principal (PRIMARY)  \n- **mysql-replica** → Nodo secundario (REPLICA) sincronizado por binlogs  \n- **db-watcher** → Servicio Python que monitoriza y dispara el failover  \n- **db-resync** → Servicio Python que resincroniza nodos desactualizados  \n- **fastapi-dashboard** → API FastAPI + dashboard web (HTML estático)\n\n\n## 📐 Diagrama general\n\n```\n                         ┌─────────────────────────────┐\n                         │     fastapi-dashboard       │\n                         │   - FastAPI (API REST)      │\n                         │   - Dashboard HTML          │\n                         └─────────────┬───────────────┘\n                                       │\n                               Usuario / Navegador\n                                       │\n                     ┌─────────────────┴─────────────────┐\n                     │                                   │\n        ┌────────────────────────┐           ┌────────────────────────┐\n        │      mysql-primary     │           │     mysql-replica      │\n        │      Role: PRIMARY     │◄────────►│     Role: REPLICA      │\n        │  Binlogs habilitados   │           │ IO/SQL threads activos │\n        └─────────────┬──────────┘           └─────────────┬──────────┘\n                      │                                    │\n                      └──────────────┬─────────────────────┘\n                                     │\n                      ┌────────────────────────────┐\n                      │        db-watcher          │\n                      │  - Heartbeat               │\n                      │  - Failover automático     │\n                      │  - Registro de eventos     │\n                      └────────────────────────────┘\n\n                      ┌────────────────────────────┐\n                      │         db-resync          │\n                      │  - Dump/restore            │\n                      │  - Reconfig. replicación   │\n                      └────────────────────────────┘\n```\n\n\n\n## ⚙️ Flujo de Failover y Recovery\n\n### 🟥 **Cuando el primary cae**\n\n1. `db-watcher` deja de recibir respuesta de `mysql-primary`.  \n2. Marca el primary como **DOWN**.  \n3. Promueve `mysql-replica` → **PRIMARY** lógico.  \n4. Detiene replicación (IO/SQL threads).  \n5. Registra el evento en los logs (accesible desde la API/dashboard).\n\n\n### 🟩 **Cuando el nodo caído vuelve**\n\n1. El nodo puede regresar **desactualizado** respecto al nuevo primary.  \n2. `db-watcher` activa el proceso `db-resync`.  \n3. Se toma un **dump** del nodo saludable.  \n4. Se restaura en el nodo que regresó.  \n5. Se reconfigura la replicación (usuario, host, log_file, log_pos).  \n6. Se reinician los IO/SQL threads.  \n7. Los estados son actualizados y registrados.\n\n\n## 🚀 Levantar el proyecto\n\nAsegúrate de tener Docker y Docker Compose instalados.\n\n```bash\ngit clone https://github.com/AFLeonardo/FailOver-BD.git\ncd FailOver-BD\n\n# Levantar todos los servicios\ndocker-compose up -d --build\n\n# Ver contenedores\ndocker ps\n```\n\nDebes ver:\n```\nmysql-primary\nmysql-replica\ndb-watcher\ndb-resync\nfastapi-dashboard\n```\n\n# Comandos importantes\n\n### 🛑 Apagar el primary\n\n```bash\ndocker stop mysql-primary\n```\nEsto simula una caída real.\n#### `db-watcher` debe promover la réplica automáticamente.\n\n### Comandos para Logs:\n\n```bash\ndocker logs -f db-watcher\ndocker logs -f db-resync\ndocker logs -f fastapi-dashboard\n```\n\n\n## 🆗 Encender nuevamente el primary\n\n```bash\ndocker start mysql-primary\n```\n\n#### Ahora `db-resync` entra en acción:\n\n```bash\ndocker logs -f db-resync\n```\n\nDebe verse:\n\n```\n📦 Iniciando backup...\n✅ Backup y restore completados.\n🔁 Restaurando topología...\n```\n\n\n## 🌐 Acceso al Dashboard y la API\n\n### Dashboard web (HTML estático)\n```\nhttp://localhost:8000/static/dashboard.html\n```\n\n### FastAPI docs (Swagger UI)\n```\nhttp://localhost:8000/docs\n```\n\n---\n\n## 🧱 Estructura del repositorio\n\n```\n/\n├── db-resync/\n│   ├── Dockerfile\n│   └── resync.py\n│\n├── db-watcher/\n│   ├── Dockerfile\n│   └── watcher.py\n│\n├── fastapi-dashboard/\n│   ├── static/\n│   │   └── dashboard.html\n│   ├── Dockerfile\n│   ├── main.py\n│   └── requirements.txt\n│\n├── DB.sql\n├── docker-compose.yml\n├── LICENSE\n├── README.md\n```\n\n\n## 📓 Notas Técnicas\n\n### 📌 Replicación MySQL\n- Replicación asíncrona.  \n- `server-id` distinto para cada nodo.  \n- Binlogs habilitados en el primary.  \n\n### 📌 Watcher (`db-watcher`)\n- Implementado en Python.  \n- Registra todos los eventos para monitoreo.  \n\n### 📌 Resync (`db-resync`)\n- Ejecuta dump + restore automático.  \n- Reconfigura la replicación.  \n- Vuelve a enganchar el nodo desactualizado.\n\n### 📌 FastAPI + Dashboard (`fastapi-dashboard`)\n#### main.py expone:\n- Estado del cluster  \n- Logs del watcher  \n- Acciones manuales (failover, resync)  \n\n#### dashboard.html muestra:\n- Estado en tiempo real  \n- Últimos eventos  \n- Indicadores visuales  \n\n\n---\n# 🎓 Conclusión\nEste proyecto implementa un sistema *totalmente funcional y automatizado* de alta disponibilidad MySQL:\n\n- Failover automático\n- Resincronización automática\n- Recuperación completa de la topología\n- Capacidad de repetir el ciclo indefinidamente\n- FastAPI para mostrar estado del cluster en el Dashboard\n- Todo con Docker + Python","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafleonardo%2Ffailover-bd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fafleonardo%2Ffailover-bd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fafleonardo%2Ffailover-bd/lists"}