L’erreur suivante a été détectée tardivement dans le fichier Alert.log. De ce fait, les sauvegardes ne sont plus disponibles (Plus d’un mois que l’erreur est présente !).
Extrait du fichier « alert.log »
ORA-01578: bloc de données ORACLE altéré (fichier # 3, bloc # 22223)
ORA-01110: fichier de données 3 : '/oradata/#####/data/sysaux01.dbf'
Un Database Verify s’impose !!!!
oracle/home/oracle$ dbv file='/oradata/XXXX/data/sysaux01.dbf' BLOCKSIZE=16384
DBVERIFY: Release 10.2.0.3.0 - Production on Ven. Oct. 16 10:53:21 2009
Copyright (c) 1982, 2005, Oracle. All rights reserved.
DBVERIFY - Début de vérification : FILE = /oradata/XXXX/data/sysaux01.dbf
La page 22223 est remplie - le support est probablement endommagé
Corrupt block relative dba: 0x00c056cf (file 3, block 22223)
Fractured block found during dbv:
Data in bad block:
type: 6 format: 2 rdba: 0x00c056cf
last change scn: 0x0000.03c01ee3 seq: 0x1 flg: 0x06
spare1: 0x0 spare2: 0x0 spare3: 0x0
consistency value in tail: 0xe9390601
check value in block header: 0x3994
computed block checksum: 0xf6da
DBVERIFY - Vérification terminée
Nbre de pages examinées : 48640
Nbre de pages traitées (Données) : 12541
Nbre de pages en échec (Données) : 0
Nbre de pages traitées (Index) : 12060
Nbre de pages en échec (Index) : 0
Nbre de pages traitées (Autre) : 13414
Nbre de pages traitées (Seg) : 0
Nbre de pages en échec (Seg) : 0
Nbre de pages vides : 10624
Nbre de pages marquées altérées : 1
Nbre de pages Influx : 1
SCN de bloc le plus élevé : 64172645 (0.64172645)
On peut voir qu’il y a effectivement des données corrompues dans le fichier « sysaux » et donc dans le tablespace SYSAUX. Il faut maintenant identifier quel objet a été altéré par cette corruption.
Création de la table REPAIR_TABLE. Qui va permettrait de stocker les informations sur le ou les objets corrompus.
BEGIN
DBMS_REPAIR.ADMIN_TABLES (
TABLE_NAME => 'REPAIR_TABLE',
TABLE_TYPE => dbms_repair.repair_table,
ACTION => dbms_repair.create_action,
TABLESPACE => 'SYSAUX');
END;
/
Le fichier « Alert.log » nous indique l’endroit de la corruption (fichier # 3, bloc # 22223), trouvons maintenant l’objet corrompu :
SELECT segment_name , segment_type , owner , tablespace_name FROM sys.dba_extents WHERE file_id = 3 AND 22223 BETWEEN block_id and block_id + blocks -1;
SEGMENT_NAME SEGMENT_TYPE OWNER TABLESPACE_NAME
-------------- ----------- ------- ---------------------------
WRH$_SQL_PLAN TABLE SYS SYSAUX
Une fois l’objet identifié, nous allons voir s’il n’y a pas d’autres blocks corrompus sur cet objet :
SET SERVEROUTPUT ON
DECLARE num_corrupt INT;
BEGIN
num_corrupt := 0;
DBMS_REPAIR.CHECK_OBJECT (
SCHEMA_NAME => 'SYS',
OBJECT_NAME => 'WRH$_SQL_PLAN',
REPAIR_TABLE_NAME => 'REPAIR_TABLE',
CORRUPT_COUNT => num_corrupt);
DBMS_OUTPUT.PUT_LINE('number corrupt: ' || TO_CHAR (num_corrupt));
END;
/
select * from REPAIR_TABLE;
OBJECT_ID TABLESPACE_ID RELATIVE_FILE_ID BLOCK_ID
---------- ------------- ---------------- ----------
8964 2 3 22223
CORRUPT_TYPE SCHEMA_NAME OBJECT_NAME BASEOBJECT_NAME
------------ ------------ ------------ ----------------
6148 SYS WRH$_SQL_PLAN
PARTITION_NAME CORRUPT_DESCRIPTION REPAIR_DESCRIPTION
--------------- --------------------------- ------------------
mark block software corrupt
MARKED_COR CHECK_TI FIX_TIME REFORMAT
---------- -------- -------- --------
TRUE 16/10/09
Résolution
L’une des méthodes pour résoudre ce problème (sur une table bien spécifique) est d’utiliser le truncate sur la table WRH$_SQL_PLAN!!
Pour cela nous allons d’abord sauvegarder les données contenues dans la table… Du moins celle que nous pouvons car certaines sont corrompues !
Création de la table temporaire avec toutes les lignes avant la corruption :
SQL> create table sys.wrh$_sql_plan_slvg as select * from sys.wrh$_sql_plan w where rowid <>
On insère ensuite le reste des lignes (sauf la ligne corrompue !) :
SQL> insert into sys.wrh$_sql_plan_slvg select * from sys.wrh$_sql_plan w where rowid > dbms_rowid.rowid_create(1, 8964, 3, 22224, 0);
SQL> commit;
On désactive les contraintes associées à la table WRH$_SQL_PLAN.
SQL> select owner, table_name, constraint_name, constraint_type from dba_constraints where index_name='WRH$_SQL_PLAN_PK';
OWNER TABLE_NAME CONSTRAINT_NAME C
------ ---------- ------------------ -
SYS WRH$_SQL_PLAN WRH$_SQL_PLAN_PK P
SQL> alter table wrh$_sql_plan disable constraint WRH$_SQL_PLAN_PK;
SQL> select owner, table_name, constraint_name, constraint_type from dba_constraints where index_name='WRH$_SQL_PLAN_PK';
Aucune ligne selectionnee
On peut faire un truncate de la table :
SQL> truncate table WRH$_SQL_PLAN;
On réactive la contrainte :
SQL> alter table wrh$_sql_plan enable constraint WRH$_SQL_PLAN_PK;
SQL> insert into WRH$_SQL_PLAN select * from wrh$_sql_plan_slvg;
SQL> commit;
Enfin, on analyse la table ce qui permettra de valider la correction :
SQL> analyze table wrh$_sql_plan validate structure cascade;
La procédure se déroule bien cependant la sauvegarde RMAN plante toujours et le DB verify indique une erreur !!
Le bloc OS doit être corrompu !!! Il faut alors rebooter le serveur pour faire un FSCK pour réparer le bloc!!
Après le FSCK :
oracle/home/oracle$ dbv file='/oradata/XXXX/data/sysaux01.dbf' BLOCKSIZE=16384
DBVERIFY: Release 10.2.0.3.0 - Production on Lun. Nov. 9 10:16:06 2009
Copyright (c) 1982, 2005, Oracle. All rights reserved.
DBVERIFY - Début de vérification : FILE = /oradata/XXXX/data/sysaux01.dbf
DBVERIFY - Vérification terminée
Nbre de pages examinées : 48640
Nbre de pages traitées (Données) : 12632
Nbre de pages en échec (Données) : 0
Nbre de pages traitées (Index) : 12163
Nbre de pages en échec (Index) : 0
Nbre de pages traitées (Autre) : 13325
Nbre de pages traitées (Seg) : 0
Nbre de pages en échec (Seg) : 0
Nbre de pages vides : 10520
Nbre de pages marquées altérées : 0
Nbre de pages Influx : 0
SCN de bloc le plus élevé : 65320415 (0.65320415)
La corruption est réparée, certes avec perte de données, mais cela permet de repartir sur une base stable.
Julien
Aucun commentaire:
Enregistrer un commentaire