Asignatura: Administración de Bases de Datos Distribuidas
Modalidad: Examen práctico individual
Duración: Según cronograma del curso
Calificación: 100 puntos (80 automático + 20 manual)
GlobalShop Inc. es una empresa de e-commerce que opera en dos regiones principales:
- Región América (Sede en Miami, USA) - Base de datos PostgreSQL
- Región Europa (Sede en Madrid, España) - Base de datos MySQL
Cada región tiene su propia base de datos que gestiona las operaciones locales, pero necesitan mantener sincronizados ciertos datos críticos del negocio en tiempo real para:
- Mantener un catálogo de productos unificado
- Sincronizar inventario entre regiones
- Compartir información de clientes globales
- Coordinar precios y promociones
El desafío: Implementar una arquitectura de replicación lógica bidireccional heterogénea (PostgreSQL ↔ MySQL) utilizando SymmetricDS en modo multi-cluster con Docker Compose.
Configurar una replicación bidireccional entre dos bases de datos heterogéneas donde:
- Los cambios en PostgreSQL (América) se repliquen automáticamente a MySQL (Europa)
- Los cambios en MySQL (Europa) se repliquen automáticamente a PostgreSQL (América)
- Se manejen correctamente las operaciones INSERT, UPDATE y DELETE
- Se eviten conflictos y loops de replicación
Se deben replicar las siguientes 4 tablas en ambas direcciones:
- product_id (PK, VARCHAR(50))
- product_name (VARCHAR(200))
- category (VARCHAR(100))
- base_price (DECIMAL(10,2))
- description (TEXT)
- is_active (BOOLEAN/TINYINT)
- created_at (TIMESTAMP)
- updated_at (TIMESTAMP)- inventory_id (PK, VARCHAR(50))
- product_id (FK, VARCHAR(50))
- region (VARCHAR(50)) -- 'AMERICA' o 'EUROPE'
- quantity (INTEGER)
- warehouse_code (VARCHAR(50))
- last_updated (TIMESTAMP)- customer_id (PK, VARCHAR(50))
- email (VARCHAR(200), UNIQUE)
- full_name (VARCHAR(200))
- country (VARCHAR(100))
- registration_date (TIMESTAMP)
- is_premium (BOOLEAN/TINYINT)
- last_purchase_date (TIMESTAMP)- promotion_id (PK, VARCHAR(50))
- promotion_name (VARCHAR(200))
- discount_percentage (DECIMAL(5,2))
- start_date (DATE)
- end_date (DATE)
- applicable_regions (VARCHAR(100)) -- 'AMERICA', 'EUROPE', 'GLOBAL'
- is_active (BOOLEAN/TINYINT)El sistema incluye scripts con datos iniciales:
- 10 productos en diferentes categorías
- 20 registros de inventario (10 por región)
- 15 clientes de diferentes países
- 8 promociones activas
┌─────────────────────────────────────────────────────────────┐
│ Docker Compose Network │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ PostgreSQL │◄────────────►│ MySQL │ │
│ │ (América) │ │ (Europa) │ │
│ │ Puerto: 5432 │ │ Puerto: 3306 │ │
│ └────────┬─────────┘ └─────────┬────────┘ │
│ │ │ │
│ │ │ │
│ ┌────────▼─────────┐ ┌─────────▼────────┐ │
│ │ SymmetricDS │◄────────────►│ SymmetricDS │ │
│ │ Node: america │ │ Node: europe │ │
│ │ Puerto: 31415 │ │ Puerto: 31416 │ │
│ └──────────────────┘ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
- ✅ Esquema de base de datos (DDL) para PostgreSQL y MySQL
- ✅ Scripts de inicialización con datos de prueba
- ✅ Plantillas de configuración (con instrucciones pero INCOMPLETAS)
- ✅ Documentación completa en
docs/ - ✅ Script de calificación automática
Este archivo NO existe, debes crearlo.
Debe incluir:
- ✅ Servicio
postgres-america(PostgreSQL 15)- Puerto: 5432
- Usuario: symmetricds
- Base de datos: globalshop
- Volumen para
init-db/postgres/
- ✅ Servicio
mysql-europe(MySQL 8.0)- Puerto: 3306
- Usuario: symmetricds
- Base de datos: globalshop
- Volumen para
init-db/mysql/
- ✅ Servicio
symmetricds-america(jumpmind/symmetricds:3.16)- Puerto: 31415
- Volúmenes para configuración
- ✅ Servicio
symmetricds-europe(jumpmind/symmetricds:3.16)- Puerto: 31416
- Volúmenes para configuración
- ✅ Red compartida entre todos los servicios
- ✅
depends_onyhealthcheckconfigurados
Ver ejemplo completo en: docs/SYMMETRICDS_GUIDE.md
Archivo 1: symmetricds/america/america.properties.main
- ⚙️
engine.name=america - ⚙️
group.id=america-store - ⚙️
external.id=001 - ⚙️ Conexión PostgreSQL completa
- ⚙️
http.port=31415 - ⚙️
sync.url=http://symmetricds-america:31415/sync/america ⚠️ NO definirregistration.url(es el nodo raíz)
Archivo 2: symmetricds/america/engines/america-setup.sql
- 📝 SQL INSERT en tablas SymmetricDS:
sym_node_group(2 grupos)sym_node_group_link(enlaces bidireccionales)sym_channel(4 canales)sym_trigger(4 triggers para products, inventory, customers, promotions)sym_router(2 routers)sym_trigger_router(vinculaciones)
Ver SQL completo en: docs/SYMMETRICDS_GUIDE.md sección "Configuración SQL"
Archivo 1: symmetricds/europe/europe.properties.main
- ⚙️
engine.name=europe - ⚙️
group.id=europe-store - ⚙️
external.id=002 - ⚙️ Conexión MySQL completa
- ⚙️
http.port=31416 - ⚙️
sync.url=http://symmetricds-europe:31416/sync/europe ⚠️ CRÍTICO:registration.url=http://symmetricds-america:31415/sync/america
Archivo 2: symmetricds/europe/engines/europe-setup.sql
- Puede estar vacío (configuración se propaga desde América)
Crea la carpeta replication-proofs/ con 4 capturas de pantalla demostrando:
Insertar un producto en PostgreSQL y mostrar que aparece en MySQL
Insertar un cliente en MySQL y mostrar que aparece en PostgreSQL
Actualizar un registro en una BD y verificar en la otra
Eliminar un registro en una BD y verificar en la otra
Ver instrucciones detalladas en la sección "Evidencias de Replicación" más abajo.
examen-abdd-2025-2/
├── README.md # 📖 Este archivo - LEER PRIMERO
├── docker-compose.yml # ⚠️ CREAR POR TI (25 pts)
│
├── init-db/ # ✅ Proporcionado (NO modificar)
│ ├── postgres/
│ │ └── 01-init.sql # DDL + datos PostgreSQL
│ └── mysql/
│ └── 01-init.sql # DDL + datos MySQL
│
├── symmetricds/ # ⚠️ COMPLETAR configuraciones
│ ├── america/
│ │ ├── america.properties.main # ⚠️ CONFIGURAR (15 pts)
│ │ └── engines/
│ │ └── america-setup.sql # ⚠️ CONFIGURAR (15 pts)
│ └── europe/
│ ├── europe.properties.main # ⚠️ CONFIGURAR (15 pts)
│ └── engines/
│ └── europe-setup.sql # ✅ Puede estar vacío (10 pts)
│
└── docs/ # ✅ Documentación de apoyo
├── SYMMETRICDS_GUIDE.md # Guía completa con ejemplos
└── TROUBLESHOOTING.md # Solución de problemas comunes
- ✅
docker-compose.yml - ✅
replication-proofs/(carpeta con evidencias)
-
Leer documentación:
# Documentación esencial (leer antes de empezar) cat docs/SYMMETRICDS_GUIDE.md # Guía completa con ejemplos
-
Clonar repositorio:
git clone https://github.com/pedrocobe/abdd-2025-2.git cd abdd-2025-2 -
Crear tu rama:
git checkout -b student/tu_nombre_apellido_cedula
-
Crear
docker-compose.ymldesde cero con los 4 servicios -
Completar configuraciones SymmetricDS:
symmetricds/america/america.properties.mainsymmetricds/america/engines/america-setup.sqlsymmetricds/europe/europe.properties.mainsymmetricds/europe/engines/europe-setup.sql
-
Levantar servicios:
docker compose up -d
-
Verificar contenedores:
docker compose ps # Debes ver 4 contenedores en estado "Up" o "healthy" -
Monitorear logs:
docker compose logs -f # Ctrl+C para salir # Esperar ~60-90 segundos hasta que SymmetricDS esté listo
-
Conectar a PostgreSQL:
docker exec -it postgres-america psql -U symmetricds -d globalshop -
Conectar a MySQL:
docker exec -it mysql-europe mysql -u symmetricds -psymmetricds globalshop -
Realizar pruebas (ver sección "Pruebas Manuales" más abajo)
-
Crear carpeta:
mkdir replication-proofs
-
Tomar 4 capturas de pantalla (ver sección "Evidencias de Replicación")
-
Crear README.md explicativo en
replication-proofs/
# Verificar cambios
git status
# Agregar archivos
git add docker-compose.yml symmetricds/ replication-proofs/
# Commit
git commit -m "Solución examen: replicación bidireccional SymmetricDS"
# Push
git push origin student/tu_nombre_apellido_cedula¡Listo! Tu examen ha sido entregado.
Calificación automática masiva:
# Desde la rama main, ejecutar:
./calificar_todos.sh
# Genera automáticamente:
# - JSON con todas las calificaciones
# - CSV para importar a Excel
# - Logs individuales por estudianteSalida: resultados_[timestamp]/
| Sección | Puntos | Qué Valida |
|---|---|---|
| 1. Docker Compose | 20 pts | • Archivo existe y sintaxis válida • 4 servicios definidos correctamente |
| 2. Contenedores | 20 pts | • Todos los contenedores en ejecución • PostgreSQL, MySQL, 2x SymmetricDS |
| 3. Bases de Datos | 15 pts | • Conexión PostgreSQL y MySQL • Tablas de negocio creadas |
| 4. SymmetricDS | 15 pts | • Tablas SymmetricDS creadas • Grupos de nodos configurados |
| 5. Replicación | 30 pts | • INSERT bidireccional • UPDATE bidireccional • DELETE bidireccional |
Genera:
- ✅ Reporte en pantalla con desglose detallado
- ✅ Archivo
calificacion_[timestamp].txt - ✅ Retroalimentación por sección
- ✅ Nota final (A, B, C, D, F)
Ejemplo de salida:
╔═════════════════════════════════════════════════╗
║ CALIFICACIÓN: EXCELENTE (A) - 95% ║
╚═════════════════════════════════════════════════╝
1. Docker Compose: 20 / 20
2. Contenedores: 20 / 20
3. Bases de Datos: 15 / 15
4. SymmetricDS: 15 / 15
5. Replicación: 25 / 30
──────────────────────────────────────────
TOTAL: 95 / 100
Este examen se divide en 2 partes:
El script calificar_todos.sh evalúa automáticamente:
| Sección | Puntos | Qué se evalúa |
|---|---|---|
| 1. Docker Compose | 25 | • Archivo existe (8 pts) • Sintaxis YAML válida (8 pts) • 4 servicios definidos (9 pts) |
| 2. Contenedores | 20 | • postgres-america corriendo (5 pts) • mysql-europe corriendo (5 pts) • symmetricds-america corriendo (5 pts) • symmetricds-europe corriendo (5 pts) |
| 3. Bases de Datos | 15 | • Conexión PostgreSQL (5 pts) • 4 tablas creadas (5 pts) • Conexión MySQL (5 pts) |
| 4. SymmetricDS | 20 | • Tablas SymmetricDS en PostgreSQL (8 pts) • Tablas SymmetricDS en MySQL (8 pts) • Grupos de nodos configurados (4 pts) |
| SUBTOTAL AUTOMÁTICO | 80 |
Debes crear una carpeta replication-proofs/ en tu rama con capturas que demuestren:
| Evidencia | Puntos | Qué Mostrar |
|---|---|---|
| 1. INSERT PG → MySQL | 5 | Insertar en PostgreSQL, mostrar en MySQL |
| 2. INSERT MySQL → PG | 5 | Insertar en MySQL, mostrar en PostgreSQL |
| 3. UPDATE bidireccional | 5 | UPDATE en una BD, verificar en la otra |
| 4. DELETE bidireccional | 5 | DELETE en una BD, verificar en la otra |
| SUBTOTAL MANUAL | 20 |
TOTAL EXAMEN: 100 puntos (80 automático + 20 manual)
IMPORTANTE: Además de la arquitectura, debes demostrar que la replicación funciona con capturas de pantalla que muestren:
📸 Capturas Requeridas:
-
INSERT: PostgreSQL → MySQL (Captura 1)
# En PostgreSQL, insertar: docker exec -it postgres-america psql -U symmetricds -d globalshop INSERT INTO products VALUES ('DEMO-001', 'Producto Demo', 'Demo', 99.99, 'Demo', true, NOW(), NOW()); SELECT * FROM products WHERE product_id = 'DEMO-001';
# En MySQL, verificar que aparece: docker exec -it mysql-europe mysql -u symmetricds -psymmetricds globalshop SELECT * FROM products WHERE product_id = 'DEMO-001';
Captura: Debes mostrar AMBAS consultas (PostgreSQL con INSERT y MySQL con SELECT mostrando el dato replicado)
-
INSERT: MySQL → PostgreSQL (Captura 2)
# En MySQL, insertar: INSERT INTO customers VALUES ('DEMO-CUST', 'demo@test.com', 'Cliente Demo', 'Spain', NOW(), 1, NOW()); SELECT * FROM customers WHERE customer_id = 'DEMO-CUST';
# En PostgreSQL, verificar: SELECT * FROM customers WHERE customer_id = 'DEMO-CUST';
Captura: Ambas consultas mostrando la replicación inversa
-
UPDATE Bidireccional (Captura 3)
# Actualizar en PostgreSQL: UPDATE products SET base_price = 149.99 WHERE product_id = 'DEMO-001';
# Verificar en MySQL que el precio cambió: SELECT product_id, base_price FROM products WHERE product_id = 'DEMO-001';
Captura: Mostrar el UPDATE y la verificación
-
DELETE Bidireccional (Captura 4)
# Eliminar en MySQL: DELETE FROM customers WHERE customer_id = 'DEMO-CUST';
# Verificar en PostgreSQL que se eliminó: SELECT COUNT(*) FROM customers WHERE customer_id = 'DEMO-CUST'; -- Debe retornar 0
Captura: Mostrar el DELETE y la verificación
Formato de las capturas:
- Deben ser legibles (texto visible)
- Incluir timestamp o comando completo
- Mostrar AMBAS bases de datos en cada operación
- Guardar en:
replication-proofs/01_insert_pg_mysql.png,02_insert_mysql_pg.png, etc.
Puntuación:
- Cada captura vale 5 puntos
- Total: 20 puntos (calificación manual del profesor)
Calificación Final = Arquitectura + Evidencias
- 90-100: Excelente (A)
- 80-89: Bueno (B)
- 70-79: Aceptable (C)
- 60-69: Suficiente (D)
- <60: Insuficiente (F)
Si no presentas las capturas de replicación, tu calificación máxima será la de arquitectura únicamente.
git clone https://github.com/pedrocobe/abdd-2025-2.git
cd abdd-2025-2IMPORTANTE: Nombra tu rama exactamente con este formato:
git checkout -b student/nombre_apellido_cedulaEjemplo:
git checkout -b student/juan_perez_1234567890Completa las siguientes tareas en tu rama:
- Crear
docker-compose.ymlcon los 4 servicios - Completar configuraciones en
symmetricds/ - Probar la replicación con las pruebas manuales
- Crear carpeta
replication-proofs/con evidencias
# Ver cambios
git status
# Agregar archivos
git add docker-compose.yml symmetricds/ replication-proofs/
# Commit
git commit -m "Solución examen: replicación bidireccional SymmetricDS"
# Subir tu rama
git push origin student/nombre_apellido_cedulaConfirma que tu rama esté en GitHub:
git branch -r | grep student/tu_nombrestudent/tu_nombre_apellido_cedula/
├── docker-compose.yml ✅ Tu solución (OBLIGATORIO)
├── symmetricds/ ✅ Configuraciones completadas
│ ├── america/
│ │ ├── america.properties.main ✅ Configuración nodo América
│ │ └── engines/
│ │ └── america-setup.sql ✅ Setup SQL América
│ └── europe/
│ ├── europe.properties.main ✅ Configuración nodo Europa
│ └── engines/
│ └── europe-setup.sql ✅ Setup SQL Europa
└── replication-proofs/ ✅ Evidencias (20 pts)
├── 01_insert_pg_to_mysql.png
├── 02_insert_mysql_to_pg.png
├── 03_update_bidireccional.png
├── 04_delete_bidireccional.png
└── README.md ✅ Explicación de capturas
docs/SYMMETRICDS_GUIDE.md- Guía completa de configuración de SymmetricDSdocs/TROUBLESHOOTING.md- Solución de problemas comunes
- Identificadores Únicos: Usar UUID o códigos que garanticen unicidad entre regiones
- Timestamps: Incluir
updated_aten todas las tablas para control de cambios - Resolución de Conflictos: SymmetricDS usa "last write wins" por defecto
- Triggers: SymmetricDS crea triggers automáticamente - no los modifiquen
- Logs: Revisar logs de SymmetricDS para debugging
Si deseas probar manualmente antes de ejecutar el script de validación:
# Conectar a PostgreSQL
docker exec -it postgres-america psql -U symmetricds -d globalshop
# Conectar a MySQL
docker exec -it mysql-europe mysql -u symmetricds -psymmetricds globalshop
# Ejemplo: Insertar un producto en PostgreSQL
INSERT INTO products VALUES
('PROD-TEST-001', 'Test Product', 'Electronics', 99.99, 'Test', true, NOW(), NOW());
# Verificar en MySQL (esperar unos segundos)
SELECT * FROM products WHERE product_id = 'PROD-TEST-001';Archivos a entregar:
docker-compose.ymlsymmetricds/america/symmetric.propertiessymmetricds/america/engines/america.propertiessymmetricds/europe/symmetric.propertiessymmetricds/europe/engines/europe.properties- Captura de pantalla del output de
validate.shexitoso
Formato de entrega: ZIP con el nombre apellido_nombre_examen_abdd.zip
Además de la arquitectura, debes demostrar que la replicación bidireccional funciona correctamente mediante capturas de pantalla.
mkdir evidencias
cd evidenciasdocker compose psCaptura: Debe mostrar los 4 contenedores en estado "Up"
# Terminal 1: Conectar a PostgreSQL
docker exec -it postgres-america psql -U symmetricds -d globalshop
# Insertar un producto
INSERT INTO products VALUES ('EVIDENCIA-01', 'Producto de Evidencia', 'Demo', 199.99, 'Test replicacion', true, NOW(), NOW());
# Verificar inserción
SELECT product_id, product_name, base_price FROM products WHERE product_id = 'EVIDENCIA-01';# Terminal 2: Conectar a MySQL y verificar (esperar 10 segundos)
docker exec -it mysql-europe mysql -u symmetricds -psymmetricds globalshop
# Verificar que se replicó
SELECT product_id, product_name, base_price FROM products WHERE product_id = 'EVIDENCIA-01';Captura: Mostrar AMBAS terminales mostrando que el dato insertado en PostgreSQL aparece en MySQL
# Terminal 1: Conectar a MySQL
docker exec -it mysql-europe mysql -u symmetricds -psymmetricds globalshop
# Insertar un cliente
INSERT INTO customers VALUES ('EVIDENCIA-02', 'test@evidencia.com', 'Cliente Evidencia', 'Ecuador', NOW(), 1, NOW());
# Verificar
SELECT customer_id, email, full_name FROM customers WHERE customer_id = 'EVIDENCIA-02';# Terminal 2: Conectar a PostgreSQL y verificar (esperar 10 segundos)
docker exec -it postgres-america psql -U symmetricds -d globalshop
# Verificar que se replicó
SELECT customer_id, email, full_name FROM customers WHERE customer_id = 'EVIDENCIA-02';Captura: Ambas terminales mostrando la replicación de MySQL a PostgreSQL
# En PostgreSQL
UPDATE products SET base_price = 299.99 WHERE product_id = 'EVIDENCIA-01';
SELECT product_id, base_price FROM products WHERE product_id = 'EVIDENCIA-01';# En MySQL (esperar 10 segundos)
SELECT product_id, base_price FROM products WHERE product_id = 'EVIDENCIA-01';
-- Debe mostrar 299.99Captura: Mostrar el UPDATE y la verificación en la otra BD
# En MySQL
DELETE FROM customers WHERE customer_id = 'EVIDENCIA-02';
SELECT COUNT(*) FROM customers WHERE customer_id = 'EVIDENCIA-02';
-- Debe retornar 0# En PostgreSQL (esperar 10 segundos)
SELECT COUNT(*) FROM customers WHERE customer_id = 'EVIDENCIA-02';
-- Debe retornar 0Captura: Mostrar el DELETE y la verificación
Crear evidencias/README.md:
# Evidencias de Replicación Bidireccional
## Estudiante
- **Nombre:** [Tu nombre]
- **Cédula:** [Tu cédula]
- **Fecha:** [Fecha de pruebas]
## Descripción de Capturas
### 01_arquitectura.png
Muestra los 4 contenedores corriendo correctamente.
### 02_insert_pg_mysql.png
Inserción en PostgreSQL replicada a MySQL.
- Producto ID: EVIDENCIA-01
- Tiempo de replicación: ~10 segundos
### 03_insert_mysql_pg.png
Inserción en MySQL replicada a PostgreSQL.
- Cliente ID: EVIDENCIA-02
- Tiempo de replicación: ~10 segundos
### 04_update.png
Actualización bidireccional funcionando.
### 05_delete.png
Eliminación bidireccional funcionando.
## Conclusión
La replicación bidireccional está funcionando correctamente en ambas direcciones.git add replication-proofs/
git commit -m "Add: Evidencias de replicación bidireccional"
git push origin student/nombre_apellido_cedulastudent/tu_nombre_apellido_cedula/
├── docker-compose.yml ← Tu solución
├── symmetricds/ ← Configuraciones completadas
│ ├── america/...
│ └── europe/...
└── replication-proofs/ ← Tus evidencias (20pts)
├── 01_insert_pg_to_mysql.png
├── 02_insert_mysql_to_pg.png
├── 03_update_bidireccional.png
├── 04_delete_bidireccional.png
└── README.md
- Consultar documentación oficial de Docker, PostgreSQL, MySQL y SymmetricDS
- Usar los archivos en
docs/como referencia - Revisar logs de Docker para debugging
- Realizar pruebas locales ilimitadas
- Copiar soluciones de otros estudiantes
- Compartir tu solución con compañeros
- Usar soluciones completas de internet sin entender
- Modificar archivos base en
init-db/
Si tienes preguntas sobre qué se pide (NO sobre cómo resolverlo):
- Contacta al profesor por el canal oficial del curso
- Horario de consultas según cronograma
- 📖
docs/SYMMETRICDS_GUIDE.md- Conceptos y configuración - 🔧
docs/TROUBLESHOOTING.md- Problemas comunes - 🐳
docker compose logs- Ver logs de contenedores - 📚 Documentación oficial SymmetricDS
- ✅ Crear
docker-compose.ymlcon 4 servicios - ✅ Configurar SymmetricDS en ambos nodos
- ✅ Probar replicación bidireccional (INSERT/UPDATE/DELETE)
- ✅ Capturar pantallas en
replication-proofs/ - ✅ Hacer commit y push a tu rama
student/nombre_apellido_cedula
- ✅ DDL de bases de datos (
init-db/) - ✅ Datos iniciales de prueba
- ✅ Estructura de carpetas
- ✅ Documentación de apoyo
- 80 pts (automático): Arquitectura Docker + Configuración SymmetricDS
- 20 pts (manual): Evidencias de replicación en capturas
Este material es propiedad académica y su uso está restringido al contexto educativo del curso.
Este examen evalúa tu capacidad para:
- Diseñar arquitecturas distribuidas con Docker
- Configurar replicación de datos entre sistemas heterogéneos
- Resolver problemas de sincronización en sistemas distribuidos
- Trabajar con herramientas empresariales de replicación
Tiempo estimado: 2-3 horas
Versión: 1.0
Fecha: Enero 2026
Materia: Administración de Bases de Datos