BBED (Block Browser Editor) en version 12c

BBED (Block Browser Editor) est un outil non documenté d’Oracle qui permet de modifier des données dans les datafiles d’une base de données Oracle. Il est non documenté et n’est plus fourni avec les versions 11g et 12c.

Cet article poursuit trois buts :
– Tester la possibilité d’utiliser encore l’outil Block Browser Editor en version 12c.
– Faire découvrir l’outil de modification de block BBED non supporté et non documenté par Oracle.
– le troisième est la raison pour laquelle j’ai recherché et découvert cet outil en parcourant internet : obtenir le moyen d’ouvrir inconditionnellement une base de données Oracle lorsque les SCN présents dans les headers des fichiers ne sont pas identiques et l’on ne possède pas de backup permettant de régulariser le problème.

Documentation

Le lien suivant permet d’obtenir la documentation la plus détaillée, même si elle date un peu (beaucoup ?). Je me suis appuyé sur le chapitre « Exemple #4 – file header reset » qui est toujours d’actualité, les offsets de l’exemple ont changé mais sont obtenus par les commandes de l’outil.
http://orafaq.com/papers/dissassembling_the_data_block.pdf
Exemple proposé
Je vous propose l’utilisation de cet outil sur un exemple qui est la modification du header d’un datafile faisant partie d’une sauvegarde plus ancienne afin de pouvoir ouvrir la base de données inconditionnellement. Le but étant de pouvoir récupérer les données se trouvant dans celui-ci. Cela nécessite bien sur que le dictionnaire de données contienne les définitions des segments se trouvant à l’intérieur du fichier incriminé.
Les manipulations décrites ci-dessous sont effectuées sur une base de données Oracle en version enterprise 12c sur un système d’exploitation linux 64bits.
Il ne s’agit que d’un exemple à effectuer sur une base de test, il est fortement déconseillé de l’utiliser sur une base de données de production.

1) Recréer l’outil en version 12c

Hélas l’outil n’est plus fourni dans la version 12c, qu’à cela ne tienne, nous allons récupérer les fichiers de librairies et  de messages adéquats à partir d’une version 10.2  afin d’arriver à nos fin. Les fichiers à récupérer sont les suivants : sbbdpt.o, ssbbded.o, bbedus.msb
sbbdpt.o et ssbbded.o sont copiés dans $ORACLE_HOME/rdbms/lib, bbedus.msb est copié dans $ORACLE_HOME/rdbms/mesg
Pour obtenir l’outil, il faut lancer la commande :

make -f ins_rdbms.mk $ORACLE_HOME/rdbms/lib/bbed

on retrouve ensuite l’utilitaire bbed dans $ORACLE_HOME/rdbms/lib
au lancement, il demande un mot de passe qui est : BLOCKEDIT

$ ./bbed
Password:
BBED: Release 2.0.0.0.0 - Limited Production on Tue Dec 31 07:31:15 2013
Copyright (c) 1982, 2013, Oracle and/or its affiliates.  All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
BBED>

2) Base de donnée arrêtée, sauvegarder le fichier cobaye

afin de simuler un fichier provenant d’une sauvegarde ancienne.

cp o1_mf_users_9d51xz0t_.dbf o1_mf_users_9d51xz0t_.dbf.old

 

3) Ouverture de la base de données et création d’un checkpoint pour décaler celui de notre fichier cobaye

 

SQL> select file#,checkpoint_change#
 from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
 ---------- ------------------
 1          1736898
 3          1736898
 4          1736898
 6          1736898
alter system checkpoint;
SQL> select file#,checkpoint_change#
 from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
 ---------- ------------------
 1          1737733
 3          1737733
 4          1737733
 6          1737733

 

4) Arrêt de la base de données, copie de l’ancienne version du fichier cobaye pour obtenir une base de données incohérente, test de la base de données

 

SQL> shutdown immediate
cp o1_mf_users_9d51xz0t_.dbf.old o1_mf_users_9d51xz0t_.dbf
SQL> startup
 ORACLE instance started.
Total System Global Area  534462464 bytes
 Fixed Size            2290416 bytes
 Variable Size          457182480 bytes
 Database Buffers       71303168 bytes
 Redo Buffers            3686400 bytes
 Database mounted.
 ORA-01113: le fichier 6 necessite une restauration physique
 ORA-01110: fichier de donnees 6 :
 '/u01/oradata/v12/datafile/o1_mf_users_9d51xz0t_.dbf'
SQL> select file#,change# from v$recover_file;
FILE#    CHANGE#
 ---------- ----------
 6    1736895
SQL> shutdown immediate

 

5) Utilisation de BBED pour modifier le fichier cobaye

5.1) récupération du SCN et horodatage du checkpoint sur un fichier sain (system)

 

BBED> set filename '/u01/oradata/v12/datafile/o1_mf_system_9d51rr13_.dbf'
BBED> p kcvfhckp
 struct kcvfhckp, 36 bytes          @484
 struct kcvcpscn, 8 bytes           @484
 ub4 kscnbas                        @484      0x001a86bc <== SCN soit 1738428
 ub2 kscnwrp                        @488      0x0000
 ub4 kcvcptim                       @492      0x31ce01c4 <== horodatage
 ub2 kcvcpthr                       @496      0x0001
 union u, 12 bytes                  @500
 struct kcvcprba, 12 bytes          @500
 ub4 kcrbaseq                       @500      0x00000001
 ub4 kcrbabno                       @504      0x00000bfe
 ub2 kcrbabof                       @508      0x0010
 ub1 kcvcpetb[0]                          @512      0x02
 ub1 kcvcpetb[1]                          @513      0x00
 ub1 kcvcpetb[2]                          @514      0x00
 ub1 kcvcpetb[3]                          @515      0x00
 ub1 kcvcpetb[4]                          @516      0x00
 ub1 kcvcpetb[5]                          @517      0x00
 ub1 kcvcpetb[6]                          @518      0x00
 ub1 kcvcpetb[7]                          @519      0x00

5.2) récupération d’autres structures nécessaires sur un fichier sain (system)

checkpoint count

BBED> p kcvfhcpc
 ub4 kcvfhcpc                                @140      0x000000b9

 
ckeckpoint count moins 1

BBED>  p kcvfhccc
 ub4 kcvfhccc                                @148      0x000000b8

 

5.3) Contrôle des même structures sur le fichier cobaye

BBED> set filename '/u01/oradata/v12/datafile/o1_mf_users_9d51xz0t_.dbf'
 FILENAME           /u01/oradata/v12/datafile/o1_mf_users_9d51xz0t_.dbf
BBED> p kcvfhckp
 struct kcvfhckp, 36 bytes          @484
 struct kcvcpscn, 8 bytes           @484
 ub4 kscnbas                        @484      0x001a80bf  <== SCN soit 1736895
 ub2 kscnwrp                        @488      0x0000
 ub4 kcvcptim                       @492      0x31ce002f <== horodatage
 ub2 kcvcpthr                       @496      0x0001
 union u, 12 bytes                  @500
 struct kcvcprba, 12 bytes          @500
 ub4 kcrbaseq                       @500      0x00000001
 ub4 kcrbabno                       @504      0x00000636
 ub2 kcrbabof                       @508      0x0010
 ub1 kcvcpetb[0]                          @512      0x02
 ub1 kcvcpetb[1]                          @513      0x00
 ub1 kcvcpetb[2]                          @514      0x00
 ub1 kcvcpetb[3]                          @515      0x00
 ub1 kcvcpetb[4]                          @516      0x00
 ub1 kcvcpetb[5]                          @517      0x00
 ub1 kcvcpetb[6]                          @518      0x00
 ub1 kcvcpetb[7]                          @519      0x00
BBED> p kcvfhcpc
 ub4 kcvfhcpc                                @140      0x000000b4
BBED> p kcvfhccc
 ub4 kcvfhccc                                @148      0x000000b3

 

5.4) Modification du header du fichier cobaye à partir des informations prélevées dans le fichier sain

 
La commande lisfile est obligatoire sinon cela ne fonctionne pas. Je positionne un fichier bidon. Cette commande permet éventuellement de charger la liste de fichiers potentiellement à éditer ou modifier sous la forme :
incrément# nom_fichier_absolu
incrément# devient le numéro de fichier qui sera utilisée dans les commande du type : dba incrément#,block, il ne correspond pas au réel numéro de fichier dans la base.
J’utilise plutôt la commande set filename qui récupère le numéro de fichier dans le header de celui-ci.

BBED> set listfile '/u01/oradata/v12/datafile/file.log'

 

BBED> set mode edit

 
!!!! Nous sommes sur linux Intel, donc valeurs stockées en  « little endian » d’où les valeurs entrées ci-dessous !!!!
Modification du SCN dans le fichier numéro 6, qui est notre fichier cobaye

BBED> modify /x bc861a dba 6,1 offset 484

Pour la modification de l’horodatage, (offset 492), j’obtiens une erreur. Pour contourner le problème, je modifie mot par mot :

BBED> modify /x c401ce31 dba 6,1 offset 492
 BBED-00209: invalid number (c401ce31)
BBED> modify /x c401 dba 6,1 offset 492
 File: /u01/oradata/v12/datafile/o1_mf_system_9d51rr13_.dbf (6)
 Block: 1                Offsets:  492 to  507           Dba:0x01800001
 ------------------------------------------------------------------------
 c401ce31 01000000 01000000 fe0b0000
BBED> modify /x  ce31 dba 6,1 offset 494
 File: /u01/oradata/v12/datafile/o1_mf_system_9d51rr13_.dbf (6)
 Block: 1                Offsets:  494 to  509           Dba:0x01800001
 ------------------------------------------------------------------------
 ce310100 00000100 0000fe0b 00001000

 
Modification des autres structures :

BBED> modify /x 9 dba 6,1 offset 140
BBED> modify /x 8 dba 6,1 offset 148
BBED> sum dba 6,1 apply
 Check value for File 6, Block 1:
 current = 0xd685, required = 0xd685

 

6) Démarrage de la base de données et ouverture

Au démarrage j’obtiens une erreur ORA-01113 que je corrige simplement avec la commande « recover database ». Il ne reste plus qu’à ouvrir la base de données avec la commande « alter database open »

SQL> startup
 ORACLE instance started.
Total System Global Area  534462464 bytes
 Fixed Size            2290416 bytes
 Variable Size          457182480 bytes
 Database Buffers       71303168 bytes
 Redo Buffers            3686400 bytes
 Database mounted.
 ORA-01113: le fichier 1 necessite une restauration physique
 ORA-01110: fichier de donnees 1 :
 '/u01/oradata/v12/datafile/o1_mf_system_9d51rr13_.dbf'
SQL> recover database;
 Media recovery complete.
 SQL> alter database open;
Database altered.
SQL> select file#,checkpoint_change#
 from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
 ---------- ------------------
 1          1738431
 3          1738431
 4          1738431
 6          1738431