Este artículo es la base de una pequeña serie dedicada a HADR. HADR es una tecnología simple de alta disponibilidad que apareció por primera vez en Db2 8.2 y que originalmente se basó en Informix HDR. El objetivo aquí no es cubrir todos los detalles que explorarán artículos posteriores, sino construir una configuración HADR que haga visible el modelo básico de funcionamiento:
- Una base de datos primary
- Una base de datos standby
- Propagación de cambios desde la primary hacia la standby
- Validación básica de que el replay está ocurriendo en la secundaria
El laboratorio usa una infraestructura simple compuesta por dos contenedores Docker con Db2 Community Edition 12.1.4 en el mismo host.
1. Objetivos del laboratorio
Al final de este laboratorio deberías poder:
- Explicar los papeles de las bases de datos HADR primary y standby
- Construir un laboratorio HADR mínimo de dos nodos en Docker
- Configurar los parámetros HADR en ambas bases de datos
- Restaurar correctamente el backup de la primary sobre la standby
- Iniciar HADR y confirmar que el par alcanza
PEER - Validar que los cambios confirmados en la base de datos primary aparecen en la standby
2. Qué cubre este artículo y qué no cubre
Este artículo cubre:
- La arquitectura básica de HADR
- Una configuración simple con solo una base de datos standby y sin gestor de clúster para automatización
Este artículo no cubre:
- Gestión de clúster con Pacemaker
- Failover automático
- Múltiples bases de datos standby
- Ajuste de configuración, como peer window o delayed replay
3. Entorno necesario
Para este laboratorio necesitas:
- Docker y Docker Compose
- 8 GB de RAM suelen ser suficientes para un laboratorio pequeño en una máquina con poca carga
Db2 LUW 12.1.4 Community Edition se descarga desde icr.io.
Suposiciones importantes:
- El laboratorio ejecuta ambos contenedores en el mismo host
- La etiqueta de la imagen está fijada en
12.1.4.0para mantener el laboratorio reproducible
4. HADR en un minuto
En el nivel más básico, HADR funciona mediante estos eventos:
1. La base de datos primary recibe cambios de datos 2. Db2 envía registros de log a la base de datos standby 3. La base de datos standby hace replay de esos registros de log 4. La base de datos standby queda lista para takeover si la primary falla
Los estados HADR más importantes que verás son:
| Estado | Significado |
|---|---|
REMOTE_CATCHUP | La base de datos standby está recibiendo cambios y haciendo replay de logs, pero todavía no está totalmente sincronizada con la primary |
PEER | Las bases de datos primary y standby están sincronizadas en el nivel operacional normal para el modo de sincronización seleccionado |
DISCONNECTED | La comunicación HADR está interrumpida |
Para este artículo, la condición de éxito es simple:
- El par HADR alcanza
PEER - Un cambio confirmado en la base de datos primary se vuelve visible en la base de datos standby
- Conseguimos realizar el takeover manual con éxito
4.1 Por qué HADR empieza con backup y restore
HADR no construye la base de datos standby copiando tablas individualmente ni reproduciendo todo lo que ocurrió en la base de datos primary desde el principio. La standby primero debe arrancar a partir de una imagen consistente de la base de datos primary, y por eso la configuración empieza con:
1. Creación de un backup de la base de datos primary 2. Creación de la base de datos standby mediante restore de ese backup
Esa secuencia es importante desde el punto de vista conceptual:
- El backup da a la base de datos standby un punto de arranque conocido y consistente
- El restore vuelve a la base de datos standby estructuralmente idéntica a la primary en ese momento
- HADR mantiene luego la standby actualizada mediante el envío y el replay de los registros de log generados después del backup
4.2 Qué hacen la primary y la standby
Los dos papeles no son simétricos.
| Papel | Responsabilidad |
|---|---|
| Primary | Acepta escrituras de las aplicaciones, genera registros de log y los envía |
| Standby | Recibe los registros de log enviados, hace replay de esos registros y permanece lista para takeover |
En la configuración básica usada aquí:
- Todas las actualizaciones ocurren en la base de datos primary
- La standby no sirve carga aplicacional normal
- La standby todavía puede usarse para verificaciones administrativas y consultas puntuales de validación en el laboratorio
4.3 Qué sincroniza HADR
HADR no sincroniza “filas” directamente. Sincroniza la base de datos primary y la standby mediante el flujo de registros de log de la base de datos:
- Una aplicación hace commit en la base de datos primary
- Db2 escribe los registros de log correspondientes
- Esos registros de log son enviados a la base de datos standby
- La base de datos standby hace replay de esos registros, actualizando su copia de la base de datos
Por eso archive logging y roll-forward recovery son tan importantes en la configuración de HADR. Sin la configuración correcta de logging, la base de datos standby no puede mantenerse mediante el replay del flujo de log procedente de la base de datos primary.
4.4 Qué cambia realmente el modo de sincronización
Uno de los primeros parámetros HADR que la gente considera es HADR_SYNCMODE. Define un trade-off importante entre latencia y protección de datos.
En términos simples:
| Modo de sincronización | Qué significa operacionalmente |
|---|---|
SYNC | El commit en la primary solo termina después de que la standby confirme que los registros de log ya fueron escritos en sus propios archivos de log. |
NEARSYNC | El commit en la base de datos primary sigue dependiendo de confirmación de la standby, pero aquí la standby puede confirmar antes: basta con que los registros de log hayan sido recibidos y colocados en memoria. La confirmación ya no espera a la escritura de los logs en disco. |
ASYNC | El commit en la base de datos primary termina después de que los registros de log de la transacción se escriban en disco y se entreguen a la pila TCP para seguir hacia la standby. |
SUPERASYNC | El commit termina inmediatamente después de escribir los registros de log de la transacción en disco. |
Esto explica por qué:
SYNCofrece la protección más fuerte porque, en el momento del commit, el log ya está persistido en ambas bases de datosNEARSYNCtiene menor latencia porque la base de datos standby no necesita esperar a la escritura en disco antes de confirmar; sigue siendo un modo fuerte de protección, pero acepta un riesgo ligeramente mayor
Otra forma de pensar en los cuatro modos de sincronización es:
| Prioridad | Modos más adecuados |
|---|---|
| Minimizar posible pérdida de transacciones | SYNC, luego NEARSYNC |
| Reducir el impacto en la latencia de commit de la base de datos primary | ASYNC, luego SUPERASYNC |
| Mantener un equilibrio práctico en muchos escenarios estándar de HA | NEARSYNC |
Las preguntas útiles son:
- ¿Cuánta latencia adicional en el commit de la base de datos primary podemos tolerar?
- ¿Qué desfase puede tolerar la standby?
- ¿Qué exposición a pérdida de datos es aceptable si la primary falla?
4.5 Qué significa realmente PEER
Cuando el par HADR alcanza PEER, Db2 te está diciendo que la relación HADR quedó totalmente establecida para el modo de sincronización seleccionado.
Operacionalmente, eso significa:
- La comunicación entre las bases de datos está funcionando
- La standby está actualizada al nivel esperado para el modo de sincronización configurado
- El par HADR está en su estado operacional estable normal
Eso no significa que el entorno sea automáticamente altamente disponible en el sentido amplio de clúster. En este artículo no existe gestor de clúster, ni relocalización de servicio, ni orquestación automática. PEER solo significa que el par de bases de datos está sano como relación HADR.
4.6 Dónde entra Pacemaker más adelante
Este artículo ignora deliberadamente el uso de Pacemaker.
¿Por qué?
Porque Pacemaker resuelve un problema diferente:
- HADR mantiene sincronizadas las copias de la base de datos
- Pacemaker automatiza el control de recursos y las decisiones de failover alrededor de esas copias
5. Crear el directorio de trabajo
Ejecuta esto para crear y entrar en el directorio de trabajo:
mkdir db2-hadr-foundation-lab
cd db2-hadr-foundation-lab6. Crear docker-compose.yml
Abre una sesión de edición para crear el archivo:
vi docker-compose.ymlPega el siguiente contenido:
services:
db2pri:
image: icr.io/db2_community/db2:12.1.4.0
container_name: db2pri
privileged: true
hostname: db2pri
environment:
LICENSE: accept
DB2INST1_PASSWORD: passw0rd
ports:
- "50000:50000"
volumes:
- db2pri_data:/database
healthcheck:
test: ["CMD", "su", "-", "db2inst1", "-c", "db2 list db directory"]
interval: 30s
timeout: 10s
retries: 15
start_period: 600s
db2std:
image: icr.io/db2_community/db2:12.1.4.0
container_name: db2std
privileged: true
hostname: db2std
environment:
LICENSE: accept
DB2INST1_PASSWORD: passw0rd
ports:
- "50001:50000"
volumes:
- db2std_data:/database
healthcheck:
test: ["CMD", "su", "-", "db2inst1", "-c", "db2 list db directory"]
interval: 30s
timeout: 10s
retries: 15
start_period: 600s
volumes:
db2pri_data:
name: db2pri_data
db2std_data:
name: db2std_data7. Arrancar los contenedores
Establece la configuración definida en docker-compose.yml:
docker compose up -dEspera un poco y comprueba el estado de los contenedores:
docker psSi alguno de los contenedores sigue arrancando, espera y vuelve a comprobar:
sleep 30
docker psNo continúes hasta que ambos contenedores estén healthy. En esta configuración he establecido un timeout de 600 segundos. Si no es suficiente, ajusta docker-compose.yml y repite los pasos anteriores.
Verifica el nivel de código de Db2:
docker compose exec db2pri su - db2inst1 -c "db2level"
docker compose exec db2std su - db2inst1 -c "db2level"Ambos contenedores deben indicar 12.1.4.0.
8. Crear la base de datos primary
Crea la base de datos primary en el contenedor db2pri:
docker compose exec db2pri su - db2inst1 -c "db2 create db HADRDB"Crea una pequeña tabla e inserta algunos datos de ejemplo:
docker compose exec db2pri su - db2inst1 -c \
"db2 connect to HADRDB && \
db2 create schema app && \
db2 \"create table app.orders (id int not null, amount decimal(10,2), primary key(id))\" && \
db2 \"insert into app.orders values (1,100.00),(2,250.00),(3,400.00)\" && \
db2 commit && \
db2 connect reset"9. Activar archive logging en la primary
HADR exige roll-forward recovery, por lo que la base de datos primary debe cambiarse en consecuencia.
Configura archive logging:
docker compose exec db2pri su - db2inst1 -c \
"mkdir -p /database/config/db2inst1/archive/HADRDB && \
db2 update db cfg for HADRDB using LOGARCHMETH1 DISK:/database/config/db2inst1/archive/HADRDB"Reinicia la instancia:
docker compose exec db2pri su - db2inst1 -c \
"db2stop force && db2start"Verifica:
docker compose exec db2pri su - db2inst1 -c \
"db2 get db cfg for HADRDB | grep -i logarchmeth1"10. Configurar HADR en la base de datos primary
Ajusta la configuración de la base de datos para soportar HADR.
docker compose exec db2pri su - db2inst1 -c \
"db2 update db cfg for HADRDB using \
HADR_LOCAL_HOST db2pri \
HADR_LOCAL_SVC 60000 \
HADR_REMOTE_HOST db2std \
HADR_REMOTE_SVC 60000 \
HADR_REMOTE_INST db2inst1 \
HADR_SYNCMODE NEARSYNC \
HADR_TIMEOUT 120 \
LOGINDEXBUILD ON"Para este artículo:
| Parámetro | Valor | Motivo |
|---|---|---|
HADR_LOCAL_HOST | db2pri | Hostname de la primary |
HADR_REMOTE_HOST | db2std | Hostname de la standby |
HADR_LOCAL_SVC / HADR_REMOTE_SVC | 60000 | Puerto de comunicación usado por HADR |
HADR_SYNCMODE | NEARSYNC | Modo de sincronización elegido para este laboratorio |
11. Producir un backup offline de la base de datos primary
Desactiva la base de datos y realiza el backup:
docker compose exec db2pri su - db2inst1 -c \
"rm -rf /database/config/db2inst1/backups/hadrdb && \
mkdir -p /database/config/db2inst1/backups/hadrdb && \
db2 deactivate db HADRDB && \
db2 backup db HADRDB to /database/config/db2inst1/backups/hadrdb"12. Copiar la imagen de backup a la standby
Copia el backup para que esté disponible dentro del contenedor db2std.
rm -rf /tmp/hadrdb-backup
mkdir -p /tmp/hadrdb-backup
docker cp db2pri:/database/config/db2inst1/backups/hadrdb/. /tmp/hadrdb-backup/
docker compose exec db2std su - db2inst1 -c "rm -rf /database/config/db2inst1/backups/hadrdb && mkdir -p /database/config/db2inst1/backups/hadrdb"
docker cp /tmp/hadrdb-backup/. db2std:/database/config/db2inst1/backups/hadrdb/13. Restaurar la base de datos en la standby
Crea la base de datos standby restaurando el backup dentro de db2std.
docker compose exec db2std su - db2inst1 -c \
"db2 restore db HADRDB from /database/config/db2inst1/backups/hadrdb into HADRDB replace existing without prompting"SQL2540W con warning 2539 es aceptable aquí. Ocurre porque el restore se completó, pero la base de datos standby todavía no está lista para uso normal: aún necesita recuperación adicional a partir de logs. Ese es exactamente el estado esperado para poder iniciarla como standby mediante START HADR AS STANDBY.
14. Configurar HADR en la standby
Ajusta la configuración HADR en la base de datos standby.
docker compose exec db2std su - db2inst1 -c \
"db2 update db cfg for HADRDB using \
HADR_LOCAL_HOST db2std \
HADR_LOCAL_SVC 60000 \
HADR_REMOTE_HOST db2pri \
HADR_REMOTE_SVC 60000 \
HADR_REMOTE_INST db2inst1 \
HADR_SYNCMODE NEARSYNC \
HADR_TIMEOUT 120 \
LOGINDEXBUILD ON"En este punto:
- El backup ya fue restaurado en la standby
- Los parámetros HADR del lado de la standby ya están configurados
- La base de datos está lista para
START HADR AS STANDBY
15. Iniciar HADR
Inicia primero la base de datos standby:
docker compose exec db2std su - db2inst1 -c \
"db2 start hadr on db HADRDB as standby"Después inicia la base de datos primary:
docker compose exec db2pri su - db2inst1 -c \
"db2 start hadr on db HADRDB as primary"16. Confirmar el estado HADR
Comprueba el estado HADR en ambos lados:
docker compose exec db2pri su - db2inst1 -c "db2pd -db HADRDB -hadr"
docker compose exec db2std su - db2inst1 -c "db2pd -db HADRDB -hadr"El par HADR debe pasar a PEER.
También puedes usar la función de tabla mon_get_hadr():
docker compose exec db2pri su - db2inst1 -c \
"db2 connect to HADRDB && db2 \"select hadr_role, hadr_state from table(mon_get_hadr(-2)) as t\" && db2 connect reset"17. Validaciones básicas
Ahora realiza y confirma un cambio en la base de datos primary:
docker compose exec db2pri su - db2inst1 -c \
"db2 connect to HADRDB && db2 \"insert into app.orders values (4,500.00)\" && db2 commit && db2 connect reset"Valida que los datos también estén visibles en la base de datos standby:
docker compose exec db2std su - db2inst1 -c \
"db2 connect to HADRDB && db2 \"select * from app.orders with ur\" && db2 connect reset"En este punto:
- La base de datos primary y la standby están configuradas correctamente
- Archive logging está activo
- HADR se ha iniciado en ambos lados y el par HADR está en el estado operacional correcto (
PEER) - Los cambios realizados en la base de datos primary se aplican en la standby
No hemos demostrado:
- Takeover manual
- Failover automatizado
- Comportamiento de client reroute
- Comportamiento de replay-only window
Todavía vamos a demostrar el takeover manual.
19. Fundamentos del takeover manual
En Db2 HADR, un takeover cambia los roles de las bases de datos:
- La standby se convierte en la nueva primary
- La antigua primary se convertirá en standby si consigue reconectarse y asumir ese papel
Este es el mecanismo de failover más simple de comprender porque lo inicia explícitamente un operador o administrador.
El comando básico se emite en la standby:
db2 takeover hadr on db HADRDBTambién existe una variante con la opción by force:
db2 takeover hadr on db HADRDB by forceLa diferencia es importante:
| Comando | Uso típico |
|---|---|
TAKEOVER HADR | Cambio de rol controlado cuando ambos lados están suficientemente sanos para una transición coordinada |
TAKEOVER HADR BY FORCE | Promoción de emergencia cuando la antigua primary no está disponible o el enlace se ha interrumpido |
Siempre debes intentar primero un takeover normal y reservar BY FORCE solo para escenarios en los que la antigua primary ya no pueda participar en HADR.
20. Consideraciones operativas antes del takeover
Antes de realizar un takeover manual, comprueba estos puntos:
| Aspecto | Por qué importa |
|---|---|
| Estado HADR | Un takeover limpio funciona mejor cuando el par está en PEER |
| Actividad de escritura de las aplicaciones | El trabajo en curso en la antigua primary puede interrumpirse por el cambio de rol |
| Conexiones de clientes | Los clientes deben reconectarse a la nueva primary a menos que exista una solución de redirección |
| Modo de sincronización | En modos menos exigentes, la standby puede ir retrasada respecto de la primary en el momento de la falla |
| Riesgo de takeover forzado | BY FORCE puede aumentar la exposición a pérdida de datos si la antigua primary tiene registros de log committed que todavía no se han enviado |
21. Validar un takeover manual limpio
Primero confirma los roles actuales de ambas bases de datos:
docker compose exec db2pri su - db2inst1 -c "db2pd -db HADRDB -hadr"
docker compose exec db2std su - db2inst1 -c "db2pd -db HADRDB -hadr"En esta fase deberías ver:
db2pricomo primarydb2stdcomo standby
Ahora realiza el takeover desde la standby:
docker compose exec db2std su - db2inst1 -c \
"db2 takeover hadr on db HADRDB"22. Confirmar la inversión de roles
Comprueba ambos lados de nuevo:
docker compose exec db2pri su - db2inst1 -c "db2pd -db HADRDB -hadr"
docker compose exec db2std su - db2inst1 -c "db2pd -db HADRDB -hadr"Ahora el resultado esperado es:
db2stdes primarydb2pries standby
Si eso ocurre, el takeover manual funcionó.
23. Validar escrituras en la nueva base de datos primary
Inserta una nueva fila en la nueva base de datos primary, que ahora es db2std:
docker compose exec db2std su - db2inst1 -c \
"db2 connect to HADRDB && db2 \"insert into app.orders values (5,650.00)\" && db2 commit && db2 connect reset"Después valida desde la nueva standby, que ahora es db2pri:
docker compose exec db2pri su - db2inst1 -c \
"db2 connect to HADRDB && db2 \"select * from app.orders with ur\" && db2 connect reset"Si la fila es visible:
- Los roles cambiaron correctamente
- El envío de log siguió funcionando correctamente después del takeover
24. Qué no resuelve este takeover manual
El takeover manual es importante, pero sigue siendo una operación manual.
Por sí solo no proporciona:
- Detección automática de fallo de la primary
- Decisión automática de promoción de la base de datos standby
- Movimiento de dirección IP virtual
- Reconexión automática de aplicaciones
Aquí es donde entra software de gestión de clúster como Pacemaker o TSAMP.
26. Cleanup
Para eliminar completamente el laboratorio, destruye los contenedores y los volúmenes Docker:
docker compose down -v27. Resumen
Este es un laboratorio HADR muy simple:
- Una base de datos primary
- Una base de datos standby
- Sin Pacemaker
- Takeover manual
Aunque es simple, resulta útil para entender la mecánica central de la solución antes de añadir temas más avanzados como peer window, delayed replay o failover gestionado por clúster.
Referencias
- IBM Docs: High availability disaster recovery (HADR)
- IBM Docs: HADR configuration parameters
- IBM Docs: db2pd command