Thursday, July 19, 2007


Block Browser and Editor on Linux with Oracle 10g R2 database



Article [1] has been written in French, contains two interesting examples .
The posting bellow is supposed to be a translation final part from [1] to English,
dealing with other tables from sample schemas loaded during standard installation.
However , the way to obtain oracle's file number and block number for particular
record from selected table is different from [1].
We also focus attention at index corruption after changing field's value or record
recovery by BBED.


1.Modifying field's value for particular record in hr.departments table.


Get file number and header block for table hr.departments:-



select owner,segment_name,header_file,header_block,blocks
from dba_segments
where owner='HR' and segment_name='DEPARTMENTS';


OWNER SEGMENT_NAME HEADER_FILE HEADER_BLOCK BLOCKS
------- ------------------- -------------------- ---------------------- -------------
SCOTT EMP 5 55 8




Getting block number of record, supposed to be changed, with dbms_rowid package:-




Searching for offset of the pattern:-




Run "modify /c Abcdefg" to replace "Support" :-




Update block's checksum:-




Verify data with select statement:-



SQL> alter system flush buffer_cache;




To force Oracle perform reading block from disk device,not from buffer cache.




2.Recovering deleted record from scott.emp.


Get file number and header block for table scott.emp:-



select owner,segment_name,header_file,header_block,blocks
from dba_segments
where owner='SCOTT' and segment_name='EMP';


OWNER SEGMENT_NAME HEADER_FILE HEADER_BLOCK BLOCKS
------ ----------- ------------- -------------- ------
SCOTT EMP 4 27 8




Get the block number contains record with ename='JAMES' like in previous example.
Then search for word 'JAMES' to get it's offset.



Make dump with offset=offset-16 and look for first byte of the record (0x2c)
Watch the value of first byte of record when it got deleted.




First byte of deleted record appears to be changed to hexadecimal 0x3c.
The intend is to put 0x2c back on it's place as the first byte of deleted record.



SQL> delete from emp where ename='JAMES';

1 row deleted.

SQL> commit;

Commit complete.




Run "modify /x 2c" in bbed:-




Update block's checksum:-




Restart Oracle instance:-



SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup;
ORACLE instance started.

Total System Global Area 285212672 bytes
Fixed Size 1218968 bytes
Variable Size 83887720 bytes
Database Buffers 192937984 bytes
Redo Buffers 7168000 bytes
Database mounted.
Database opened.




Or just:-



SQL> alter system flush buffer_cache;




To force Oracle perform reading block from disk device,not from buffer cache.


Check for undeleted record:-



SQL> conn scott/tiger@orcl;
Connected.

SQL> select * from emp where ename='JAMES';

EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO
----------
7900 JAMES CLERK 7698 03-DEC-81 950
30

SQL> select * from emp where empno=7900;
no rows selected




At this point it became quite clear , that we have to recreate any indexes on table,
which records have been recovered by BBED.They are no longer valid.
Same issue will be in place regarding indexes based on columns have been modified by BBED.
Recreate index on empno field of emp table:-



SQL> alter table emp drop constraint PK_EMP;

Table altered.

SQL> alter table emp add constraint PK_EMP primary key(empno);

Table altered.

SQL> select * from emp where empno=7900;

EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- --------- ---------- ----------
DEPTNO
----------
7900 JAMES CLERK 7698 03-DEC-81 950
30




References.


1.http://mbouayoun.developpez.com/bbed/
2.http://orafaq.com/papers/dissassembling_the_data_block.pdf