Le « Block Media Recovery » ou BMR est la possibilité de restaurer un bloc Oracle en cas de corruption. Jusqu’à Oracle 11g Database Release 1, seul Oracle Oracle Recovery Manager, RMAN, permet de restaurer simplement un bloc. Avec la version 11.2 de la base de données, lorsque vous utilisez Active Data Guard et que vous utilisez une standby database et Real Time Query, les corruptions de données sont corrigées automatiquement. Cette nouvelle fonctionnalité permet d’éviter les erreurs ORA-01578
de manière automatique et quasiment transparente. Cette article illustre cette fonctionnalité à travers une méthode simple pour corrompre, tour à tour, la base de données primaire et la standby.
Cet article est le troisième d’une série plus large que je vous invite à découvrir ci-dessous :
- Le 1er article, présente comment créer une configuration Data Guard en 5 minutes, en plus du temps de copie de la base de données et comment effectuer une transition des roles des bases de données
- Le 2nd article, présente comment changer le mode de protection, activer la compression, Snapshot Standby et Real Time Query
- Le 3ème article (celui-ci) illustre le fonctionnement de la correction automatique de blocs corrumpus sur la base de données primaire et standby
- Le 4ème article démontre comment garantir la fraicheur des données sur la standby
- Le 5ème article illustre l’utilisation du Block Change Tracking File sur la base standby et l’utilisation de la commande recover database noredo pour gérer la perte d’un fichier archivelog
Il s’agit d’un tour d’horizon assez complet de l’état de l’art de Data Guard en 11g Release 2. Bien sur, si vous avez d’autres idées, n’hésitez pas à les partager en laissant vos commentaires…
Préambule
Pour commencer, il faut configurer une standby physique en « real time query ». Pour cela, je vous renvoie au premier article et au second article de la série. Dans la configuration qui suit, BLACK
est la base de données primaire et WHITE
, la base de données standby en real time apply. J’ai effectué mes tests sur Linux x86.
dgmgrl sys/change_on_install@black show database white; Database - white Role: PHYSICAL STANDBY Intended State: APPLY-ON Transport Lag: 0 seconds Apply Lag: 0 seconds Real Time Query: ON Instance(s): WHITE Database Status: SUCCESS exit
Corruption d’un bloc sans une Standby « Real Time Query »
Pour commencer, vous pouvez désactiver la base de données standby « Real Time Query » pour visualiser ce qu’il se passe lorsque un bloc est corrompu sans Active Data Guard. Pour cela, connectez-vous à la standby avec le client du broker et démarrer la base standby en mode mount
:
dgmgrl sys/change_on_install@white shutdown abort ORACLE instance shut down. startup mount; ORACLE instance started. Database mounted. show database white; Database - white Role: PHYSICAL STANDBY Intended State: APPLY-ON Transport Lag: 0 seconds Apply Lag: 0 seconds Real Time Query: OFF Instance(s): WHITE Database Status: SUCCESS exit;
Pour la suite, nous allons répérer un bloc à corrompre. Pour cet exemple, nous allons utiliser la table exemple SCOTT.EMP
. Le package DBMS_ROWID
permet de repérer le bloc d’une ligne à partir de son rowid
:
sqlplus sys/change_on_install@black as sysdba set serveroutput on declare v_rowid_type number; v_object_number number; v_relative_fno number; v_block_number number; v_row_number number; begin for i in (select rowid, ename from scott.emp) loop dbms_rowid.ROWID_INFO( i.rowid, v_rowid_type, v_object_number, v_relative_fno, v_block_number, v_row_number); dbms_output.put_line( 'Employee: '||i.ename|| ' - block: '||to_char(v_block_number )); end loop; end; / Employee: SMITH - block: 151 Employee: ALLEN - block: 151 Employee: WARD - block: 151 Employee: JONES - block: 151 Employee: MARTIN - block: 151 Employee: BLAKE - block: 151 Employee: CLARK - block: 151 Employee: SCOTT - block: 151 Employee: KING - block: 151 Employee: TURNER - block: 151 Employee: ADAMS - block: 151 Employee: JAMES - block: 151 Employee: FORD - block: 151 Employee: MILLER - block: 151
Nous allons donc corrompre le bloc 151 de notre datafile. Pour cela, nous allons utiliser la commande dd qui est facile à utiliser lorsque vous n’utilisez pas Automatic Storage Manager (Avec ASM, il faut d’abord repérer la position des extents du datafiles dans le diskgroup). Après que vous ayez corrompu le bloc, Oracle vous retourne l’erreur ORA-01578
lorsque vous tentez d’y accéder :
select file_name from dba_data_files where tablespace_name='USERS'; FILE_NAME ----------------------------------------- /u01/app/oracle/oradata/BLACK/users01.dbf ! ls -l /u01/app/oracle/oradata/BLACK/users01.dbf ! dd if=/dev/zero - of=/u01/app/oracle/oradata/BLACK/users01.dbf - bs=8k count=1 seek=151 conv=notrunc alter system flush buffer_cache; select * from scott.emp; * ERROR at line 1: ORA-01578: ORACLE data block corrupted (file # 4, block # 151) ORA-01110: data file 4: '/u01/app/oracle/oradata/BLACK/users01.dbf' exit;
Note
le paramètreconv=notrunc
de la commandedd
permet de ne pas tronquer le fichier après le bloc que vous modifiez, ce qui est le comportement par défaut.
Corriger un bloc corrompu avec la base de données Standby « Real Time Query »
Pour corriger le bloc corrompu, vous pouvez bien entendu utiliser Recovery Manager; Au lieu de celà, nous allons simplement activer la standby en mode « Real Time Query » :
dgmgrl sys/manager@white show database white; Database - white Role: PHYSICAL STANDBY Intended State: APPLY-ON Transport Lag: 0 seconds Apply Lag: 0 seconds Real Time Query: OFF Instance(s): WHITE Database Status: SUCCESS shutdown immediate; ORA-01109: database not open Database dismounted. ORACLE instance shut down. startup ORACLE instance started. Database mounted. Database opened. show database white; Database - white Role: PHYSICAL STANDBY Intended State: APPLY-ON Transport Lag: 0 seconds Apply Lag: 0 seconds Real Time Query: ON Instance(s): WHITE Database Status: SUCCESS exit;
Maintenant, il suffit d’accéder au bloc corrompu sur la base de données primaire pour corriger l’erreur :
sqlplus sys/change_on_install@black as sysdba set pages 1000 select empno, ename from scott.emp; EMPNO ENAME ----- ------- 7369 SMITH 7499 ALLEN 7521 WARD 7566 JONES 7654 MARTIN 7698 BLAKE 7782 CLARK 7788 SCOTT 7839 KING 7844 TURNER 7876 ADAMS 7900 JAMES 7902 FORD 7934 MILLER
L’erreur est corrigée, comme par magie. Pour comprendre ce qui s’est passé, allez voir le fichier alert.log et vous y découvrirez un message indiquant que la correction automatique du bloc a été déclenchée. Voici le-dit extrait sur ma base de données :
Sun Oct 04 13:27:13 2009 Hex dump of (file 4, block 151) in trace file /u01/app/oracle/diag/rdbms/black/BLACK/trace/BLACK_ora_15682.trc Corrupt block relative dba: 0x01000097 (file 4, block 151) Completely zero block found during buffer read Reading datafile '/u01/app/oracle/oradata/BLACK/users01.dbf' for corruption at rdba: 0x01000097 (file 4, block 151) Reread (file 4, block 151) found same corrupt data Starting background process ABMR Sun Oct 04 13:27:13 2009 ABMR started with pid=37, OS id=15692 Auto BMR service is active. Requesting Auto BMR for (file# 4, block# 151) Waiting Auto BMR response for (file# 4, block# 151) Auto BMR successful
Quel est l’impact de la correction automatique de la corruption ?
Re-faîtes le même test, cette fois-ci en ayant déjà la base de données en mode « Real Time Query »
- Sans corruption de données
sqlplus / as sysdba alter system flush buffer_cache; set timing on select empno, ename from scott.emp; [...] Elapsed: 00:00:00.01
- Avec corruption de données
sqlplus / as sysdba ! dd if=/dev/zero - of=/u01/app/oracle/oradata/BLACK/users01.dbf - bs=8k count=1 seek=151 conv=notrunc alter system flush buffer_cache; set timing on select empno, ename from scott.emp; [...] Elapsed: 00:00:00.48
Vous pouvez encore vérifier dans le fichier alert.log que la gestion automatique du « Block Media Recovery » a été déclenchée. Vous constaterez que si l’impact n’est pas transparent, il est relativement négligeable; bien sur, ce temps dépend du lag de la standby.
Corruption de la base de données Standby
La gestion automatique de la corruption de bloc est également disponible sur la standby. Pour vous en persuader, vous pouvez effectuer le même test depuis la base standby en mode « Real Time Query ». Remarquez que dans ce cas, voulu(*) ou pas une erreur est renvoyée à l’utilisateur :
sqlplus sys/change_on_install@white as sysdba alter system flush buffer_cache; ! dd if=/dev/zero - of=/u01/app/oracle/oradata/WHITE/users01.dbf - bs=8k count=1 seek=151 conv=notrunc select empno, ename from scott.emp; * ERROR at line 2: ORA-01578: ORACLE data block corrupted (file # 4, block # 151) ORA-01110: data file 4: '/u01/app/oracle/oradata/WHITE/users01.dbf'
Si vous ré-exécutez la requête, le bloc est corrigé :
select empno, ename from scott.emp; EMPNO ENAME ----- -------- 7369 SMITH 7499 ALLEN 7521 WARD 7566 JONES 7654 MARTIN 7698 BLAKE 7782 CLARK 7788 SCOTT 7839 KING 7844 TURNER 7876 ADAMS 7900 JAMES 7902 FORD 7934 MILLER
Le fichier alert.log montre que la corruption est détectée :
Hex dump of (file 4, block 151) in trace file /u01/app/oracle/diag/rdbms/white/WHITE/trace/WHITE_ora_17556.trc Corrupt block relative dba: 0x01000097 (file 4, block 151) Completely zero block found during multiblock buffer read Reading datafile '/u01/app/oracle/oradata/WHITE/users01.dbf' for corruption at rdba: 0x01000097 (file 4, block 151) Reread (file 4, block 151) found same corrupt data Errors in file /u01/app/oracle/diag/rdbms/white/WHITE/trace/WHITE_ora_17556.trc (incident=97362): ORA-01578: ORACLE data block corrupted (file # 4, block # 151) ORA-01110: data file 4: '/u01/app/oracle/oradata/WHITE/users01.dbf' Incident details in: /u01/app/oracle/diag/rdbms/white/WHITE/incident/incdir_97362/WHITE_ora_17556_i97362.trc Sun Oct 04 14:03:07 2009 Sweep [inc][97362]: completed Sun Oct 04 14:03:08 2009 Trace dumping is performing id=[cdmp_20091004140308] Sun Oct 04 14:03:09 2009 Sweep [inc2][97362]: completed
Conclusion
Ces changements, à priori mineurs, à la lumière de ces tests, non seulement fonctionnent mais apportent un vrai plus à l’infrastructure Active Data Guard. Et ce n’est qu’un début puisque dans le prochain article, nous testerons la possibilité offerte par la standby « Real Time Query » de garantir la fraicheur des données interrogée sur la base secondaire. J’espère pouvoir vous faire partager notre enthousiasme pour ces nouvelles fonctionnalités. Qu’en pensez-vous ?
(*) La base de données standby a un SCN plus petit, même très proche, que le SCN de la base de données primaire; il est possible que la requête doivent être arrêtée parce que la standby ne peut pas garantir que le bloc remonté ne contient pas des données modifiées depuis. Ceci dépend de la manière dont le bloc est accédé et il se peut que ce soit une limite de l’implémentation actuelle (malgré la présence des UNDO). Il faudrait activer les traces sur la primaire et démonter le mécanisme pour en savoir plus. Y a-t-il un curieux/courageux pour comprendre ce qu’il se passe plus en détail ?
13 réflexions sur “Oracle 11g Release 2 Data Guard (3/5) : Automatic Block Media Recovery”
Ping : Active Data Guard 11g Release 2 (5/5) : BCTF et RECOVER NOREDO sur la Standby | EASYTEAM
Ping : Active Data Guard 11g Release 2 (5/5) : BCTF et RECOVER NOREDO sur la Standby | EASYTEAM LE BLOG
Ping : Oracle Database 11g Release 2 Data Guard (7/5): Observer et Fast Start Failover « EASYTEAM LE BLOG
Ping : Oracle Database 11g Release 2 Data Guard (6/5): Créer une standby logique avec le broker « EASYTEAM LE BLOG
D’après ce qui est dit dans la documentation, meme sans accéder au bloc, la correction doit pouvoir se faire au moment de l’application des logs.
Effectivement; sur la standby. Je n’ai pas testé ce scénario mais si un bloc est corrompu puis modifié… La correction pourrait être automatique. Je vais vérifier
Pour continuer la discussion précédente, j’ai fait le test avec RMAN. Dans ce cas :
1) le bloc corrompu est détecté
2) Il n’est pas automatiquement corrigé.
3) Advise Failure indique de passer la commande « recover datafile 4 block 151; »
4) La dite commande utilise la standby (je n’ai pas de backup ni de datafilecopy pour aller au bout
5) après ça, le backup passe
Après avoir corrumpu le bloc, voici la sortie de mes commandes RMAN:
J’ai mis en gras la ligne intéressante; C’est dommage, le fichier alert.log ne dit pas comment le BMR c’est fait:
Comme on peut s’y attendre le résultat est le même pour la commande VALIDATE.
Comme quoi, RMAN ça en jette!
Pour que RMAN puisse tirer parti de la base de données standby, il faut que celle ci soit en mode Real Time Query; Si la base de données n’est qu’en recover, il faudra fair un BMR à partir d’une sauvegarde.
Chaque bloc en plus d’avoir une structure définie contient des checksums. C’est d’ailleurs comme ça que la corruption est détectée. C’est aussi pour ça que créer un datafile prend du temps; et que Exadata va beaucoup plus vite pour créer des grosses bases de données, même vide comparé à une base Oracle sans Exadata Cell Storage Server;
La corruption est détectée lorsque le bloc est monté en mémoire, en effet.
Ta question est très intéressante, parce qu’elle en amène un autre à laquelle je ne sais pas répondre:
Réponse 1 (simple) : Si le bloc n’est jamais accédé, il n’est jamais corrigé mais cela n’a pas d’impact puisqu’il n’est jamais accédé : Quoique en janvier l’année prochaine ou lors d’un archivage dans 3 ans !
Réponse 2 (plus compliquée) : Tu accèdes aux blocs pour faire tes sauvegardes, ou les valider; c’est d’ailleurs une des raisons pour lesquelles il vaut mieux utiliser RMAN ou valider les blocs régulièrement. Mais dans ce cas, je ne sais pas si les corruptions sont corrigées
C’était un peu le sens de ma question, car dans ton test tu accèdes au bloc juste après l’avoir pourri, mais imagine que c’est 6 mois après ?
En faisant des sauvegardes avec RMAN, ou en validant les datafiles de manière régulière, on peut éviter de découvrir une corruption 6 mois après. Cela dit, la question reste ouverte, à savoir si Active Data Guard résoud, dans ce cas également le problème de corruption. Je testerai.
Génial cet article !
la détection du bloc corrompu par le noyau se fait comment ? c’est au moment ou tu le lis qu’il le détecte ? Que se passe-t-il si personne ne lit ce bloc, dans ce cas ?
Les commentaires sont fermés.