OracleData GuardAlta Disponibilidad
Juan Maldonado30 de abril de 20195 min lectura

Implementación Data Guard Físico usando Oracle Database 12c

Implementación Data Guard Físico usando Oracle Database 12c

Oracle Data Guard es un producto que nos asegura la alta disponibilidad, protección de datos, y un sitio alterno o disaster recovery (Standby Database) en caso de algún fallo  de carácter físico o lógico de nuestra base de datos principal. Oracle Data Guard nos ayuda a mantener estas bases de datos standby como copias de nuestra base de datos de producción, lo cual nos permite que durante mantenimientos que tienen un tiempo muy prolongado disponibilizar el servicio de nuestra base de datos, minimizando el tiempo de pérdida del servicio de nuestra base de datos comparado con el tiempo del mantenimiento programado.

image

La implementación del sitio de contingencia fue desarrollado en un ambiente que cuenta con las siguientes características:

SITIO PRIMARIO

  • Sistema Operativo CentOS 7.5 64 bits
  • Base de Datos Oracle 12c Release 2 configurada en Stand Alone
  • Modo Archive activo (es necesario y obligatorio para la implementación del sitio alterno o standby)
  • Conexión entre servidores sin restricciones, no hay firewall en medio de ambos.
  • Almacenamiento en filesystem
  • Listener configurado por defecto (puerto 1521)

SITIO STANDBY

  • Sistema Operativo CentOS 7.5 64 bits
  • Software Base de Datos Oracle 12c Release 2
  • Almacenamiento en filesystem
  • Listener configurado por defecto (puerto 1521)

Nota: En los comandos siguientes se utilizan los nombres primario y standby como DB_UNIQUE_NAME / ORACLE_SID, y las rutas /u01/app/oracle/oradata/primario/ y /u01/app/oracle/oradata/standby/. Ajusta estos valores a los de tu entorno.

Antes de iniciar con la implementación de nuestro Dataguard Físico debemos asegurarnos que existe conectividad y resolución de hostname por medio de ssh entre los servidores que intervendrán en esta configuración:

a) Edición de archivo /etc/hosts

Es muy importante que la resolución de los hostnames de los servidores que intervendrán en esta configuración se lo realice localmente por medio del archivo /etc/hosts o  por medio de un DNS.

Archivo /etc/hosts en servidor PRIMARIO y STANDBY

# /etc/hosts  (contenido idéntico en ambos servidores)
192.168.1.10  primary.polluxdata.com  primary
192.168.1.11  standby.polluxdata.com  standby

b) Ping entre servidores 

PING ENTRE SERVIDOR PRIMARIO Y STANDBY

# Desde el primario
ping -c 4 standby

# Desde el standby
ping -c 4 primary

c) Conectividad SSH

CONECTIVIDAD SSH ENTRE PRIMARIO Y STANDBY

# Configurar equivalencia de llaves (ssh sin password) en el usuario oracle
# En el PRIMARIO
ssh-keygen -t rsa -b 2048
ssh-copy-id oracle@standby

# En el STANDBY
ssh-keygen -t rsa -b 2048
ssh-copy-id oracle@primary

# Verificar (no debe pedir password)
ssh oracle@standby 'hostname; id'
ssh oracle@primary 'hostname; id'

Luego de haber comprobado que la resolución de hostnames en los servidores primario y standby son correctos y que la conectividad ssh se realiza correctamente, podemos continuar con las configuraciones necesarias para crear nuestro STANDBY FISICO

1)  Base de Datos en Modo Archive

Es indispensable que nuestro sitio PRIMARIO tenga  habilitado el ** MODO ARCHIVE ** para que la implementación de nuestro sitio alterno o standby sea correcto debido a que Oracle Data Guard utilizará los archivelogs para aplicarlos en nuestro STANDBY, y de esta manera tener una copia exacta de nuestra base de datos PRIMARIA

VALIDACIÓN MODO ARCHIVE

-- Conectarse a la base de datos PRIMARIA como sysdba
sqlplus / as sysdba

-- Validar el modo archive
ARCHIVE LOG LIST;

-- Alternativa con query
SELECT log_mode FROM v$database;

-- Si NO está en modo ARCHIVELOG, habilitarlo:
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE OPEN;

2) Habilitamos FORCE LOGGING

Para garantizar la consitencia de la base de datos STANDBY debemos habilitar FORCE LOGGING a nivel de la base de datos PRIMARIA. Este característica, que viene deshabilitada por defecto, nos ayuda a que todos los cambios que se realizan dentro de la base de datos PRIMARIA sean registrado dentro de los** REDO LOGS, **incluso se registrará las transacciones u operaciones que tienen NOLOGGING.

-- Habilitar FORCE LOGGING en la base de datos PRIMARIA
ALTER DATABASE FORCE LOGGING;

-- Verificar
SELECT force_logging FROM v$database;

3) Agregamos Standby Redo Logs en base de datos PRIMARIA

A pesar que los Standby Redo logs son exclusivos para los sitios alternos o standby, en caso de realizar un cambio de roles entre la base de datos Standby y Primaria, se los va a tener que crear almomento de realizar esta transición de roles.

-- Consultar el tamaño de los online redo logs para crear los SRL del mismo tamaño
SELECT group#, bytes/1024/1024 AS size_mb, status
FROM v$log;

-- Crear Standby Redo Logs (un grupo más que los online redo logs)
-- En este ejemplo: 3 grupos de online redo logs -> 4 grupos de standby redo logs
ALTER DATABASE ADD STANDBY LOGFILE ('/u01/app/oracle/oradata/primario/srl01.log') SIZE 50M;
ALTER DATABASE ADD STANDBY LOGFILE ('/u01/app/oracle/oradata/primario/srl02.log') SIZE 50M;
ALTER DATABASE ADD STANDBY LOGFILE ('/u01/app/oracle/oradata/primario/srl03.log') SIZE 50M;
ALTER DATABASE ADD STANDBY LOGFILE ('/u01/app/oracle/oradata/primario/srl04.log') SIZE 50M;

-- Verificar
SELECT group#, bytes/1024/1024 AS size_mb, status FROM v$standby_log;

4) Mapeo en tnsnames.ora

tnsnames.ora EN PRIMARIA y STANDBY

# $ORACLE_HOME/network/admin/tnsnames.ora  (idéntico en ambos servidores)
PRIMARIO =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = primary)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = primario)
    )
  )

STANDBY =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = standby)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = standby)
    )
  )
# Verificar conectividad SQL*Net desde ambos servidores
tnsping primario
tnsping standby

5) Cambio de parámetros inicialización en base de datos PRIMARIA

Para el correcto funcionamiento de Oracle Dataguard es necesario modifcar los siguientes parámetros de inicialización en nuestra base de datos PRIMARIA.

-- Habilitar la configuración de Data Guard
ALTER SYSTEM SET LOG_ARCHIVE_CONFIG='DG_CONFIG=(primario,standby)' SCOPE=BOTH;

-- Definir el destino del envío de redo hacia el standby
ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=standby ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=standby' SCOPE=BOTH;
ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=ENABLE SCOPE=BOTH;

-- Formato de los archive logs y procesos de archivado
ALTER SYSTEM SET LOG_ARCHIVE_FORMAT='%t_%s_%r.arc' SCOPE=SPFILE;
ALTER SYSTEM SET LOG_ARCHIVE_MAX_PROCESSES=30 SCOPE=BOTH;

-- Password file exclusivo (necesario para log transport)
ALTER SYSTEM SET REMOTE_LOGIN_PASSWORDFILE=EXCLUSIVE SCOPE=SPFILE;

-- Parámetros para cuando la PRIMARIA asuma el rol de STANDBY (switchover/failover)
ALTER SYSTEM SET FAL_SERVER=standby SCOPE=BOTH;
ALTER SYSTEM SET DB_FILE_NAME_CONVERT='/u01/app/oracle/oradata/standby/','/u01/app/oracle/oradata/primario/' SCOPE=SPFILE;
ALTER SYSTEM SET LOG_FILE_NAME_CONVERT='/u01/app/oracle/oradata/standby/','/u01/app/oracle/oradata/primario/' SCOPE=SPFILE;
ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO SCOPE=BOTH;

6) Reinicio de base de datos PRIMARIA

Para que tomen efecto los parámetros que no son dinámicos en la base de datos es necesario realizar un reinicio de la misma.

SHUTDOWN IMMEDIATE;
STARTUP;

-- Verificar que los parámetros tomaron efecto
SHOW PARAMETER LOG_ARCHIVE_CONFIG
SHOW PARAMETER LOG_ARCHIVE_DEST_2

7) Creación de PFILE para STANDBY

-- Crear un PFILE a partir del SPFILE de la base de datos PRIMARIA
CREATE PFILE='/home/oracle/initstandby.ora' FROM SPFILE;

8) Respaldo RMAN completo de la base de datos PRIMARIA

# Conectarse a RMAN en el servidor PRIMARIO
rman target /

# Respaldo completo de la base de datos más archivelogs
RMAN> BACKUP DATABASE PLUS ARCHIVELOG;
# Alternativa: respaldo a una ubicación específica para enviar al standby
mkdir -p /home/oracle/backup

rman target / <<EOF
BACKUP DATABASE PLUS ARCHIVELOG FORMAT '/home/oracle/backup/%U';
EOF

9) Creación de standby controlfile

STANDBY CONTROLFILE

-- Crear el standby controlfile en la base de datos PRIMARIA
ALTER DATABASE CREATE STANDBY CONTROLFILE AS '/home/oracle/backup/standby_control.ctl';

10) Envío de respaldo RMAN, standby controlfile, pfile y password file hacia servidor de contingencia

# Enviar respaldo RMAN y standby controlfile
scp -r /home/oracle/backup/* oracle@standby:/home/oracle/backup/

# Enviar el PFILE creado para el standby
scp /home/oracle/initstandby.ora oracle@standby:/home/oracle/

# Enviar el password file (renombrando según el ORACLE_SID del standby)
scp $ORACLE_HOME/dbs/orapwprimario oracle@standby:$ORACLE_HOME/dbs/orapwstandby

11) Creación de directorios faltantes para base de datos STANDBY

# En el servidor STANDBY, crear los directorios necesarios
mkdir -p /u01/app/oracle/oradata/standby
mkdir -p /u01/app/oracle/fast_recovery_area/standby
mkdir -p /u01/app/oracle/admin/standby/adump

# Directorio donde llegan los respaldos
mkdir -p /home/oracle/backup

12) Copia de Standby Controlfile

# En el servidor STANDBY, copiar el standby controlfile a las ubicaciones
# definidas en el parámetro CONTROL_FILES del PFILE
cp /home/oracle/backup/standby_control.ctl /u01/app/oracle/oradata/standby/control01.ctl
cp /home/oracle/backup/standby_control.ctl /u01/app/oracle/fast_recovery_area/standby/control02.ctl

13) Edición de PFILE en servidor STANDBY

Editamos el archivo PFILE que fue enviado desde nuestro sitio PRIMARIO con los valores de acuerdo a nuestro sitio de contingencia

# /home/oracle/initstandby.ora  (editado en el servidor STANDBY)
*.db_name='primario'
*.db_unique_name='standby'
*.log_archive_config='DG_CONFIG=(primario,standby)'
*.log_archive_dest_2='SERVICE=primario ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=primario'
*.log_archive_dest_state_2=ENABLE
*.log_archive_format='%t_%s_%r.arc'
*.log_archive_max_processes=30
*.remote_login_passwordfile='EXCLUSIVE'
*.fal_server='primario'
*.db_file_name_convert='/u01/app/oracle/oradata/primario/','/u01/app/oracle/oradata/standby/'
*.log_file_name_convert='/u01/app/oracle/oradata/primario/','/u01/app/oracle/oradata/standby/'
*.standby_file_management='AUTO'
*.control_files='/u01/app/oracle/oradata/standby/control01.ctl','/u01/app/oracle/fast_recovery_area/standby/control02.ctl'

14) Creación de SPFILE desde PFILE editado

Creamos un SPFILE a partir del PFILE anteriormente editado, para montar la base de datos

-- En el servidor STANDBY, exportar el ORACLE_SID correspondiente
-- export ORACLE_SID=standby

sqlplus / as sysdba

-- Crear SPFILE a partir del PFILE editado
CREATE SPFILE FROM PFILE='/home/oracle/initstandby.ora';

15) Montamos la base de datos STANDBY

-- Iniciar la base de datos STANDBY en modo MOUNT (no se abre)
STARTUP MOUNT;

-- Verificar el rol y el modo
SELECT database_role, open_mode FROM v$database;
-- Debe mostrar: PHYSICAL STANDBY / MOUNTED

16) Catalogamos respaldos RMAN 

Debido a que los repaldos RMAN enviados desde el servidor PRIMARIO se encuentran en un directorio distinto al origen debemos catalogarlos nuevamente.

rman target /

# Catalogar todos los backup pieces del nuevo directorio
RMAN> CATALOG START WITH '/home/oracle/backup/';

# Confirmar con YES cuando lo solicite
# Verificar que los respaldos estén catalogados
RMAN> LIST BACKUP;

17) Restaruramos Base de Datos STANDBY a partir de respaldo RMAN enviado de sitio PRIMARIO

rman target /

# Restaurar la base de datos STANDBY desde los respaldos catalogados
RMAN> RESTORE DATABASE;

18) Renombramos Redo logs

Una vez completa la restauración de la base de datos STANDBY, debemos renombrar los redologs.

-- La base de datos debe estar en MOUNT
-- Renombrar los online redo logs a las rutas del standby
ALTER DATABASE RENAME FILE '/u01/app/oracle/oradata/primario/redo01.log' TO '/u01/app/oracle/oradata/standby/redo01.log';
ALTER DATABASE RENAME FILE '/u01/app/oracle/oradata/primario/redo02.log' TO '/u01/app/oracle/oradata/standby/redo02.log';
ALTER DATABASE RENAME FILE '/u01/app/oracle/oradata/primario/redo03.log' TO '/u01/app/oracle/oradata/standby/redo03.log';

19) Recover de base de datos STANDBY

rman target /

-- Aplicar los archive logs respaldados desde el PRIMARIO
RMAN> RECOVER DATABASE;

-- Si no se dispone de los archive logs en el respaldo y se desea
-- que el redo llegue vía log transport, usar:
-- RMAN> RECOVER DATABASE NOREDO;

20) Recreamos standby redo logs

-- Eliminar los standby redo logs con rutas del primario (si existen)
ALTER DATABASE DROP STANDBY LOGFILE GROUP 4;
ALTER DATABASE DROP STANDBY LOGFILE GROUP 5;
ALTER DATABASE DROP STANDBY LOGFILE GROUP 6;
ALTER DATABASE DROP STANDBY LOGFILE GROUP 7;

-- Recrear los standby redo logs con las rutas del STANDBY
ALTER DATABASE ADD STANDBY LOGFILE ('/u01/app/oracle/oradata/standby/srl01.log') SIZE 50M;
ALTER DATABASE ADD STANDBY LOGFILE ('/u01/app/oracle/oradata/standby/srl02.log') SIZE 50M;
ALTER DATABASE ADD STANDBY LOGFILE ('/u01/app/oracle/oradata/standby/srl03.log') SIZE 50M;
ALTER DATABASE ADD STANDBY LOGFILE ('/u01/app/oracle/oradata/standby/srl04.log') SIZE 50M;

-- Verificar
SELECT group#, bytes/1024/1024 AS size_mb, status FROM v$standby_log;

21) Iniciamos proceso APPLY en base de datos  STANDBY

-- Iniciar el Managed Recovery Process (MRP) en tiempo real
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

-- Verificar que el apply esté funcionando
SELECT process, status, thread#, sequence#, block#, blocks
FROM v$managed_standby
WHERE process LIKE 'MRP%';

-- Verificar el gap entre primario y standby
SELECT thread#, MAX(sequence#) FROM v$archived_log GROUP BY thread#;

-- En el PRIMARIO, verificar el estado del envío de redo
SELECT dest_name, status, error FROM v$archive_dest WHERE dest_id=2;
-- Para DETENER el proceso APPLY si fuera necesario
-- ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;