Desde la versión 11g, la posibilidad de descargar los backups RMAN en una BD standby física (no aplica en standby lógica) es completa, pudiendo hacer copia del controlfile para recuperar cualquier rol Data Guard (primaria o standby). Podemos por lo tanto hacer copias de la BD en una standby sin preocuparnos de cómo generar, de ser necesario, un controlfile CURRENT en un escenario de disaster recovery de producción, ya que Oracle gestionará de manera automática y transparente la conversión de rol que sea necesaria (aplica también a una standby a partir de un controlfile current). Como requisito, debemos configurar correctamente las BDs primaria y standby en el catálogo RMAN, importante para una correcta ejecución de los backups y escenarios de recuperación en esta configuración. Esta funcionalidad de intercambio de roles de controlfile entre primaria y standby aparece documentada desde la versión 11.1 de base de datos. En esta documentación se indica que los metadatos almacenados en el catálogo RMAN permiten hacer un seguimiento correcto de todos los nombres de los ficheros de las BDs que componen la configuración Data Guard, haciendo posible el intercambio de datafiles y controlfiles.

Recientemente, haciendo una validación de restore cruzado a un nuevo servidor en un cliente, encontré con que aparentemente esta premisa no se cumplía, y la restauración del controlfile mantenía el nuevo controlfile de la BD como standby. Tras diferentes pruebas y consulta de información y de notas Metalink, encontramos que el problema venía derivado del bug 18455956, que en realidad sólo se presenta en un escenario en el que la restauración del controlfile es ejecutado sin conexión al catálogo RMAN, que era justo la prueba que queríamos validar haciendo una apertura con resetlogs sin con ello impactar al resto de la configuración Data Guard registrada en el mismo catálogo, evitando añadir una nueva encarnación “falsa” derivada de esta prueba. El objetivo global era validar un escenario en el que derivar todas las tareas de backup a una BD standby, pero este problema me hizo plantear la posibilidad de tener que hacer backups del controlfile primario (ayudado, todo sea dicho, por un error en la documentación de certificación Fecha Guard de Oracle University donde se indicaba que los controlfiles no son intercambiables entre primary y standby).

Para verificar las posibilidades reales, creamos una BD single instance en un servidor con una standby física en otro. Para simplificar las cosas, las dos máquinas son en realidad un clúster con Grid Infrastructure, que comparten acceso a un filesystem ACFS montado en /acfs/desdata. La BD primaria tiene por nombre alberto y la standby bertodg (nomenclatura de Sergio la quien debo agradecer que montara este contorno en un tiempo récord con su magia usando gdbClone!). Antes de hacer las pruebas de restauración, ejecutamos en bertodg (standby) simplemente el comando backup database que hizo un backup a la FRA configurada en el mismo filesystem. Por lo tanto es un escenario sencillo donde los backups de las BDs están disponibles en los dos entornos sin necesidad de copiar datos previamente o tenerlos que recatalogar antes de restaurar.

Restauración de BD primaria con copia de standby usando conexión a catálogo RMAN

Conectados a la BD alberto (primaria) y al catálogo, en esta prueba el script RMAN restaura explícitamente el controfile del backup hecho previamente en la BD bertodg (standby). Pese a ser un standby controlfile, y sin especificar nada en el comando RMAN, este es restaurado de manera automática como un current controlfile válido para una BD primaria.

[oracle@nodo1 ]$ rman target / catalog=usrcat/xxxxxx@rman
RMAN> run
{
  shutdown immediate;
  startup nomount;
  restore controlfile from '/acfs/desdata/bertodg/BERTODG/backupset/2017_09_29/el1_mf_ncsnf_TAG20170929T120630_dww6sbyk_.bkp';
  alter database mount;
  restore database;
  recover database noredo;
  alter database open resetlogs;
}2> 3> 4> 5> 6> 7> 8> 9> 10> 

database closed
database dismounted
Oracle instance shut down

connected to target database (not started)
Oracle instance started

Total System Global Arena    4275781632 bytees

Fixed Size                     2260088 bytees
Variable Size               2449474440 bytees
Database Buffers            1811939328 bytees
Redo Buffers                  12107776 bytees

Starting restore at 29/09/2017 12:54:12
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=212 device type=DISK

channel ORA_DISK_1: restoring control file
channel ORA_DISK_1: restore complete, elapsed time: 00:00:01
output file name=/acfs/desdata/alberto/control01.ctl
Finished restore at 29/09/2017 12:54:13

database mounted
released channel: ORA_DISK_1

Starting restore at 29/09/2017 12:54:17
Starting implicit crosscheck backup at 29/09/2017 12:54:17
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=212 device type=DISK
Crosschecked 1 objects
Finished implicit crosscheck backup at 29/09/2017 12:54:18

Starting implicit crosscheck copy at 29/09/2017 12:54:18
using channel ORA_DISK_1
Crosschecked 2 objects
Finished implicit crosscheck copy at 29/09/2017 12:54:18

searching fuere all files in the recovery arena
cataloging files...
cataloging done

List of Cataloged Files
=======================
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_28/el1_mf_1_34_06sfjc3k_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_28/el1_mf_1_1_dwsnj7rf_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_28/el1_mf_1_2_dwsnjx2d_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_28/el1_mf_1_3_dwsnlrhm_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_28/el1_mf_1_4_dwsnlvhy_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_28/el1_mf_1_5_dwt92r23_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_28/el1_mf_1_6_dwt92wjf_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_28/el1_mf_1_7_dwtrr0tq_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_29/el1_mf_1_8_dwvggf46_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_29/el1_mf_1_1_dww55lnk_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_29/el1_mf_1_2_dww55q9x_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_29/el1_mf_1_3_dww5rdbj_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_29/el1_mf_1_4_dww7z6wb_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_29/el1_mf_1_1_dww7z75j_.arc
File Name: /acfs/desdata/alberto/ALBERTO/archivelog/2017_09_29/el1_mf_1_2_dww7zbnc_.arc

using channel ORA_DISK_1

channel ORA_DISK_1: restoring datafile 00001
input datafile copy RECID=11 STAMP=955976061 file name=/acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_system_03sfjd9lo_.dbf
destination fuere restore of datafile 00001: /acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_system_02sfjc33_.dbf
channel ORA_DISK_1: copied datafile copy of datafile 00001
output file name=/acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_system_02sfjc33_.dbf RECID=15 STAMP=955976062
channel ORA_DISK_1: restoring datafile 00002
input datafile copy RECID=12 STAMP=955976061 file name=/acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_sysaux_04sfjd9lo_.dbf
destination fuere restore of datafile 00002: /acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_sysaux_03sfjc33_.dbf
channel ORA_DISK_1: copied datafile copy of datafile 00002
output file name=/acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_sysaux_03sfjc33_.dbf RECID=16 STAMP=955976065
channel ORA_DISK_1: restoring datafile 00003
input datafile copy RECID=13 STAMP=955976061 file name=/acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_undotbs1_05sfjd9lo_.dbf
destination fuere restore of datafile 00003: /acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_undotbs1_04sfjc33_.dbf
channel ORA_DISK_1: copied datafile copy of datafile 00003
output file name=/acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_undotbs1_04sfjc33_.dbf RECID=17 STAMP=955976068
channel ORA_DISK_1: restoring datafile 00004
input datafile copy RECID=14 STAMP=955976061 file name=/acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_users_06sfjd9r_.dbf
destination fuere restore of datafile 00004: /acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_users_05sfjc3i_.dbf
channel ORA_DISK_1: copied datafile copy of datafile 00004
output file name=/acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_users_05sfjc3i_.dbf RECID=18 STAMP=955976068

datafile 1 switched to datafile copy
input datafile copy RECID=19 STAMP=955976069 file name=/acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_system_02sfjc33_.dbf
datafile 2 switched to datafile copy
input datafile copy RECID=20 STAMP=955976069 file name=/acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_sysaux_03sfjc33_.dbf
datafile 3 switched to datafile copy
input datafile copy RECID=21 STAMP=955976069 file name=/acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_undotbs1_04sfjc33_.dbf
datafile 4 switched to datafile copy
input datafile copy RECID=22 STAMP=955976069 file name=/acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_users_05sfjc3i_.dbf
Finished restore at 29/09/2017 12:54:29

Starting recover at 29/09/2017 12:54:30
using channel ORA_DISK_1
renamed tempfile 1 to /acfs/desdata/.ACFS/snaps/alberto/ALBERTO/datafile/el1_mf_temp_dwsmc1kp_.tmp in control file

Finished recover at 29/09/2017 12:54:31

database opened
new incarnation of database registered in recovery catalog
starting full resync of recovery catalog
full resync complete
starting full resync of recovery catalog
full resync complete

Restauración de BD primaria con copia de standby sin conexión a catálogo RMAN

Repetimos la prueba anterior, pero esta vez sin conectar al catálogo RMAN. Funcionan la restauración y la recuperación, pero no es posible abrir la BD porque el controlfile no fue modificado por Oracle durante el proceso y sigue marcado como standby.

[oracle@nodo1 ]$ rman target /

Recovery Manager: Release 11.2.0.4.0 - Production on Sun Oct 1 15:57:04 2017

Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.

connected to target database: ALBERTO (DBID=2724215542)

RMAN> run
{
  shutdown immediate;
  startup nomount;
  restore controlfile from '/acfs/desdata/bertodg/BERTODG/backupset/2017_09_29/el1_mf_ncsnf_TAG20170929T120630_dww6sbyk_.bkp';
  alter database mount;
  restore database;
  recover database noredo;
  alter database open resetlogs;
}2> 3> 4> 5> 6> 7> 8> 9> 10> 

using target database control file instead of recovery catalog
database closed
database dismounted
Oracle instance shut down

connected to target database (not started)
Oracle instance started

Total System Global Arena    4275781632 bytees

Fixed Size                     2260088 bytees
Variable Size               2449474440 bytees
Database Buffers            1811939328 bytees
Redo Buffers                  12107776 bytees

Starting restore at 01/10/2017 15:57:24
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=212 device type=DISK

channel ORA_DISK_1: restoring control file
channel ORA_DISK_1: restore complete, elapsed time: 00:00:01
output file name=/acfs/desdata/alberto/control01.ctl
Finished restore at 01/10/2017 15:57:25

database mounted
released channel: ORA_DISK_1

Starting restore at 01/10/2017 15:57:30
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=212 device type=DISK

skipping datafile 1; already restored to file /acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_system_03sfjd9lo_.dbf
skipping datafile 2; already restored to file /acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_sysaux_04sfjd9lo_.dbf
skipping datafile 3; already restored to file /acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_undotbs1_05sfjd9lo_.dbf
skipping datafile 4; already restored to file /acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_users_06sfjd9r_.dbf
restore not done; all files read only, offline, or already restored
Finished restore at 01/10/2017 15:57:31

Starting recover at 01/10/2017 15:57:31
using channel ORA_DISK_1

Finished recover at 01/10/2017 15:57:32

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of alter db command at 10/01/2017 15:57:33
ORA-01666: control file is for a standby database

Verificamos que el controlfile no fue transformado en CURRENT durante la operación de RESTORE CONTROLFILE.

SQL> select controlfile_type from v$database;

CONTROL
-------
STANDBY

Bug 18455956

Parece lógico que al no contar con el catálogo no sea posible tomar la decisión de convertir un controlfile a un tipo diferente del momento en el que se hizo backup, ya que Oracle no tiene la referencia del rol que desempeña la BD que restauramos dentro de la configuración Data Guard. De hecho, para cubrir este hecho, el comando RESTORE CONTROLFILE puede ser empleado, ya desde 11gR1, en 3 posibles variantes:

  • RESTORE CONTROLFILE. El controlfile es restaurado en la BD a la que estamos conectado y su tipo será determinado en función del rol asignado a la BD en el catálogo RMAN al que estamos conectados. La BD sobre la que estamos trabajando mantendrá el mismo rol que tenía registrada en el catálogo antes de iniciar la recuperación.
  • RESTORE PRIMARY CONTROLFILE. Con este comando forzamos que el controlfile que restauramos, sea un backup de una primary o de una standby, sea configurado para su uso en una BD primaria.
  • RESTORE STANDBY CONTROLFILE. El controlfile restaurado será configurado cómo STANDBY independientemente del rol que tuviera la BD desde la que fue hecho el backup.

De este modo, tenemos la opción de restaurar un controlfile de manera automática manteniendo el rol original si conectamos a un repositorio RMAN, y tenemos la opción de hacer una conversión específica en caso de que vayamos a cambiar el rol de la BD o de que no podamos determinarlo de manera automática al no conectar al catálogo. Si consultamos la nota Step by Step method to create Primary/Standby Database from Standby Backup (Doc ID 1604251.1), vemos que, como consecuencia de la correción del bug 7553431, aparece un nuevo bug, el 18455956. Sin el correspondiente parche aplicado, el comando RESTORE PRIMARY CONTROLFILE no hace la conversión necesaria si no estamos empleando un catálogo RMAN cuando recuperamos una copia hecha en una standby. Si conectamos al catálogo RMAN (workaround propuesto en el bug), desaparece el problema.

En nuestro escenario, comprobamos que el parche 18455956 no está instalado, con un nivel de PSU de abril de 2017.

[oracle@nodo1 ]$ $ORACLE_HOME/OPatch/opatch lsinventory | grep "Patch Set Update"
Patch description:  "Database Patch Set Update : 11.2.0.4.170418 (24732075)"
Sub-patch  24006111; "Database Patch Set Update : 11.2.0.4.161018 (24006111)"
Sub-patch  23054359; "Database Patch Set Update : 11.2.0.4.160719 (23054359)"
Sub-patch  22502456; "Database Patch Set Update : 11.2.0.4.160419 (22502456)"
Sub-patch  21948347; "Database Patch Set Update : 11.2.0.4.160119 (21948347)"
Sub-patch  21352635; "Database Patch Set Update : 11.2.0.4.8 (21352635)"
Sub-patch  20760982; "Database Patch Set Update : 11.2.0.4.7 (20760982)"
Sub-patch  20299013; "Database Patch Set Update : 11.2.0.4.6 (20299013)"
Sub-patch  19769489; "Database Patch Set Update : 11.2.0.4.5 (19769489)"
Sub-patch  19121551; "Database Patch Set Update : 11.2.0.4.4 (19121551)"
Sub-patch  18522509; "Database Patch Set Update : 11.2.0.4.3 (18522509)"
Sub-patch  18031668; "Database Patch Set Update : 11.2.0.4.2 (18031668)"
Sub-patch  17478514; "Database Patch Set Update : 11.2.0.4.1 (17478514)"

[oracle@nodo1 ]$ $ORACLE_HOME/OPatch/opatch lsinventory | grep 18455956
[oracle@nodo1 ]$

Al ser así, podemos verificar que la restauración falla cuando no empleamos catálogo, incluso especificando la opción PRIMARY, como podemos ver en la siguiente prueba:

[oracle@nodo1 ]$ rman target /
 
Recovery Manager: Release 11.2.0.4.0 - Production on Sun Oct 1 15:58:16 2017
 
Copyright (c) 1982, 2011, Oracle and/or its affiliates.  All rights reserved.
 
connected to target database: ALBERTO (DBID=2724215542)

RMAN> run
{
  shutdown immediate;
  startup nomount;
  restore primary controlfile from '/acfs/desdata/bertodg/BERTODG/backupset/2017_09_29/el1_mf_ncsnf_TAG20170929T120630_dww6sbyk_.bkp';
  alter database mount;
  restore database;
  recover database noredo;
  alter database open resetlogs;
}2> 3> 4> 5> 6> 7> 8> 9> 10> 

database dismounted
Oracle instance shut down

connected to target database (not started)
Oracle instance started

Total System Global Arena    4275781632 bytees

Fixed Size                     2260088 bytees
Variable Size               2449474440 bytees
Database Buffers            1811939328 bytees
Redo Buffers                  12107776 bytees

Starting restore at 01/10/2017 15:58:17
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=212 device type=DISK

channel ORA_DISK_1: restoring control file
channel ORA_DISK_1: restore complete, elapsed time: 00:00:01
output file name=/acfs/desdata/alberto/control01.ctl
Finished restore at 01/10/2017 15:58:19

database mounted
released channel: ORA_DISK_1

Starting restore at 01/10/2017 15:58:23
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=212 device type=DISK

skipping datafile 1; already restored to file /acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_system_03sfjd9lo_.dbf
skipping datafile 2; already restored to file /acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_sysaux_04sfjd9lo_.dbf
skipping datafile 3; already restored to file /acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_undotbs1_05sfjd9lo_.dbf
skipping datafile 4; already restored to file /acfs/desdata/.ACFS/snaps/bertodg/BERTODG/datafile/el1_mf_users_06sfjd9r_.dbf
restore not done; all files read only, offline, or already restored
Finished restore at 01/10/2017 15:58:24

Starting recover at 01/10/2017 15:58:24
using channel ORA_DISK_1

Finished recover at 01/10/2017 15:58:25

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of alter db command at 10/01/2017 15:58:25
ORA-01666: control file is for a standby database

Alternativas sin uso de catálogo

Ahora que conocemos tanto el problema como su alcance, podemos emplear diferentes alternativas como solución. La primera pasa por recrear el controfile desde la propia BD standby para la recuperación de la BD primaria.

Puede resultar interesante saber que la BD standby que hemos recuperado puede ser abiera en modo sólo lectura.

SQL> alter database open read only;

Database altered.

Otra solución pasa por la apertura de la BD recuperada, que será una standby, como una BD primaria, forzando un failover de la misma. Previamente para evitar errores eliminamos los standby logs y también deshabilitamos flashback database, para evitar errores durante la apertura en el intento de habilitar flashback database.

SQL> select * from v$logfile;

    GROUP# ESTATUS  TYPE    MEMBER									    IS_
---------- ------- ------- -------------------------------------------------------------------------------- ---
	 3	   ONLINE  /acfs/desdata/bertodg/BERTODG/onlinelog/el1_mf_3_dwsnjzp0_.log		    EN El
	 2	   ONLINE  /acfs/desdata/bertodg/BERTODG/onlinelog/el1_mf_2_dwsnjzkj_.log		    EN El
	 1	   ONLINE  /acfs/desdata/bertodg/BERTODG/onlinelog/el1_mf_1_dwsnjzdr_.log		    EN El
	 4	   STANDBY /acfs/desdata/bertodg/BERTODG/onlinelog/el1_mf_4_dww5rdg9_.log		    EN El
	 5	   STANDBY /acfs/desdata/bertodg/BERTODG/onlinelog/el1_mf_5_dww5rdgy_.log		    EN El
	 6	   STANDBY /acfs/desdata/bertodg/BERTODG/onlinelog/el1_mf_6_dww5rdg2_.log		    EN El


SQL> alter database clear logfile group 4;

Database altered.

SQL> alter database clear logfile group 5;

Database altered.

SQL> alter database clear logfile group 6;

Database altered.

SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-38760: This database instance failed to turn on flashback database

SQL> alter database flashback off;

Database altered.

SQL> alter database open;

Database altered.

SQL> alter database flashback on;

Database altered.

SQL> select controlfile_type from v$database;

CONTROL
-------
CURRENT

Resumen

Debemos emplear catálogo RMAN siempre para hacer copias en un entorno Data Guard. Pese a ello, hay escenarios, como una prueba de restauración para convalidar los procedimientos internos de backup, en las que nos puede interesar evitar el uso del catálogo para no interferir en la configuración real de las copias. En casos como éste, debemos ser conscientes, si estamos en la versión 11.2.0.4 (no afecta a 11.2.0.3 o anteriores), de la existencia del bug 18455856 por lo que tendremos que optar, bien por la aplicación del correspondiente parche, bien por la procedimentación del escenario habida cuenta la limitación en la conversión a primary controlfile cuando no nos conectamos al catálogo RMAN.

Créditos

Ilustración: Alicia Constela