Monday, February 25, 2013

Java program to extract records from Oracle Control Files.

Following is the simple Java program I used to extract database name, file names, and tablespace names from Oracle Control Files.  It could easily be modified to extract backup information etc.

It is a large Java program laid out in order of execution for easy reading and learning purposes.  Yes, I know that  a "real Java programmer" would do a better job, and there is lots of room for improvement, but it is good enough for learning about Oracle data structures.

Anyone is welcome to download it, modify it, and use it for any purpose, but I don't guarantee that it extracts all records available, or will work on all OS or DB versions.  Use it at your own risk.  Enjoy !

An example of the output can be found here :- http://blog.contractoracle.com/2013/02/oracle-control-file-physical-structure.html


# ControlScanCMD.java


import java.io.IOException;
import java.io.RandomAccessFile;

public class ControlScanCMD {

public static void main(String[] args) {
try {

    RandomAccessFile raf = new RandomAccessFile("D:\\oracle\\WIN64\\CONTROLFILE\\O1_MF_8L5T35GK_.CTL", "r");
int BlockSize = 8192*2;
int BlockStart = 0;
int BlockNum;
int FileSize =(int)raf.length();
int NumBlocks = FileSize / BlockSize;
int NextRecordStart;
int FileRecordSize = 524;
int TablespaceRecordSize = 68;
int HeaderSize =18;
int TailSize = 4;
int RecordCount = 0;
int FileIdOffset = 4;
int TablespaceFirstChar = 9;
int NameOffset = 14;
int Pointer = 0;
byte MyByte = 0;
char MyChar = 0;
int FileID = 0;

System.out.println("Number of Blocks                 :- " + NumBlocks);

// get database name

BlockStart = BlockSize * 1;
System.out.println("Block                            :- 2");
System.out.print("Tablespace Name :- ");

raf.seek(BlockStart + HeaderSize + NameOffset);

for(int ct1 = 1; ct1 <= 8; ct1++)
{
MyByte = raf.readByte();
if (MyByte == 0) 

System.out.print("");
//System.out.println(String.format("%02X ", raf.readByte()));
}
else if (32 < MyByte && MyByte <= 126) 
{
//MyChar = ((char)Integer.parseInt(String.format("%02X", MyByte), 16));
MyChar = (char)MyByte;
System.out.print("" + MyChar);

//jTextAreaFile.append(" " + ct + "-" + String.format("%02X", MyByte) + " ");
}
else

System.out.print(" " + ct1 + "-" + String.format("%02X", MyByte) + " ");
}
}

System.out.println("");
System.out.println("");

// get file details

for(BlockNum = 31; BlockNum <= 32; BlockNum++)
{
BlockStart = BlockSize * BlockNum;
NextRecordStart = HeaderSize;
RecordCount = 0;
System.out.println("Block                            :- " + BlockNum);

raf.seek(BlockStart + NextRecordStart + FileIdOffset);
FileID = raf.readByte();

while (FileID != 0 && (NextRecordStart + FileRecordSize) < BlockSize)
{
RecordCount = RecordCount + 1;
raf.seek(BlockStart + NextRecordStart);

System.out.println("Record                           :- " + RecordCount);
System.out.println("Byte 1                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 2                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("File Type 3-LOG, 4-DATA, 7-TEMP  :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 4                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("File ID                          :- " + raf.readByte());
System.out.println("Byte 6                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 7                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 8                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 9                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 10                          :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 11                          :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 12                          :- " + String.format("%02X ", raf.readByte()));
System.out.print("File Name :- ");

for(int ct1 = 1; ct1 <= 512; ct1++)
{
MyByte = raf.readByte();
if (MyByte == 0) 

System.out.print("");
//System.out.println(String.format("%02X ", raf.readByte()));
}
else if (32 < MyByte && MyByte <= 126) 
{
//MyChar = ((char)Integer.parseInt(String.format("%02X", MyByte), 16));
MyChar = (char)MyByte;
System.out.print("" + MyChar);

//jTextAreaFile.append(" " + ct + "-" + String.format("%02X", MyByte) + " ");
}
else

System.out.print(" " + ct1 + "-" + String.format("%02X", MyByte) + " ");
}
}
System.out.println("");
System.out.println("");
NextRecordStart = NextRecordStart + FileRecordSize;
raf.seek(BlockStart + NextRecordStart + FileIdOffset);
FileID = raf.readByte();
}


// get tablespace names

for(BlockNum = 179; BlockNum <= 179; BlockNum++)
{
BlockStart = BlockSize * BlockNum;
NextRecordStart = HeaderSize;
RecordCount = 0;
System.out.println("Block                            :- " + BlockNum);

raf.seek(BlockStart + NextRecordStart + TablespaceFirstChar);
FileID = raf.readByte();

while (FileID != 0 && (NextRecordStart + TablespaceRecordSize) < BlockSize)
{
RecordCount = RecordCount + 1;
raf.seek(BlockStart + NextRecordStart);

System.out.println("Record                           :- " + RecordCount);
System.out.println("Byte 1                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 2                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("Tablespace ID                    :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 4                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 5                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 6                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 7                           :- " + String.format("%02X ", raf.readByte()));
System.out.println("Byte 8                           :- " + String.format("%02X ", raf.readByte()));
System.out.print("Tablespace Name :- ");


for(int ct1 = 1; ct1 <= 30; ct1++)
{
MyByte = raf.readByte();
if (MyByte == 0) 

System.out.print("");
//System.out.println(String.format("%02X ", raf.readByte()));
}
else if (32 < MyByte && MyByte <= 126) 
{
//MyChar = ((char)Integer.parseInt(String.format("%02X", MyByte), 16));
MyChar = (char)MyByte;
System.out.print("" + MyChar);

//jTextAreaFile.append(" " + ct + "-" + String.format("%02X", MyByte) + " ");
}
else

System.out.print(" " + ct1 + "-" + String.format("%02X", MyByte) + " ");
}
}
System.out.println("");
System.out.println("");
NextRecordStart = NextRecordStart + TablespaceRecordSize;
raf.seek(BlockStart + NextRecordStart + TablespaceFirstChar);
FileID = raf.readByte();
}
}



}
raf.close();

      } catch (IOException ex) {
         ex.printStackTrace();
      }

}
}