Datafiles UNAMED en dataguard

Hoy vamos a ver un a pequeña entrada de un error bastante común en dataguard.

El problema se da cuando la base de datos standby deja de aplicar

DGMGRL> show configuration verbose
Configuration - test
  Protection Mode: MaxPerformance
  Members:
  DBTEST        - Primary database
    DBTEST_STBY   - Physical standby database
      Error: ORA-16810: multiple errors or warnings detected for the database

Ante un error tan genérico como este, lo primero que hemos de hacer es buscar en el alert.log de la base de datos del standby.
En este alert.log ya vemos un error mas claro

Errors in file /u01/app/oracle/diag/rdbms/dbtest_stby/dbtest/trace/dbtest_mrp0_3972.trc:
ORA-01111: name for data file 21 is unknown - rename to correct file
ORA-01110: data file 21: '/u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/UNNAMED0021'
ORA-01157: cannot identify/lock data file 21 - see DBWR trace file
ORA-01111: name for data file 21 is unknown - rename to correct file
ORA-01110: data file 21: '/u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/UNNAMED0021'

Que es ese datafile que aparece en el $ORACLE_HOME/dbs llamado UNNAMED?

La respuesta nos la da oracle en la nota ID 739618.1..
Estos ficheros aparecen en el equipo de standby cuando se ha creado un datafile en el primario y el secundario no ha podido crearlo (por falta de espacio, error de configuración …. )

Como lo solucionamos ?

Lo primero que tenemos que hacer es cambiar el STANDBY_FILE_MANAGEMENT a MANUAL ya que vamos a modificar manualmente la ubicación de ficheros.

ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=MANUAL;

Tras esto, identificaremos en la base de datos primary cual es la ubicación correcta del fichero, si miramos en el extracto anterior del alert.log, veremos que se trata del datafile 21, así pues, iremos a la base de datos primary y veremos donde esta ubicado .

SQL>   select file_name,tablespace_name,bytes/1024/1024/1024 Gb
  from dba_data_files where file_id=21;

FILE_NAME  		                      TABLESPACE_NAME      GB 
----------------------------------------------------------------
+DATA_01/DBTEST/DATAFILE/testdf.791.968123327   TESTDF           5

Ahora tenemos que ir al standby y mover el fichero UNNAMED a su lugar correcto, para ello no usaremos el MOVE sino el comando CREATE DATAFILE AS

alter database create datafile 
'/u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/UNNAMED0021'
 as '+DATA_01' ;

Como podéis ver, no ha indicado el nombre que debe de tener el datafile, solamente la ruta, esto es por que tenemos definido el parametro db_recovery_file_dest que nos lo dejara con el nombre correcto.

Posible errores

Efectivamente, con el comando anterior no va a funcionar, ya que nos dara el error

ERROR at line 1:
ORA-01136: specified size of file 204 (80 blocks) is less than original size of
655360 blocks
ORA-01111: name for data file 204 is unknown - rename to correct file
ORA-01110: data file 204:
'/u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/UNNAMED0021'

Que hemos echo mal ?

No hemos echo nada mal, lo que ocurre es que cuando la ubicación de destino es dentro el ASM tendremos que indicarle el tamaño exacto del fichero .
En el alert nos ha indicado que el tamaño es de 655360 blocks
Si miramos el tamaño de bloque que tenemos :

SQL> show parameter block_size
NAME               TYPE        VALUE
------ --------------------------------------
db_block_size     integer       8192

Llevando a cabo una pequeña operacion aritmética 655360 *8192=5368709120

Ya podemos ejecutar el comando completo

alter database create datafile 
'/u01/app/oracle/product/12.1.0.2/dbhome_1/dbs/UNNAMED0021' 
as '+DATA_01'size 5368709120;

Con esto tenemos el problema solucionado.

Volvemos a poner el standby en modo management auto

ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO;

Y activamos el broker de nuevo desde el primario.

DGMGRL> show configuration verbose
Configuration - test
  Protection Mode: MaxPerformance
  Members:
  DBTEST        - Primary database
    DBTEST_STBY   - Physical standby database
      Error: ORA-16810: multiple errors or warnings detected for the database

DGMGRL> enable database 'DBTEST_STBY'
Disabled.
DGMGRL> enable database 'DBTEST_STBY'
Enabled.
DGMGRL> show configuration verbose
Configuration - test
  Protection Mode: MaxPerformance
  Members:
  DBTEST        - Primary database
    DBTEST_STBY   - Physical standby database
.
.

Configuration Status:
SUCCESS

Como siempre , mas información en las notas de soporte

  • How to resolve ORA-01111 ORA-01110 ORA-01157 in a physical standby database (Doc ID 1416554.1)
  • Background Media Recovery terminated with ORA-1274 after adding a Datafile (Doc ID 739618.1)

Bloques coruptos en una base de datos

Uno de los problemas a los que tenemos que enfrentarnos dia a dia es el de lidiar con bloques corruptos en la base de datos.

Vayamos al supuesto en el que alguna de nuestras herramientas (RMNA,EMC,dbvf, el propio motor en algun acceso) ha detectado que tenemos estos bloques corruptos. La manera de encontarlos es mediante la vista V$DATABASE_BLOCK_CORRUPTION

SQL> select * from V$DATABASE_BLOCK_CORRUPTION;
	 FILE#     BLOCK#     BLOCKS CORRUPTION_CHANGE# CORRUPTIO
---------- ---------- ---------- ------------------ ---------
	 2      88231          1            6821577 NOLOGGING
	 2      58442          1            6821577 NOLOGGING

Recuperacion de bloques corruptos

La manera de recuperarlos es tan sencillo como decirle al RMAN que lo haga, para esto ejecutaremos el comando de rman RECOVER CORRUPTION LIST;:
RMAN> RECOVER CORRUPTION LIST;
Starting recover at 14-JAN-18
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=206 device type=DISK
starting media recovery
media recovery complete, elapsed time: 00:00:01
Finished recover at 14-JAN-18

Comprobacion de que han sido recuperados

Aunque rman nos haya dicho OK, deberemos revisar que los bloques estan correctos, para ello usaremos la opcion VALIDATE DATAFILE de RMAN aplicado al FILE# que nos indicaba la vista de bloques corruptos
RMAN>  validate datafile 2;

Starting validate at 14-JAN-18
using channel ORA_DISK_1
channel ORA_DISK_1: specifying datafile(s) for validation
input datafile file number=2 name=/u01/app/oracle/ORASID/sysaux01.dbf
channel ORA_DISK_1: validation complete, elapsed time: 00:00:01

List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
2    OK     0              21603        336384          41455048 

Finished validate at  14-JAN-18

Y si no lo ha solucionado?

Que ocurre si RMAN no ha podido recuperar el bloque corrupto?
En este caso el comando validate nos devolveria algo similar a

RMAN> validate datafile 2;
Starting validate at 14-JAN-18
using channel ORA_DISK_1
channel ORA_DISK_1: starting validation of datafile
channel ORA_DISK_1: specifying datafile(s) for validation
input datafile file number=2 name=/u01/app/oracle/ORASID/sysaux01.dbf
channel ORA_DISK_1: validation complete, elapsed time: 00:00:01
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks Examined High SCN
---- ------ -------------- ------------ --------------- ----------
2    OK     2              20225        99863           49937565
File Name: /u01/app/oracle/ORASID/sysaux01.dbf
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data       0              26483
Index      0              24051
Other      0              29081
Finished validate at 14-JAN-18

Por que puede ser esto?
En el caso en que no resolvamos el problema, echaremos un vistazo al alert.log,


ORA-01578: ORACLE data block corrupted (file # ORA-01578: ORACLE data block corrupted (file # 2, block # 58442)
ORA-01110: data file 2: '/u01/app/oracle/ORASID/sysaux01.dbf'
ORA-26040: Data block was loaded using the NOLOGGING option

Lo que nos esta indicando este error es que el objeto se creo en modo nologging por lo que la base de datos no tiene informacion de como recuperarla, si queremos recuperar esta informacion deberemos de recrear el objeto ( y cruzar los dedos para que este objeto sea un indice y no datos de negocio)

COmo siempre podemos encontrar mas informacion al respecto en soporte Oracle en las notas:

  • How to identify the corrupt Object reported by ORA-1578 / RMAN / DBVERIFY (Doc ID 819533.1)
  • ORA-1578 / ORA-26040 Corrupt blocks by NOLOGGING - Error explanation and solution (Doc ID 794505.1)
  • How to identify all the Corrupted Objects in the Database with RMAN (Doc ID 472231.1)