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