by Enrique Orbegozo

Un problema recurrente con las bases de datos Standby es la pérdida de uno o más archivelog aún no aplicados. La solución era usualmente el reconstruir la base de datos Standby, lo cual si bien es relativamente fácil, puede consumir bastante tiempo. Esto fue lo que algunos sugirieron a un afligido DBA que pedía ayuda en el foro de Oracle Technet hace algún tiempo. Afortunadamente desde Oracle Server 10gR2 la solución se hizo mucho más simple y rápida, y ha sido detallada en muchos blogs, incluso acá mismo en Toad World, pero a partir de Oracle Server 12cR1 lo es mucho más. ¿Suena bien? Entonces veamos el procedimiento detallado*, pero primero tengamos en cuenta que el escenario sobre el cual trabajaremos es el siguiente.

* El procedimiento a ser mostrado ha sido probado con Oracle Server 12.1.0.1

  

Se trata de una base de datos con su respectivo Standby, sincronizado mediante Real Time Apply, y con Data Guard Broker configurado (opcional).

DGMGRL> show configuration

Configuration - dbtest

Protection Mode: MaxPerformance
Databases:
prim - Primary database
   stdb - Physical standby database

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

En segundo lugar asumiremos que se presenta el escenario más complicado: debido a una falla se suspendió la sincronización temporalmente, intervalo en el cual:

  • Se adicionó un datafile al tablespace DemoData (datafile 6).
  • Accidentalmente se eliminaron algunos archivelog necesarios para reiniciar la sincronización (75,76 y 77)

 Debido a ello, cuando se reinicia la sincronización del Standby, ésta se suspende ante la falta de los archivelog, tal como se reporta en el archivo alert.log y se confirma con dgmgrl.

Thu Jun 26 17:28:33 2014
Primary database is in MAXIMUM PERFORMANCE mode
RFS[3]: Assigned to RFS process (PID:4918)
RFS[3]: Selected log 4 for thread 1 sequence 81 dbid 2149324683 branch 851178251
Thu Jun 26 17:28:37 2014
RFS[4]: Assigned to RFS process (PID:4920)
RFS[4]: Selected log 5 for thread 1 sequence 80 dbid 2149324683 branch 851178251
Thu Jun 26 17:28:44 2014
Archived Log entry 34 added for thread 1 sequence 80 ID 0x801b348b dest 1:
Thu Jun 26 17:28:54 2014
FAL[client]: Failed to request gap sequence
GAP - thread 1 sequence 75-77
DBID 2149324683 branch 851178251

FAL[client]: All defined FAL servers have been attempted.
------------------------------------------------------------
Check that the CONTROL_FILE_RECORD_KEEP_TIME initialization
parameter is defined to a value that's sufficiently large
enough to maintain adequate log switch information to resolve
archivelog gaps.
------------------------------------------------------------

DGMGRL> show configuration

Configuration - dbtest

Protection Mode: MaxPerformance
Databases:
prim - Primary database
   Error: ORA-16724: cannot resolve gap for one or more standby databases

   stdb - Physical standby database

Fast-Start Failover: DISABLED

Configuration Status:
ERROR

Con estas consideraciones, los pasos a seguir para resolver este problema son los siguientes:

1. Ya que Data Guard Broker está configurado y operando, hay que detenerlo a fin de que no se reintente automáticamente la sincronización mientras ejecutamos el presente procedimiento.

sys@STDB> ALTER SYSTEM SET DG_BROKER_START=FALSE;

2. Tomar nota de los online redo logs y standby redo logs existentes en la base de datos Standby.

sys@STDB> select distinct group#, type from v$logfile;

   GROUP#  TYPE
---------- ---------------------
         1 ONLINE
         2 ONLINE         
         3 ONLINE
         4 STANDBY
         5 STANDBY
         6 STANDBY
         7 STANDBY

 3. Detener la sincronización de la base de datos Standby.

sys@STDB> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

Statement processed

4. Obtener el SCN al cual se ha llegado a sincronizar la base de datos Standby.

sys@STDB> SELECT MIN(F.FHSCN)
           FROM X$KCVFH F, V$DATAFILE D
           WHERE F.HXFIL = D.FILE#
             AND D.ENABLED != 'READ ONLY';

MIN(F.FHSCN) 
----------------
509983

5. Obtener la relación de datafiles que se han creado en la base de datos Primary, posteriormente al SCN obtenido en el paso anterior.

sys@PRIM> SELECT FILE#, NAME
           FROM V$DATAFILE
           WHERE CREATION_CHANGE# > 509983;

     FILE#  NAME
---------- --------------------------------------------------
         6 +DATA/PRIM/DATAFILE/demodata.309.851275097;

6. Detener la base de datos Standby y levantarla en estado nomount.

sys@STDB> SHUTDOWN IMMEDIATE;

database dismounted
Oracle instance shut down

sys@STDB> STARTUP NOMOUNT;

connected to target database (not started)
Oracle instance started

Total System Global Area     784998400 bytes

Fixed Size                     2293296 bytes
Variable Size               314573264 bytes
Database Buffers             465567744 bytes
Redo Buffers                   2564096 bytes

7. Restaurar el standby controlfile a partir del controlfile de la base de datos Primary, usando para ello un string de conexión (definida en el archivo tnsnames.ora) que la referencie.

RMAN> RESTORE STANDBY CONTROLFILE FROM SERVICE prim;

Starting restore at 26/06/2014 18:01:22
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=23 device type=DISK

channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: using network backup set from service prim
channel ORA_DISK_1: restoring control file
channel ORA_DISK_1: restore complete, elapsed time: 00:00:07
output file name=+DATA/STDB/CONTROLFILE/current.264.851195749
output file name=+DATA/STDB/CONTROLFILE/current.265.851195753
Finished restore at 26/06/2014 18:01:29

8. Montar la base de datos Standby.

RMAN> ALTER DATABASE MOUNT;

Statement processed

9. Restaurar los datafiles faltantes en la base de datos Standby, identificados en el paso 5.

RMAN> RESTORE DATAFILE 6 FROM SERVICE prim;

Starting restore at 26/06/2014 18:05:21
using channel ORA_DISK_1

channel ORA_DISK_1: starting datafile backup set restore
channel ORA_DISK_1: using network backup set from service prim
channel ORA_DISK_1: specifying datafile(s) to restore from backup set
channel ORA_DISK_1: restoring datafile 00006 to +DATA/PRIM/DATAFILE/demodata.309.851275097
channel ORA_DISK_1: restore complete, elapsed time: 00:00:08
Finished restore at 26/06/2014 18:05:29

10. Ya que se está usando un nuevo standby controlfile, éste contiene referencias a los nombres que tienen los datafiles en la base de datos Primary, por lo que es necesario cambiarlas a los nombres que tienen en la base de datos Standby.

RMAN> switch datafile 1,2,3,4,5 to copy;

datafile 1 switched to datafile copy "+DATA/STDB/DATAFILE/system.266.851195769"
datafile 2 switched to datafile copy "+DATA/STDB/DATAFILE/sysaux.267.851195803"
datafile 3 switched to datafile copy "+DATA/STDB/DATAFILE/undotbs1.268.851195829"
datafile 4 switched to datafile copy "+DATA/STDB/DATAFILE/users.269.851195853"
datafile 5 switched to datafile copy "+DATA/STDB/DATAFILE/demodata.260.851274537"

Obsérvese que se incluye la relación completa de datafiles, exceptuando aquellos que se han restaurado manualmente como se detalla en el paso 9, ya que para ellos los nombres son los correctos.

11. Actualizamos la base de datos Standby usando un backup incremental de los datafiles de la pase de datos Primary, usando para ello un string de conexión (definida en el archivo tnsnames.ora) que la referencie.

RMAN> RECOVER DATABASE FROM SERVICE prim NOREDO;

Starting recover at 26/06/2014 18:07:41
using channel ORA_DISK_1
skipping datafile 6; already restored to SCN 517415
channel ORA_DISK_1: starting incremental datafile backup set restore
channel ORA_DISK_1: using network backup set from service prim
destination for restore of datafile 00001: +DATA/STDB/DATAFILE/system.266.851195769
channel ORA_DISK_1: restore complete, elapsed time: 00:00:15
channel ORA_DISK_1: starting incremental datafile backup set restore
channel ORA_DISK_1: using network backup set from service prim
destination for restore of datafile 00002: +DATA/STDB/DATAFILE/sysaux.267.851195803
channel ORA_DISK_1: restore complete, elapsed time: 00:00:15
channel ORA_DISK_1: starting incremental datafile backup set restore
channel ORA_DISK_1: using network backup set from service prim
destination for restore of datafile 00003: +DATA/STDB/DATAFILE/undotbs1.268.851195829
channel ORA_DISK_1: restore complete, elapsed time: 00:00:15
channel ORA_DISK_1: starting incremental datafile backup set restore
channel ORA_DISK_1: using network backup set from service prim
destination for restore of datafile 00004: +DATA/STDB/DATAFILE/users.269.851195853
channel ORA_DISK_1: restore complete, elapsed time: 00:00:01
channel ORA_DISK_1: starting incremental datafile backup set restore
channel ORA_DISK_1: using network backup set from service prim
destination for restore of datafile 00005: +DATA/STDB/DATAFILE/demodata.260.851274537
channel ORA_DISK_1: restore complete, elapsed time: 00:00:03

Finished recover at 26/06/2014 18:08:31

12. Actualizar los nombres de los online redo logs y standby redo logs, de los que se tomó nota en el paso 2.

RMAN> ALTER DATABASE CLEAR LOGFILE GROUP 1;

Statement processed

RMAN> ALTER DATABASE CLEAR LOGFILE GROUP 2;

Statement processed

RMAN> ALTER DATABASE CLEAR LOGFILE GROUP 3;

Statement processed

RMAN> ALTER DATABASE CLEAR LOGFILE GROUP 4;

Statement processed

RMAN> ALTER DATABASE CLEAR LOGFILE GROUP 5;

Statement processed

RMAN> ALTER DATABASE CLEAR LOGFILE GROUP 6;

Statement processed

RMAN> ALTER DATABASE CLEAR LOGFILE GROUP 7;

Statement processed

13. Reactivamos Data Guard Broker.

sys@STDB> ALTER SYSTEM SET DG_BROKER_START=TRUE;

Statement processed

14. Reactivamos la sincronización de la base de datos Standby.

sys@STDB> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT NODELAY;

Statement processed

15. Verificamos que todo opera normalmente.

sys@STDB> SELECT process, status, thread#, sequence#
        FROM v$managed_standby;

PROCESS   STATUS         THREAD#  SEQUENCE#
--------- ------------ ---------- ----------
ARCH     CONNECTED             0         0
ARCH     CONNECTED             0         0
ARCH     CLOSING               1        83
ARCH     CONNECTED             0         0
MRP0     APPLYING_LOG          1        84
RFS      IDLE                  1        84
RFS      IDLE                  0         0
RFS      IDLE                  0         0

8 rows selected

 

RMAN> SELECT * FROM v$archive_gap;

no rows selected

 

DGMGRL> show configuration;

Configuration - dbtest

Protection Mode: MaxPerformance
Databases:
prim - Primary database
   stdb - Physical standby database

Fast-Start Failover: DISABLED

Configuration Status:
SUCCESS

Listo, tarea concluida, ya no existe gap alguno y la base de datos Standby se está sincronizando normalmente en base al redo que recibe de la base de datos Primary.

Finalmente se señala que este procedimiento aplica no sólo cuando un archivelog se ha perdido, sino también cuando se han realizado operaciones con nologging en la base de datos Primary, o cuando hay un gran retraso en la sincronización.