being able to plug in an older version of a file
into the current instance could be a huge save
in terms of recovery. at one point in time, a
file has certain values related to its state,
and that state is consistent with other files in
the database. when the state is off, oracle
informs the dba about it right away via one or
more error messages, especially the one about a
file needing more media recovery. in a normal
recovery scenario where media loss has occurred,
the recovery consists of restoring a backed up
copy of one or more datafiles and then applying
archived redo to bring the file to a consistent
state.
in the bbed recovery scenario, one will not be
applying redo, but rather will be jumping the
state of the file from a point in the past to a
point in time consistent with the rest of the
database. the specific part of the file to be
edited is the file header. information will be
needed from three structs: kcvfhckp, kcvfhcpc,
and kcvfhccc. published elsewhere are decode
tables for many of these items, and these are
generally easy to interpret. kernel-related
codes begin with a k, fh looks like file header,
and the remainder are related to checkpoints.
specifically, good values from the following are
needed:
-
kscnbas – last change scn
-
kcvcptim – time of the last change
-
kcvfhcpc – checkpoint count
-
kcvfhccc – a checkpoint checker value, which
is one less than kcvfhcpc
for file headers, one is interested in the
output of the kcvfh struct. the output of “p
kcvfh” is long, but it is interesting to browse
through the output. it is also interesting how
the name of the database (orcl2 here) appears
spelled out.
bbed> p kcvfh
struct kcvfh, 676 bytes
@0
struct kcvfhbfh, 20 bytes
@0
ub1 type_kcbh
@0
0x0b
ub1 frmt_kcbh
@1
0xa2
ub1 spare1_kcbh
@2
0x00
ub1 spare2_kcbh
@3
0x00
ub4 rdba_kcbh
@4
0x01800001
ub4 bas_kcbh
@8
0x00000000
ub2 wrp_kcbh
@12
0x0000
ub1 seq_kcbh
@14
0x01
ub1 flg_kcbh
@15
0x04 (kcbhfckv)
ub2 chkval_kcbh
@16
0x8f50
ub2 spare3_kcbh
@18
0x0000
struct kcvfhhdr, 76 bytes
@20
ub4 kccfhswv
@20
0x00000000
ub4 kccfhcvn
@24
0x0a200100
ub4 kccfhdbi
@28
0x266ecc46
text kccfhdbn[0]
@32
o
text kccfhdbn[1]
@33
r
text kccfhdbn[2]
@34
c
text kccfhdbn[3]
@35
l
text kccfhdbn[4]
@36
2
here is the test case. a new tablespace (bb),
user (bb) and table (emp) where the table has
three rows and three columns from scott’s emp
table is created. the datafile is bb01.dbf,
created with a size of 100k. a backup exists
where the three rows are in place. the current
instance has had a deletion of all three rows
and the object is to restore the data by
recovering the older datafile. therefore, get a
new list of files for use within the parameter
file, and the copy of bb01.dbf will be the older
version. only two files are really needed – one
with a good scn state, and the older file, but
all were listed anyway.
1 /opt/app/oracle/oradata/orcl2/system01.dbf
513802240
2 /opt/app/oracle/oradata/orcl2/undotbs01.dbf
36700160
3 /opt/app/oracle/oradata/orcl2/sysaux01.dbf
272629760
4 /opt/app/oracle/oradata/orcl2/users01.dbf
5242880
5 /opt/app/oracle/oradata/orcl2/example01.dbf
104857600
6 /opt/app/oracle/oradata/orcl2/bb01.dbf
106496
replace the file and issue a startup command.
one should see the error related to the “bad”
file.
sql> conn / as sysdba
connected to an idle
instance.
sql> startup
oracle instance started.
total system global area
922746880 bytes
fixed size
1222624 bytes
variable size
281020448 bytes
database buffers
633339904 bytes
redo buffers
7163904 bytes
database mounted.
ora-01113: file 6 needs
media recovery
ora-01110: data file 6:
'/opt/app/oracle/oradata/orcl2/bb01.dbf'
the current checkpoint number is not necessarily
needed, but since it can be pulled directly from
the database, see what it is. it will also show
up in the file itself courtesy of bbed. the
current scn is at 689110 and the bad file is at
685758.
sql> select distinct
checkpoint_change# from v$datafile;
checkpoint_change#
------------------
689110
sql> select change# from
v$recover_file;
change#
----------
685758
start a bbed session and print the kcvfhckp
struct. the first few lines are shown and the
values of interest are the scn and last time.
bbed> p kcvfhckp
struct kcvfhckp, 36 bytes
@484
struct kcvcpscn, 8 bytes
@484
ub4 kscnbas
@484
0x000a83d6
ub2 kscnwrp
@488
0x0000
ub4 kcvcptim
@492
0x2799048e
the hexadecimal value 0x000a83d6 should convert
to 689110 in base 10 (decimal). use the
scientific calculator on windows, something on
the internet, or get the decimal value manually.
the fun way is by hand. the significant part of
the hex value is a83d6. convert hex to binary
where each hex character is xxxx in binary. now
there is:
a
|
8
|
3
|
d
|
6
|
1010
|
1000
|
0011
|
1101
|
0110
|
binary 1010100001111010110 is 689110, so that is
good. now print kcvfhcpc and kcvfhccc. the
system datafile is used by setting dba 1,1.
bbed> p kcvfhcpc
ub4 kcvfhcpc
@140
0x0000004a
bbed> p kcvfhccc
ub4 kcvfhccc
@148
0x00000049
one other, albeit final complication in all of
this is taking into account the byte ordering of
data on the platform the server is running on.
it is big endian versus little endian. the
database is running oracle enterprise linux on a
pc, so that makes it little endian. the order of
the first two values has to be reversed (pair by
pair). to summarize the changes to be made to
the older file, see the table below.
attribute
|
kscnbas
|
kcvcptim
|
kcvfhcpc
|
kcvfhccc
|
value
|
000a83d6
(d6830a00)
|
2799048e
(8e049927)
|
4a
|
49
|
offset
|
484
|
492
|
140
|
148
|
use the modify command with
/x for hexadecimal editing and a
dba of file 6, block 1.
when finished with the four modify statements,
perform a “sum dba x,1 apply” where “x” is your
file number. if after applying the changes one
receives an error upon startup, check the scn
values output from:
select file#, change# from
v$recover_file; and
select v1.group#, member,
sequence#, first_change#
from v$log v1, v$logfile
v2
where v1.group# =
v2.group#;
if the scn for the recovered file is wildly
different from the others, the byte ordering of
the hex value during the modify command might
have been reversed.
sql> startup
oracle instance started.
total system global area
922746880 bytes
fixed size
1222624 bytes
variable size
281020448 bytes
database buffers
633339904 bytes
redo buffers
7163904 bytes
database mounted.
ora-01122: database file 6
failed verification check
ora-01110: data file 6:
'/opt/app/oracle/oradata/orcl2/bb01.dbf'
ora-01207: file is more
recent than control file - old control file