Oracle 11g offre, parmi les nouvelles fonctionnalités RMAN, un outil simple pour corriger un problème lié à une corruption de votre base de données; Data Recovery Advisor, c’est son nom, vous proposera, en fonction des situations, un plan pour vous sortir d’un mauvais pas, sans ouvrir le manuel. Dans ce post, vous trouverez une exemple de corruption volontaire d’un bloc de données grâce à la commande dd
. Évidemment, vous verrez également comment Data Recovery Advisor vous vient en aide dans un pareil cas !
1. Un exemple de corruption
Pour commencer, simulons la corruption d’un bloc de données. Pour limiter l’impact d’une mauvaise manipulation, créez un tablespace séparé que vous pourrez effacer à la fin de la démonstration:
create tablespace t
datafile '/u01/app/oracle/oradata/BLACK/t.dbf'
size 128M;
Ensuite créez une table X, un index et insérez quelques données:
create table X(textfield varchar2(4000))
tablespace t;
create index X_IDX on X(textfield)
tablespace t;
begin
for i in 1..1000 loop
insert into x(textfield)
values (lpad('X',1000,'X'));
end loop;
end;
/
commit;
Pour que vous puissiez corriger la corruption, il faut que votre base de données soit en mode ARCHIVELOG; Si vous voulez pouvoir faire un Block Media Recovery, effectuez une sauvegarde du nouveau fichier; sinon vous devrez faire un recover de l’ensemble du fichier:
set lines 120
col name format a80
set pages 1000
select file#, name from v$datafile
order by name;
FILE# NAME
----- -------------------------------------------
2 /u01/app/oracle/oradata/BLACK/sysaux01.dbf
1 /u01/app/oracle/oradata/BLACK/system01.dbf
5 /u01/app/oracle/oradata/BLACK/t.dbf
3 /u01/app/oracle/oradata/BLACK/undotbs01.dbf
4 /u01/app/oracle/oradata/BLACK/users01.dbf
exit;
rman target /
backup datafile 5;
exit;
Vous voilà prêt à corrompre vos données; Listez les blocs de la table:
select FILE_ID,BLOCK_ID,BYTES
from dba_extents
where owner=user
and SEGMENT_NAME='X';
FILE_ID BLOCK_ID BYTES
---------- ---------- ----------
5 128 65536
5 152 65536
5 176 65536
5 192 65536
5 208 65536
...
Videz le buffer cache afin de les relire depuis le disque au prochain accès. En effet, vous allez corrompre les données sur le disque et pas en mémoire :
alter system flush buffer_cache;
Enfin lancez la commande dd comme ci-dessous pour corrompre un des blocs; pour en savoir plus sur les options utilisées, tapez man dd
:
dd if=/dev/zero
of=/u01/app/oracle/oradata/BLACK/t.dbf
obs=8k count=1 seek=177 conv=notrunc
Remarques:
- Notre tablespace a des blocs de 8k; d’ou la valeur de
obs
- Pour effacer un bloc de données et pas les structures d’allocation des données, nous avons évite le premier extend et les premiers blocs des extends (Nous effaçons le bloc 177 dans notre exemple).
Vous pouvez vous assurez de la corruption:
select /*+ full */ count(textfield) from x;
select /*+ full */ count(textfield) from x
*
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 5, block # 177)
ORA-01110: data file 5: '/u01/app/oracle/oradata/BLACK/t.dbf'
Si le block corrompu n’apparaît pas dans v$database_block_corruption
, utilisez la commande RMAN validate
comme ci-dessous:
rman target /
validate datafile 5;
exit;
Notez que dans cette simulation, tout n’est pas encore perdu:
select /*+ index(x X_idx) */ count(textfield) from x;
COUNT(TEXTFIELD)
----------------
1000
2. Utiliser Data Recovery Advisor
Pour utiliser Data Recovery Advisor, connectez vous avec RMAN et lancer successivement les commandes ci-dessous dans la même session:
LIST FAILURE
(ouLIST FAILURE ALL)
pour lister les problèmes détectés par RMANADVISE FAILURE
pour proposer les corrections possibles pour les erreurs listees précedemmentREPAIR FAILURE PREVIEW
pour visualer la commande RMAN qui sera utilisée implementer le conseil proposé parADVISE FAILURE
REPAIR FAILURE
pour exécuter la commande RMAN qui sera implementr le conseil proposé parADVISE FAILURE
Vous trouverez ci-dessous un exemple de session utilisant Data Recovery Advisor:
rman target /
Recovery Manager: Release 11.1.0.7.0 - Production on Sat Dec 20 11:57:52 2008
Copyright (c) 1982, 2007, Oracle. All rights reserved.
connected to target database: BLACK (DBID=350304923)
RMAN> LIST FAILURE;
using target database control file instead of recovery catalog
List of Database Failures
=========================
Failure ID Priority Status Time Detected Summary
---------- -------- --------- ------------- -------
2901 HIGH OPEN 20-DEC-08 Datafile 5: '/u01/app/oracle/oradata/BLACK/t.dbf' contains one or more corrupt blocks
RMAN> ADVISE FAILURE;
List of Database Failures
=========================
Failure ID Priority Status Time Detected Summary
---------- -------- --------- ------------- -------
2901 HIGH OPEN 20-DEC-08 Datafile 5: '/u01/app/oracle/oradata/BLACK/t.dbf' contains one or more corrupt blocks
analyzing automatic repair options; this may take some time
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=133 device type=DISK
analyzing automatic repair options complete
Mandatory Manual Actions
========================
no manual actions available
Optional Manual Actions
=======================
1. If a standby database is available, then consider a Data Guard switchover or failover
Automated Repair Options
========================
Option Repair Description
------ ------------------
1 Perform block media recovery of block 177 in file 5
Strategy: The repair includes complete media recovery with no data loss
Repair script: /u01/app/oracle/diag/rdbms/black/BLACK/hm/reco_794160253.hm
RMAN> REPAIR FAILURE PREVIEW;
Strategy: The repair includes complete media recovery with no data loss
Repair script: /u01/app/oracle/diag/rdbms/black/BLACK/hm/reco_794160253.hm
contents of repair script:
# block media recovery
recover datafile 5 block 177;
RMAN> REPAIR FAILURE;
Strategy: The repair includes complete media recovery with no data loss
Repair script: /u01/app/oracle/diag/rdbms/black/BLACK/hm/reco_794160253.hm
contents of repair script:
# block media recovery
recover datafile 5 block 177;
Do you really want to execute the above repair (enter YES or NO)? YES
executing repair script
Starting recover at 20-DEC-08
using channel ORA_DISK_1
channel ORA_DISK_1: restoring block(s)
channel ORA_DISK_1: specifying block(s) to restore from backup set
restoring blocks of datafile 00005
channel ORA_DISK_1: reading from backup piece /u01/app/oracle/backup/BLACK/58k2nmtq_1_1
channel ORA_DISK_1: piece handle=/u01/app/oracl e/backup/BLACK/58k2nmtq_1_1 tag=TAG20081220T115538
channel ORA_DISK_1: restored block(s) from backup piece 1
channel ORA_DISK_1: block restore complete, elapsed time: 00:00:01
starting media recovery
media recovery complete, elapsed time: 00:00:03
Finished recover at 20-DEC-08
repair failure complete
RMAN> exit;
3. Data Recovery Advisor… NOARCHIVELOG
Si « par hasard », vous ne pouviez pas restaurer vos données Data Recover Advisor vous offre un support psychologique 😉 :
RMAN> list failure;
List of Database Failures
=========================
Failure ID Priority Status Time Detected Summary
---------- -------- --------- ------------- -------
2901 HIGH OPEN 20-DEC-08 Datafile 5: '/u01/app/oracle/oradata/BLACK/t.dbf' contains one or more corrupt blocks
RMAN> advise failure;
List of Database Failures
=========================
Failure ID Priority Status Time Detected Summary
---------- -------- --------- ------------- -------
2901 HIGH OPEN 20-DEC-08 Datafile 5: '/u01/app/oracle/oradata/BLACK/t.dbf' contains one or more corrupt blocks
analyzing automatic repair options; this may take some time
using channel ORA_DISK_1
analyzing automatic repair options complete
Mandatory Manual Actions
========================
1. No backup of block 177 in file 5 was found. Drop and re-create the associated object (if possible), or use the DBMS_REPAIR package to repair the block corruption
2. Contact Oracle Support Services if the preceding recommendations cannot be used, or if they do not fix the failures selected for repair
Optional Manual Actions
=======================
1. If a standby database is available, then consider a Data Guard switchover or failover
Automated Repair Options
========================
no automatic repair options available
exit;
Dans notre cas, parce que la table est corrompue mais toutes les données sont dans l’index, vous pouvez simplement créer une copie de la table à partir de l’index comme ci-dessous:
create table x_copy
as select /*+ index(x x_idx) */ *
from x
where textfield is not null;
4. Ignorer une erreur
Vous pouvez voiloir grder une structure corrompue; Si, par exemple, vous avez recréé la table avec DBMS_REPAIR ou un SELECT, vous pouvez indiquer au Data Recovery Advisor que l’erreur n’est pas importante. Pour cela utilisez CHANGE FAILURE
comme ci-dessous; L’erreur n’apparaitra plus avec LIST FAILURE
:
RMAN> list failure;
using target database control file instead of recovery catalog
List of Database Failures
=========================
Failure ID Priority Status Time Detected Summary
---------- -------- --------- ------------- -------
2901 HIGH OPEN 20-DEC-08 Datafile 5: '/u01/app/oracle/oradata/BLACK/t.dbf' contains one or more corrupt blocks
RMAN> change failure 2901 priority low;
List of Database Failures
=========================
Failure ID Priority Status Time Detected Summary
---------- -------- --------- ------------- -------
2901 HIGH OPEN 20-DEC-08 Datafile 5: '/u01/app/oracle/oradata/BLACK/t.dbf' contains one or more corrupt blocks
Do you really want to change the above failures (enter YES or NO)? YES
changed 1 failures to LOW priority
RMAN> list failure;
no failures found that match specification
RMAN> list failure all;
List of Database Failures
=========================
Failure ID Priority Status Time Detected Summary
---------- -------- --------- ------------- -------
2901 LOW OPEN 20-DEC-08 Datafile 5: '/u01/app/oracle/oradata/BLACK/t.dbf' contains one or more corrupt blocks
5. Supprimer l’exemple
Pour terminer, effacez les structures utilisées dans cet exemple:
drop tablespace t
including contents and datafiles;