Tuesday, February 26, 2013

A demonstration of Oracle row movement within a block.

The following is an investigation of what happens in the Oracle block when a record does not have room to grow.


SQL> create table TEST_TABLE(id integer, attribute1 varchar2(200)) tablespace test;

Table created.

SQL> select file_id, file_name from dba_data_files where tablespace_name = 'TEST';

   FILE_ID
----------
FILE_NAME
----------------------------------------------------------------
         5
D:\ORACLE\WIN64\DATAFILE\O1_MF_TEST_8LRBSQ59_.DBF

SQL> select object_id, data_object_id from dba_objects where object_name = 'TEST_TABLE';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
     73516          73516

SQL> insert into test_table values (1,'AAAAA');

1 row created.

SQL> insert into test_table values (2,'BBBBB');

1 row created.

SQL> commit;

Commit complete.

SQL> alter system checkpoint;

System altered.

SQL> select file_id, block_id, blocks, relative_fno from dba_extents where segme
nt_name = 'TEST_TABLE';

   FILE_ID   BLOCK_ID     BLOCKS RELATIVE_FNO
---------- ---------- ---------- ------------
         5        160          8            5

We extract the block contents using the following program :- http://blog.contractoracle.com/2013/02/java-program-to-extract-data-from.html


Block 163 Contains Object ID 73516
Block Header start       :- 0
 Block Type 06-DATA          :- 06 
 Block Format                :- A2 
 Spare1                      :- 00 
 Spare2                      :- 00 
 Relative Block Address      :- 20971683
 SCN Base                    :- 1075559
 SCN Wrap                    :- 0
 Sequence                    :- 01 
 Flag 01-NEW                 :- 06 
 CheckSum                    :- 32492
 Spare3                      :- 0
Transaction Header start  :- 20
 Type 01-DATA 02-INDEX       :- 01 
 Spare 1                     :- 00 
 Spare 2                     :- 00 
 Spare 3                     :- 00 
 Object ID                   :- 73516
 Cleanout SCN Base           :- 1075556
 Cleanout SCN Wrap           :- 0
 Spare 4                     :- 00 
 Spare 5                     :- 00 
 ITL Slots                   :- 2
 UNKNOWN Byte                :- 00 
 Flag 00-FREE                :- 32 
 ITL TX Feeelist Slot        :- 00 
 Next Block On Free List     :- 20971680
ITLSlot                     :- 1
 Undo Segment               :- 1
 Undo Segment Slot          :- 5
 Transaction Sequence       :- 633
 Undo Block Address         :- 12583566
 Undo Sequence              :- 165
 Undo Record Number         :- 23
 Spare 1                    :- 0
 Flag                       :- 8194
 _ktbitun                   :- 0
 Base                       :- 1075559
ITLSlot                     :- 2
 Undo Segment               :- 0
 Undo Segment Slot          :- 0
 Transaction Sequence       :- 0
 Undo Block Address         :- 0
 Undo Sequence              :- 0
 Undo Record Number         :- 0
 Spare 1                    :- 0
 Flag                       :- 0
 _ktbitun                   :- 0
 Base                       :- 0
Data Header start        :- 100
 Flags                       :- 00 
 Number of Tables            :- 1
 Number of Rows              :- 2
 Offset to Freespace Start   :- -1
 Offset to Freespace End     :- 22
 Available Space             :- 8064
 Available Space after Commit:- 8042
Table Directory start    :-114
 Table                       :- 1
  Offset                      :- 0
  Number of Rows              :- 2
 Total Number of Rows        :- 2
Row Directory start      :-118
 Row Offset 1 :- 8076(+100)
 Row Offset 2 :- 8064(+100)
1 Row Header start  :-8176
 Flags              :-  2C  Table Data
 Lock Status        :- 01 
 Number of Columns  :- 2
Column 1 Bytes 2 Data :- C1 02 
Column 2 Bytes 5 Data :- AAAAA
2 Row Header start  :-8164
 Flags              :-  2C  Table Data
 Lock Status        :- 01 
 Number of Columns  :- 2
Column 1 Bytes 2 Data :- C1 03 
Column 2 Bytes 5 Data :- BBBBB

From the above we can see that there are two rows in block 163, starting at bytes 8164 and 8176.  The first record inserted (AAAAA) is at the end of the block, with no room to grow.

If we update the record with more data :-


SQL> update test_table set attribute1 = '012345678901234567890123456789012345678
9012345678901234567890123456789012345678901234567890' where attribute1 = 'AAAAA'
;

1 row updated.

SQL> commit;

Commit complete.

SQL> alter system checkpoint;

System altered.


We can now see that :-

1. the block SCNs and sequence have been updated

2. the block CheckSum has been updated
3. the Available Space in the block has decreased
4. the record that previously started at byte 8176 has now moved to byte 8066 to allow it to grow.


Block 163 Contains Object ID 73516
Block Header start       :- 0
 Block Type 06-DATA          :- 06 
 Block Format                :- A2 
 Spare1                      :- 00 
 Spare2                      :- 00 
 Relative Block Address      :- 20971683
 SCN Base                    :- 1075759
 SCN Wrap                    :- 0
 Sequence                    :- 02 
 Flag 01-NEW                 :- 06 
 CheckSum                    :- -25092
 Spare3                      :- 0
Transaction Header start  :- 20
 Type 01-DATA 02-INDEX       :- 01 
 Spare 1                     :- 00 
 Spare 2                     :- 00 
 Spare 3                     :- 00 
 Object ID                   :- 73516
 Cleanout SCN Base           :- 1075757
 Cleanout SCN Wrap           :- 0
 Spare 4                     :- 00 
 Spare 5                     :- 00 
 ITL Slots                   :- 2
 UNKNOWN Byte                :- 00 
 Flag 00-FREE                :- 32 
 ITL TX Feeelist Slot        :- 00 
 Next Block On Free List     :- 20971680
ITLSlot                     :- 1
 Undo Segment               :- 1
 Undo Segment Slot          :- 5
 Transaction Sequence       :- 633
 Undo Block Address         :- 12583566
 Undo Sequence              :- 165
 Undo Record Number         :- 23
 Spare 1                    :- 0
 Flag                       :- -32768
 _ktbitun                   :- 0
 Base                       :- 1075559
ITLSlot                     :- 2
 Undo Segment               :- 7
 Undo Segment Slot          :- 22
 Transaction Sequence       :- 605
 Undo Block Address         :- 12583559
 Undo Sequence              :- 222
 Undo Record Number         :- 49
 Spare 1                    :- 0
 Flag                       :- 8193
 _ktbitun                   :- 0
 Base                       :- 1075759
Data Header start        :- 100
 Flags                       :- 00 
 Number of Tables            :- 1
 Number of Rows              :- 2
 Offset to Freespace Start   :- -1
 Offset to Freespace End     :- 22
 Available Space             :- 7966
 Available Space after Commit:- 7956
Table Directory start    :-114
 Table                       :- 1
  Offset                      :- 0
  Number of Rows              :- 2
 Total Number of Rows        :- 2
Row Directory start      :-118
 Row Offset 1 :- 7966(+100)
 Row Offset 2 :- 8064(+100)
1 Row Header start  :-8066
 Flags              :-  2C  Table Data
 Lock Status        :- 02 
 Number of Columns  :- 2
Column 1 Bytes 2 Data :- C1 02 
Column 2 Bytes 91 Data :- 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
2 Row Header start  :-8164
 Flags              :-  2C  Table Data
 Lock Status        :- 00 
 Number of Columns  :- 2
Column 1 Bytes 2 Data :- C1 03 
Column 2 Bytes 5 Data :- BBBBB



What happens to Oracle data blocks during Truncate.

The following is an investigation of what happens during an Oracle table truncate.  First we create a table and insert two records.


SQL> create table TEST_TABLE(id integer, attribute1 char(5), attribute2 varchar2 (5)) tablespace test;

Table created.

SQL> select file_id, file_name from dba_data_files where tablespace_name = 'TEST';

   FILE_ID
----------
FILE_NAME
-----------------------------------------------------------------
         5
D:\ORACLE\WIN64\DATAFILE\O1_MF_TEST_8LRBSQ59_.DBF


SQL> select object_id, data_object_id from dba_objects where object_name = 'TEST_TABLE';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
     73514          73514

SQL> insert into test_table values (1,'AAAAA','BBB');

1 row created.

SQL> insert into test_table values (2,'CCCCC','DDDDD');

1 row created.

SQL> commit;

Commit complete.

SQL> alter system checkpoint;

System altered.

SQL> select file_id, block_id, blocks, relative_fno from dba_extents where segment_name = 'TEST_TABLE';

   FILE_ID   BLOCK_ID     BLOCKS RELATIVE_FNO
---------- ---------- ---------- ------------
         5        152          8            5


We can find the data for the table in file 5 in an extent starting at block 152.  When we scan for the data, we find that the records we inserted are in block 155, with empty blocks 156,7,8,9.  The following output is from :- http://blog.contractoracle.com/2013/02/java-program-to-extract-data-from.html



Block 155 Contains Object ID 73514
Block Header start       :- 0
 Block Type 06-DATA          :- 06 
 Block Format                :- A2 
 Spare1                      :- 00 
 Spare2                      :- 00 
 Relative Block Address      :- 20971675
 SCN Base                    :- 1074483
 SCN Wrap                    :- 0
 Sequence                    :- 01 
 Flag 01-NEW                 :- 06 
 CheckSum                    :- 14737
 Spare3                      :- 0
Transaction Header start  :- 20
 Type 01-DATA 02-INDEX       :- 01 
 Spare 1                     :- 00 
 Spare 2                     :- 00 
 Spare 3                     :- 00 
 Object ID                   :- 73514
 Cleanout SCN Base           :- 1074478
 Cleanout SCN Wrap           :- 0
 Spare 4                     :- 00 
 Spare 5                     :- 00 
 ITL Slots                   :- 2
 UNKNOWN Byte                :- 00 
 Flag 00-FREE                :- 32 
 ITL TX Feeelist Slot        :- 00 
 Next Block On Free List     :- 20971672
ITLSlot                     :- 1
 Undo Segment               :- 1
 Undo Segment Slot          :- 14
 Transaction Sequence       :- 632
 Undo Block Address         :- 12583042
 Undo Sequence              :- 162
 Undo Record Number         :- 51
 Spare 1                    :- 0
 Flag                       :- 8194
 _ktbitun                   :- 0
 Base                       :- 1074483
ITLSlot                     :- 2
 Undo Segment               :- 0
 Undo Segment Slot          :- 0
 Transaction Sequence       :- 0
 Undo Block Address         :- 0
 Undo Sequence              :- 0
 Undo Record Number         :- 0
 Spare 1                    :- 0
 Flag                       :- 0
 _ktbitun                   :- 0
 Base                       :- 0
Data Header start        :- 100
 Flags                       :- 00 
 Number of Tables            :- 1
 Number of Rows              :- 2
 Offset to Freespace Start   :- -1
 Offset to Freespace End     :- 22
 Available Space             :- 8054
 Available Space after Commit:- 8032
Table Directory start    :-114
 Table                       :- 1
  Offset                      :- 0
  Number of Rows              :- 2
 Total Number of Rows        :- 2
Row Directory start      :-118
 Row Offset 1 :- 8072(+100)
 Row Offset 2 :- 8054(+100)
1 Row Header start  :-8172
 Flags              :-  2C  Table Data
 Lock Status        :- 01 
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 02 
Column 2 Bytes 5 Data :- AAAAA
Column 3 Bytes 3 Data :- BBB
2 Row Header start  :-8154
 Flags              :-  2C  Table Data
 Lock Status        :- 01 
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 03 
Column 2 Bytes 5 Data :- CCCCC
Column 3 Bytes 5 Data :- DDDDD

Block 156 Contains Object ID 73514
Block 157 Contains Object ID 73514
Block 158 Contains Object ID 73514
Block 159 Contains Object ID 73514

Now we truncate the table.  Selecting from the data dictionary table we can see that the data blocks listed in DBA_EXTENTS did not change, but in DBA_OBJECTS the DATA_OBJECT_ID was updated.



SQL> truncate table test_table;

Table truncated.

SQL> alter system checkpoint;

System altered.

SQL> select * from test_table;

no rows selected


SQL> select object_id, data_object_id from dba_objects where object_name = 'TEST_TABLE';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
     73514          73515

SQL> select file_id, block_id, blocks, relative_fno from dba_extents where segment_name = 'TEST_TABLE';

   FILE_ID   BLOCK_ID     BLOCKS RELATIVE_FNO
---------- ---------- ---------- ------------
         5        152          8            5

If we again scan for blocks associated with the old DATA_OBJECT_ID 73514 we can see that they are unchanged and still have the original data in them.  This means that even after a table is truncated, the data remains in the blocks on disk, and could be extracted (until the blocks are overwritten).


Block 155 Contains Object ID 73514
Block Header start       :- 0
 Block Type 06-DATA          :- 06 
 Block Format                :- A2 
 Spare1                      :- 00 
 Spare2                      :- 00 
 Relative Block Address      :- 20971675
 SCN Base                    :- 1074483
 SCN Wrap                    :- 0
 Sequence                    :- 01 
 Flag 01-NEW                 :- 06 
 CheckSum                    :- 14737
 Spare3                      :- 0
Transaction Header start  :- 20
 Type 01-DATA 02-INDEX       :- 01 
 Spare 1                     :- 00 
 Spare 2                     :- 00 
 Spare 3                     :- 00 
 Object ID                   :- 73514
 Cleanout SCN Base           :- 1074478
 Cleanout SCN Wrap           :- 0
 Spare 4                     :- 00 
 Spare 5                     :- 00 
 ITL Slots                   :- 2
 UNKNOWN Byte                :- 00 
 Flag 00-FREE                :- 32 
 ITL TX Feeelist Slot        :- 00 
 Next Block On Free List     :- 20971672
ITLSlot                     :- 1
 Undo Segment               :- 1
 Undo Segment Slot          :- 14
 Transaction Sequence       :- 632
 Undo Block Address         :- 12583042
 Undo Sequence              :- 162
 Undo Record Number         :- 51
 Spare 1                    :- 0
 Flag                       :- 8194
 _ktbitun                   :- 0
 Base                       :- 1074483
ITLSlot                     :- 2
 Undo Segment               :- 0
 Undo Segment Slot          :- 0
 Transaction Sequence       :- 0
 Undo Block Address         :- 0
 Undo Sequence              :- 0
 Undo Record Number         :- 0
 Spare 1                    :- 0
 Flag                       :- 0
 _ktbitun                   :- 0
 Base                       :- 0
Data Header start        :- 100
 Flags                       :- 00 
 Number of Tables            :- 1
 Number of Rows              :- 2
 Offset to Freespace Start   :- -1
 Offset to Freespace End     :- 22
 Available Space             :- 8054
 Available Space after Commit:- 8032
Table Directory start    :-114
 Table                       :- 1
  Offset                      :- 0
  Number of Rows              :- 2
 Total Number of Rows        :- 2
Row Directory start      :-118
 Row Offset 1 :- 8072(+100)
 Row Offset 2 :- 8054(+100)
1 Row Header start  :-8172
 Flags              :-  2C  Table Data
 Lock Status        :- 01 
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 02 
Column 2 Bytes 5 Data :- AAAAA
Column 3 Bytes 3 Data :- BBB
2 Row Header start  :-8154
 Flags              :-  2C  Table Data
 Lock Status        :- 01 
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 03 
Column 2 Bytes 5 Data :- CCCCC
Column 3 Bytes 5 Data :- DDDDD

Block 156 Contains Object ID 73514
Block 157 Contains Object ID 73514
Block 158 Contains Object ID 73514
Block 159 Contains Object ID 73514



Monday, February 25, 2013

What happens in an Oracle block during a delete.

The following is an investigation of what happens in the Oracle database block when a record is deleted.  First we create a table with 2 rows.


SQL> create table TEST_TABLE(id integer, attribute1 char(5), attribute2 varchar2 (5)) tablespace test;

Table created.

SQL> select file_id, file_name from dba_data_files where tablespace_name = 'TEST';

   FILE_ID
----------
FILE_NAME
----------------------------------------------------------------
         5
D:\ORACLE\WIN64\DATAFILE\O1_MF_TEST_8LRBSQ59_.DBF


SQL> select object_id, data_object_id from dba_objects where object_name = 'TEST_TABLE';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
     73513          73513

SQL> insert into test_table values (1,'AAAAA','BBB');

1 row created.

SQL> insert into test_table values (2,'CCCCC','DDDDD');

1 row created.

SQL> commit;

Commit complete.

SQL> select file_id, block_id, blocks, relative_fno from dba_extents where segment_name = 'TEST_TABLE';

   FILE_ID   BLOCK_ID     BLOCKS RELATIVE_FNO
---------- ---------- ---------- ------------
         5        144          8            5

SQL> alter system checkpoint;

System altered.


When we scan the file for data object ID 73513 we find the data in block 150.  The following block data was extracted using :- http://blog.contractoracle.com/2013/02/java-program-to-extract-data-from.html


Block 150 Contains Object ID 73513
Block Header start       :- 0
 Block Type 06-DATA          :- 06 
 Block Format                :- A2 
 Spare1                      :- 00 
 Spare2                      :- 00 
 Relative Block Address      :- 20971670
 SCN Base                    :- 1073062
 SCN Wrap                    :- 0
 Sequence                    :- 01 
 Flag 01-NEW                 :- 06 
 CheckSum                    :- 14473
 Spare3                      :- 0
Transaction Header start  :- 20
 Type 01-DATA 02-INDEX       :- 01 
 Spare 1                     :- 00 
 Spare 2                     :- 00 
 Spare 3                     :- 00 
 Object ID                   :- 73513
 Cleanout SCN Base           :- 1073058
 Cleanout SCN Wrap           :- 0
 Spare 4                     :- 00 
 Spare 5                     :- 00 
 ITL Slots                   :- 2
 UNKNOWN Byte                :- 00 
 Flag 00-FREE                :- 32 
 ITL TX Feeelist Slot        :- 00 
 Next Block On Free List     :- 20971664
ITLSlot                     :- 1
 Undo Segment               :- 5
 Undo Segment Slot          :- 33
 Transaction Sequence       :- 814
 Undo Block Address         :- 12583110
 Undo Sequence              :- 169
 Undo Record Number         :- 6
 Spare 1                    :- 0
 Flag                       :- 8194
 _ktbitun                   :- 0
 Base                       :- 1073062
ITLSlot                     :- 2
 Undo Segment               :- 0
 Undo Segment Slot          :- 0
 Transaction Sequence       :- 0
 Undo Block Address         :- 0
 Undo Sequence              :- 0
 Undo Record Number         :- 0
 Spare 1                    :- 0
 Flag                       :- 0
 _ktbitun                   :- 0
 Base                       :- 0
Data Header start        :- 100
 Flags                       :- 00 
 Number of Tables            :- 1
 Number of Rows              :- 2
 Offset to Freespace Start   :- -1
 Offset to Freespace End     :- 22
 Available Space             :- 8054
 Available Space after Commit:- 8032
Table Directory start    :-114
 Table                       :- 1
  Offset                      :- 0
  Number of Rows              :- 2
 Total Number of Rows        :- 2
Row Directory start      :-118
 Row Offset 1 :- 8072(+100)
 Row Offset 2 :- 8054(+100)
1 Row Header start  :-8172
 Flags              :-  2C  Table Data
 Lock Status        :- 01 
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 02 
Column 2 Bytes 5 Data :- AAAAA
Column 3 Bytes 3 Data :- BBB
2 Row Header start  :-8154
 Flags              :-  2C  Table Data
 Lock Status        :- 01 
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 03 
Column 2 Bytes 5 Data :- CCCCC
Column 3 Bytes 5 Data :- DDDDD


Now we delete one row :-


SQL> delete from test_table where id = 1;

1 row deleted.

SQL> commit;

Commit complete.


SQL> select * from test_table;

        ID ATTRI ATTRI
---------- ----- -----
         2 CCCCC DDDDD


SQL> alter system checkpoint;

System altered.



And we can extract the block data again and confirm that the result of the delete is that  :-

1. the block SCNs and Sequence have been updated
2. the block CheckSum has been updated
3. ITL Slot 2 was used for the transaction
4. ITL Slot 1 flag was set to -32768 (unused)
5. The row header flag was updated from 2C to 3C
6. The row header lock status was updated to 02

Note that the delete did not actually remove the record from the block, it just updated the row flag.  This means that even if a record has been deleted from an Oracle database table is possible to read the data for the deleted record directly from the block (until it is overwritten).



Block 150 Contains Object ID 73513
Block Header start       :- 0
 Block Type 06-DATA          :- 06 
 Block Format                :- A2 
 Spare1                      :- 00 
 Spare2                      :- 00 
 Relative Block Address      :- 20971670
 SCN Base                    :- 1073294
 SCN Wrap                    :- 0
 Sequence                    :- 02 
 Flag 01-NEW                 :- 06 
 CheckSum                    :- -6419
 Spare3                      :- 0
Transaction Header start  :- 20
 Type 01-DATA 02-INDEX       :- 01 
 Spare 1                     :- 00 
 Spare 2                     :- 00 
 Spare 3                     :- 00 
 Object ID                   :- 73513
 Cleanout SCN Base           :- 1073292
 Cleanout SCN Wrap           :- 0
 Spare 4                     :- 00 
 Spare 5                     :- 00 
 ITL Slots                   :- 2
 UNKNOWN Byte                :- 00 
 Flag 00-FREE                :- 32 
 ITL TX Feeelist Slot        :- 00 
 Next Block On Free List     :- 20971664
ITLSlot                     :- 1
 Undo Segment               :- 5
 Undo Segment Slot          :- 33
 Transaction Sequence       :- 814
 Undo Block Address         :- 12583110
 Undo Sequence              :- 169
 Undo Record Number         :- 6
 Spare 1                    :- 0
 Flag                       :- -32768
 _ktbitun                   :- 0
 Base                       :- 1073062
ITLSlot                     :- 2
 Undo Segment               :- 6
 Undo Segment Slot          :- 27
 Transaction Sequence       :- 797
 Undo Block Address         :- 12583068
 Undo Sequence              :- 174
 Undo Record Number         :- 43
 Spare 1                    :- 0
 Flag                       :- 8193
 _ktbitun                   :- 14
 Base                       :- 1073294
Data Header start        :- 100
 Flags                       :- 00 
 Number of Tables            :- 1
 Number of Rows              :- 2
 Offset to Freespace Start   :- -1
 Offset to Freespace End     :- 22
 Available Space             :- 8054
 Available Space after Commit:- 8032
Table Directory start    :-114
 Table                       :- 1
  Offset                      :- 0
  Number of Rows              :- 2
 Total Number of Rows        :- 2
Row Directory start      :-118
 Row Offset 1 :- 8072(+100)
 Row Offset 2 :- 8054(+100)
1 Row Header start  :-8172
 Flags              :-  3C  Deleted
 Lock Status        :- 02 
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 02 
Column 2 Bytes 5 Data :- AAAAA
Column 3 Bytes 3 Data :- BBB
2 Row Header start  :-8154
 Flags              :-  2C  Table Data
 Lock Status        :- 00 
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 03 
Column 2 Bytes 5 Data :- CCCCC
Column 3 Bytes 5 Data :- DDDDD


What happens in an Oracle Block during an update.

The following is an investigation of what happens in an Oracle datafile block during an update.  First we create a simple table with two rows.


SQL> create table TEST_TABLE(id integer, attribute1 char(5), attribute2 varchar2(5)) tablespace test;

Table created.

SQL> select file_id, file_name from dba_data_files where tablespace_name = 'TEST';

   FILE_ID
----------
FILE_NAME
-----------------------------------------------------------------
         5
D:\ORACLE\WIN64\DATAFILE\O1_MF_TEST_8LRBSQ59_.DBF


SQL> select object_id, data_object_id from dba_objects where object_name = 'TEST
_TABLE';

 OBJECT_ID DATA_OBJECT_ID
---------- --------------
     73512          73512

SQL> insert into test_table values (1,'AAAAA','BBB');

1 row created.

SQL> commit;

Commit complete.

SQL> insert into test_table values (2,'CCCCC','DDDDD');

1 row created.

SQL> commit;

Commit complete.

SQL> select file_id, block_id, blocks, relative_fno from dba_extents where segme
nt_name = 'TEST_TABLE';

   FILE_ID   BLOCK_ID     BLOCKS RELATIVE_FNO
---------- ---------- ---------- ------------
         5        136          8            5

SQL> alter system checkpoint;

System altered.


The table we are working on for this test is stored in file 5 with extent starting at block 136 in blocks with DATA_OBJECT_ID 73512 .  When we scan the file for blocks with data object ID 73512 we can see that the rows we are interested in are in block 139.  Two ITL Slots have been created in the block.

The following block data was extracted using :- http://blog.contractoracle.com/2013/02/java-program-to-extract-data-from.html


Block 139 Contains Object ID 73512
Block Header start       :- 0
 Block Type 06-DATA          :- 06 
 Block Format                :- A2 
 Spare1                      :- 00 
 Spare2                      :- 00 
 Relative Block Address      :- 20971659
 SCN Base                    :- 1072047
 SCN Wrap                    :- 0
 Sequence                    :- 02 
 Flag 01-NEW                 :- 06 
 CheckSum                    :- 17170
 Spare3                      :- 0
Transaction Header start  :- 20
 Type 01-DATA 02-INDEX       :- 01 
 Spare 1                     :- 00 
 Spare 2                     :- 00 
 Spare 3                     :- 00 
 Object ID                   :- 73512
 Cleanout SCN Base           :- 1072042
 Cleanout SCN Wrap           :- 0
 Spare 4                     :- 00 
 Spare 5                     :- 00 
 ITL Slots                   :- 2
 UNKNOWN Byte                :- 00 
 Flag 00-FREE                :- 32 
 ITL TX Feeelist Slot        :- 00 
 Next Block On Free List     :- 20971656
ITLSlot                     :- 1
 Undo Segment               :- 10
 Undo Segment Slot          :- 29
 Transaction Sequence       :- 633
 Undo Block Address         :- 12583185
 Undo Sequence              :- 140
 Undo Record Number         :- 3
 Spare 1                    :- 0
 Flag                       :- 8193
 _ktbitun                   :- 0
 Base                       :- 1072043
ITLSlot                     :- 2
 Undo Segment               :- 5
 Undo Segment Slot          :- 19
 Transaction Sequence       :- 814
 Undo Block Address         :- 12583108
 Undo Sequence              :- 169
 Undo Record Number         :- 33
 Spare 1                    :- 0
 Flag                       :- 8193
 _ktbitun                   :- 0
 Base                       :- 1072047
Data Header start        :- 100
 Flags                       :- 00 
 Number of Tables            :- 1
 Number of Rows              :- 2
 Offset to Freespace Start   :- -1
 Offset to Freespace End     :- 22
 Available Space             :- 8054
 Available Space after Commit:- 8032
Table Directory start    :-114
 Table                       :- 1
  Offset                      :- 0
  Number of Rows              :- 2
 Total Number of Rows        :- 2
Row Directory start      :-118
 Row Offset 1 :- 8072(+100)
 Row Offset 2 :- 8054(+100)
1 Row Header start  :-8172
 Flags              :-  2C  Table Data
 Lock Status        :- 01 
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 02 
Column 2 Bytes 5 Data :- AAAAA
Column 3 Bytes 3 Data :- BBB
2 Row Header start  :-8154
 Flags              :-  2C  Table Data
 Lock Status        :- 02 
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 03 
Column 2 Bytes 5 Data :- CCCCC
Column 3 Bytes 5 Data :- DDDDD



Now we update one record in the table.


SQL> update test_table set attribute1 = 'EEEEE' where attribute1 = 'AAAAA';

1 row updated.

SQL> commit;

Commit complete.

SQL> alter system checkpoint;

System altered.


After dumping the block we can see that :-


1. block SCNs were updated
2. block CheckSum was updated
3. ITL Slot 1 was used for the transaction
4. ITL Slot 2 flag was updated to -32768 (I guess indicating unused)
5. The Row lock status for the untouched row was cleared.
6. The data was updated.



Block 139 Contains Object ID 73512
Block Header start       :- 0
 Block Type 06-DATA          :- 06
 Block Format                :- A2
 Spare1                      :- 00
 Spare2                      :- 00
 Relative Block Address      :- 20971659
 SCN Base                    :- 1072247
 SCN Wrap                    :- 0
 Sequence                    :- 02
 Flag 01-NEW                 :- 06
 CheckSum                    :- -6509
 Spare3                      :- 0
Transaction Header start  :- 20
 Type 01-DATA 02-INDEX       :- 01
 Spare 1                     :- 00
 Spare 2                     :- 00
 Spare 3                     :- 00
 Object ID                   :- 73512
 Cleanout SCN Base           :- 1072246
 Cleanout SCN Wrap           :- 0
 Spare 4                     :- 00
 Spare 5                     :- 00
 ITL Slots                   :- 2
 UNKNOWN Byte                :- 00
 Flag 00-FREE                :- 32
 ITL TX Feeelist Slot        :- 00
 Next Block On Free List     :- 20971656
ITLSlot                     :- 1
 Undo Segment               :- 4
 Undo Segment Slot          :- 16
 Transaction Sequence       :- 596
 Undo Block Address         :- 12583572
 Undo Sequence              :- 147
 Undo Record Number         :- 55
 Spare 1                    :- 0
 Flag                       :- 8193
 _ktbitun                   :- 0
 Base                       :- 1072247
ITLSlot                     :- 2
 Undo Segment               :- 5
 Undo Segment Slot          :- 19
 Transaction Sequence       :- 814
 Undo Block Address         :- 12583108
 Undo Sequence              :- 169
 Undo Record Number         :- 33
 Spare 1                    :- 0
 Flag                       :- -32768
 _ktbitun                   :- 0
 Base                       :- 1072047
Data Header start        :- 100
 Flags                       :- 00
 Number of Tables            :- 1
 Number of Rows              :- 2
 Offset to Freespace Start   :- -1
 Offset to Freespace End     :- 22
 Available Space             :- 8054
 Available Space after Commit:- 8032
Table Directory start    :-114
 Table                       :- 1
  Offset                      :- 0
  Number of Rows              :- 2
 Total Number of Rows        :- 2
Row Directory start      :-118
 Row Offset 1 :- 8072(+100)
 Row Offset 2 :- 8054(+100)
1 Row Header start  :-8172
 Flags              :-  2C  Table Data
 Lock Status        :- 01
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 02
Column 2 Bytes 5 Data :- EEEEE
Column 3 Bytes 3 Data :- BBB
2 Row Header start  :-8154
 Flags              :-  2C  Table Data
 Lock Status        :- 00
 Number of Columns  :- 3
Column 1 Bytes 2 Data :- C1 03
Column 2 Bytes 5 Data :- CCCCC
Column 3 Bytes 5 Data :- DDDDD