mardi 17 novembre 2009

Récupération après corruption de la table WRH$_SQL_PLAN sans sauvegarde.

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;


Puis, on insére les lignes de la table

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