Canalblog
Editer l'article Suivre ce blog Administration + Créer mon blog
Publicité
Blog d'un DBA sur le SGBD Oracle et SQL
7 février 2021

RMAN : VALIDATE vérifier si des blocs sont corrompus - VALIDATE check if blocks are corrupted

     

Introduction
Dans un article précédent nous avons vu la commande CROSSCHECK de RMAN qui vérifie que les backups du repository RMAN sont toujours présents sur le disque dur (même nom, même répertoire).

Aujourd'hui voyons la commande VALIDATE : elle vérifie si des fichiers (datafiles, backupsets, redologs, spfile, ctrl file etc) sont corrompus ou manquants.
 



Points d'attention
N/A.




Base de tests
Une base Oracle 18c multi-tenants.




Exemples

============================================================================================
Les corruptions
============================================================================================ 

Oracle utilise trois fonctions VALIDATE : ne vous inquiétez pas, quand vous l'utilisez avec BACKUP ou RESTORE, à aucun moment Oracle ne fait de sauvegarde ou de restauration.

  • VALIDATE : effectue les mêmes types de contrôles que BACKUP VALIDATE mais Oracle peut vérifier une plus grande sélection d'objets
  • BACKUP ... VALIDATE : valider les blocs des backupsets
  • RESTORE ... VALIDATE : valider les blocs des backupsets qui seront utilisés pour un RESTORE

Un bloc corrompu est un bloc dont le contenu est différent de celui attendu par Oracle. Il y a deux types de corruption : physique et logique. Par défaut la commande VALIDATE ne détecte que les corruptions physiques, pas les logiques.

Corruption physique ou media corruption
La base ne reconnait pas du tout le bloc de données ou le checksum est invalide ou le bloc ne contient que des zéros ou bien il y a incohérence entre le header et le footer.

  • pb lié aux disques durs ou aux contrôleurs de disques
  • pb de mémoire
  • pb lié à un bug du logiciel Oracle
  • ...

Corruption logique
Le contenu du bloc est logiquement incohérent : par exemple la corruption d'un enregistrement ou d'une entrée d'index. 
Selon AskTom il est plus ardu à simuler car il faut créer un bloc Oracle de structure valide MAIS avec des données incorrectes; et pour cela il faut utiliser un éditeur hexadécimal et connaître la structure d'un bloc Oracle; on ne testera donc pas ce cas car trop complexe à implémenter!

Par défaut, VALIDATE ne teste pas la corruption logique, il faut le demander explicitement avec le mot clé LOGICAL.

La commande VALIDATE met à jour les vues suivantes chaque fois qu'elle rencontre un bloc corrompu
- V$BACKUP_CORRUPTION et V$COPY_CORRUPTION : blocs corrompus dans les backups RMAN, pas dans le base elle même
- V$DATABASE_BLOCK_CORRUPTION : blocs corrompus dans la base et non pas dans les backups RMAN

Dans V$BACKUP_CORRUPTION, voici les types de corruption répertoriés

  • ALL ZERO - Block header on disk contained only zeros. The block may be valid if it was never filled and if it is in an Oracle7 file. The buffer will be reformatted to the Oracle8 standard for an empty block.
  • FRACTURED - Block header looks reasonable, but the front and back of the block are different versions.
  • CHECKSUM - optional check value shows that the block is not self-consistent. It is impossible to determine exactly why the check value fails, but it probably fails because sectors in the middle of the block are from different versions.
  • CORRUPT - Block is wrongly identified or is not a data block (for example, the data block address is missing)
  • LOGICAL - Block is logically corrupt
  • NOLOGGING - Block does not have redo log entries (for example, NOLOGGING operations on primary database can introduce this type of corruption on a physical standby)


Dans V$DATABASE_BLOCK_CORRUPTION les types d'erreurs loggués sont les mêmes que dans V$BACKUP_CORRUPTION sauf NOLOGGING qui est absent.

Une fois les blocs corrompus identifiés, il faut utiliser l'outil "Block Media Recovery" de RMAN pour corriger le problème.


============================================================================================
Base de test
============================================================================================

J'utilise un backup du tablespace CROSS pour mes tests.
     [oracle@vbgeneric ~]$ rman target SYS@orcl
     connected to target database: ORCL12C:ORCL (DBID=2846920952)

     RMAN> list backup of tablespace CROSS;
     using target database control file instead of recovery catalog

     List of Backup Sets
     ===================
     BS Key Type LV Size Device Type Elapsed Time Completion Time
     ------- ---- -- ---------- ----------- ------------ ---------------
     2 Full 1.04M DISK 00:00:00 31-JAN-21
     BP Key: 2 Status: AVAILABLE Compressed: NO Tag: TAG20210131T094819

     Piece Name: /u01/app/oracle/fast_recovery_area/orcl12c/ORCL12C/49BFF8A6BB912582E0530100007F8BE4/backupset/2021_01_31/o1_mf_nnndf_TAG20210131T094819_j1fjsn5j_.bkp

     List of Datafiles in backup set 2
     File LV Type Ckp SCN Ckp Time Abs Fuz SCN Sparse Name
     ---- -- ---- ---------- --------- ----------- ------ ----
     21 Full 2074043 31-JAN-21 NO /u01/app/oracle/oradata/orcl12c/orcl/cross.dbf

VALIDATE d'un datafile
Si je fais un VALIDATE sur le tablespace CROSS, Oracle vérifie bien le datafile du tbs mais pas son backupset.

On voit dans la sortie que les colonnes "Marked Corrupt" et "Blocks Failing" valent 0 : excellent!
     RMAN> validate tablespace CROSS;
     Starting validate at 06-FEB-21
     allocated channel: ORA_DISK_1
     channel ORA_DISK_1: SID=42 device type=DISK
     channel ORA_DISK_1: starting validation of datafile
     channel ORA_DISK_1: specifying datafile(s) for validation
     input datafile file number=00021 name=/u01/app/oracle/oradata/orcl12c/orcl/cross.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
     ---- ------ -------------- ------------ --------------- ----------
     21     OK          0         12673           12800       2073514

     File Name: /u01/app/oracle/oradata/orcl12c/orcl/cross.dbf

     Block Type Blocks Failing Blocks Processed

     ---------- -------------- ----------------
     Data                 0           0
     Index                0           0
     Other                0         127
     Finished validate at 06-FEB-21

VALIDATE d'un backupset
Pour valider le backupset de ce tablespace, il faut utiliser le numéro du backupset. A noter que la sortie n'a rien à voir avec celle du VALIDATE du tablespace ci-dessus. Oracle ne détecte aucune erreur et on a "validation complete" donc le VALDATE a bien eu lieu.
     RMAN> validate backupset 2;
     Starting validate at 06-FEB-21
     using channel ORA_DISK_1
     channel ORA_DISK_1: starting validation of datafile backup set
     channel ORA_DISK_1: reading from backup piece /u01/app/oracle/fast_recovery_area/orcl12c/ORCL12C/49BFF8A6BB912582E0530100007F8BE4/backupset/2021_01_31/o1_mf_nnndf_TAG20210131T094819_j1fjsn5j_.bkp
     channel ORA_DISK_1: piece         handle=/u01/app/oracle/fast_recovery_area/orcl12c/ORCL12C/49BFF8A6BB912582E0530100007F8BE4/backupset/2021_01_31/o1_mf_nnndf_TAG20210131T09     4819_j1fjsn5j_.bkp tag=TAG20210131T094819
     channel ORA_DISK_1: restored backup piece 1
     channel ORA_DISK_1: validation complete, elapsed time: 00:00:01
     Finished validate at 06-FEB-21


============================================================================================
Détecter une corruption physique
============================================================================================

On crée maintenant une corruption physique en vérolant un bloc de données du tbs. Cela se fait en insérant des données incohérentes dans un bloc Oracle de 8K (le bloc N° 121) via la commande dd de Linux. 
Nous avons vu ci-dessus qu'il y a 127 blocs dans le tbs CROSS (colonne "Blocks Processed").
     SQL> alter tablespace CROSS offline;
     [oracle@vbgeneric ~]$ dd if=/u01/app/oracle/oradata/orcl12c/orcl/cross.dbf bs=8192 count=120 > t1
     [oracle@vbgeneric ~]$ dd if=/dev/zero bs=8291 count=1 > t2
     [oracle@vbgeneric ~]$ dd if=/u01/app/oracle/oradata/orcl12c/orcl/cross.dbf bs=8192 skip=121 count=26 > t3
     [oracle@vbgeneric ~]$ cp /u01/app/oracle/oradata/orcl12c/orcl/cross.dbf /u01/app/oracle/oradata/orcl12c/orcl/cross.dbf.old
     [oracle@vbgeneric ~]$ cat t1 t2 t3 > /u01/app/oracle/oradata/orcl12c/orcl/cross.dbf

Aïe, impossible de mettre le tbs online...
     SQL> alter tablespace CROSS online;
     alter tablespace CROSS online
     *
     ERROR at line 1:
     ORA-01157: cannot identify/lock data file 21 - see DBWR trace file
     ORA-01110: data file 21: '/u01/app/oracle/oradata/orcl12c/orcl/cross.dbf'

Le VALIDATE échoue mais est-ce à cause du fait que le tbs est offline ou de l'erreur que j'ai provoquée?
L'erreur "RMAN-06169: could not read file header for datafile 21 error reason 4" est pour moi liée à l'état du tbs donc ce test n'est pas suffisant pour voir quels sont les messages générés par le VALIDATE.
     RMAN> validate tablespace CROSS;
     Starting validate at 06-FEB-21
     using target database control file instead of recovery catalog
     allocated channel: ORA_DISK_1
     channel ORA_DISK_1: SID=269 device type=DISK
     RMAN-06169: could not read file header for datafile 21 error reason 4
     RMAN-00571: ===========================================================
     RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
     RMAN-00571: ===========================================================
     RMAN-03002: failure of validate command at 02/06/2021 08:00:57
     RMAN-06056: could not access datafile 21

Je vais alors sous Linux recopier la sauvegarde du datafile pour écraser le corrompu et ainsi pouvoir remettre online le tbs; attention, on parle bien des fichiers de la base, pas des backups RMAN.
     [oracle@vbgeneric ~]$ mv /u01/app/oracle/oradata/orcl12c/orcl/cross.dbf.old /u01/app/oracle/oradata/orcl12c/orcl/cross.dbf

     [oracle@vbgeneric ~]$ sqlplus SYS@orcl as sysdba
     SQL> alter tablespace CROSS online;
     Tablespace altered.

Et maintenant que le tbs est online, je recopie le fichier corrompu comme fichier du tbs SANS mettre celui-ci offline.
     [oracle@vbgeneric ~]$ cp /u01/app/oracle/oradata/orcl12c/orcl/cross.dbf.CORRUPT /u01/app/oracle/oradata/orcl12c/orcl/cross.dbf

Dans ce tbs je peux créer une table, des enregistrements certainement parce que les blocs corrompus ne sont pas utilisés par Oracle lors de ces opérations.
     SQL> create table zzvalidate (id number) tablespace cross;
     SQL> insert into zzvalidate values (1);
     SQL> insert into zzvalidate select * from zzvalidate;
     ...
     SQL> /
     256 rows created.
     SQL> commit;

Et si je relance VALIDATE, on voit des messages d'erreur différents du précédent lorsque le tbs était offline, preuve que la corruption de blocs a bien été détectée : "RMAN-03009: failure of validate command", "ORA-01122: database file 21 failed verification check" et "ORA-27046: file size is not a multiple of logical block size". Visiblement les données insérées via la commande dd ont créé un bloc de données de taille anormale.
     RMAN> validate tablespace CROSS;
     Starting validate at 06-FEB-21
     using target database control file instead of recovery catalog
     allocated channel: ORA_DISK_1
     channel ORA_DISK_1: SID=269 device type=DISK
     channel ORA_DISK_1: starting validation of datafile
     channel ORA_DISK_1: specifying datafile(s) for validation
     RMAN-00571: ===========================================================
     RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
     RMAN-00571: ===========================================================
     RMAN-03009: failure of validate command on ORA_DISK_1 channel at 02/06/2021 08:12:00
     ORA-01122: database file 21 failed verification check
     ORA-01110: data file 21: '/u01/app/oracle/oradata/orcl12c/orcl/cross.dbf'
     ORA-01565: error in identifying file '/u01/app/oracle/oradata/orcl12c/orcl/cross.dbf'
     ORA-27046: file size is not a multiple of logical block size
     Additional information: 1

Tiens, il n'y a rien dans V$DATABASE_BLOCK_CORRUPTION... bizarre! bon, pas grave, l'objectif était de voir la sortie de la commande VALIDATE en cas de bloc corrompus.
     SQL> connect SYS@orcl as sysdba
     SQL> select * from v$database_block_corruption;
     no rows selected

DBVERIFY
Je lance l'utilitaire Oracle DBVERIFY (commande dbv) pour faire une double vérification. Zut, l'erreur n'est pas parlante.
     [oracle@vbgeneric ~]$ dbv FILE=/u01/app/oracle/oradata/orcl12c/orcl/cross.dbf FEEDBACK=100
     DBVERIFY: Release 12.2.0.1.0 - Production on Sun Feb 7 06:56:06 2021
     Copyright (c) 1982, 2017, Oracle and/or its affiliates. All rights reserved.
     DBV-00102: File I/O error on FILE (/u01/app/oracle/oradata/orcl12c/orcl/cross.dbf) during end read operation (-1)

Et si je lance DBVERIFY sur un tbs non corrompu? Ah, c'est mieux, là encore la sortie est intéressante, surtout la ligne "Total Pages Marked Corrupt".
     [oracle@vbgeneric ~]$ dbv FILE=/u01/app/oracle/oradata/orcl12c/orcl/users01.dbf FEEDBACK=100
     DBVERIFY - Verification starting : FILE = /u01/app/oracle/oradata/orcl12c/orcl/users01.dbf
     ................................................................................
     .................
     DBVERIFY - Verification complete
     Total Pages Examined : 9760
     Total Pages Processed (Data) : 6795
     Total Pages Failing (Data) : 0
     Total Pages Processed (Index): 324
     Total Pages Failing (Index): 0
     Total Pages Processed (Lob) : 401
     Total Pages Failing (Lob) : 0
     Total Pages Processed (Other): 920
     Total Pages Processed (Seg) : 0
     Total Pages Failing (Seg) : 0
     Total Pages Empty : 1320
     Total Pages Marked Corrupt : 0
     Total Pages Influx : 0
     Total Pages Encrypted : 0
     Highest block SCN : 2093534 (0.2093534)

Bon, j'ai l'impression que la corruption faite dans mon tbs pose pb à Oracle pour être détectée :-(

Publicité
Publicité
Commentaires
Blog d'un DBA sur le SGBD Oracle et SQL
Publicité
Archives
Blog d'un DBA sur le SGBD Oracle et SQL
  • Blog d'un administrateur de bases de données Oracle sur le SGBD Oracle et sur les langages SQL et PL/SQL. Mon objectif est de vous faire découvrir des subtilités de ce logiciel, des astuces, voir même des surprises :-)
  • Accueil du blog
  • Créer un blog avec CanalBlog
Visiteurs
Depuis la création 340 689
Publicité