c语言进阶-利用c语言解构oracle底层数据(不开库)-读取字典表tab$,col$表和obj$表

c语言进阶-利用c语言解构oracle底层数据(不开库)-读取字典表tab$,col$表和obj$表_第1张图片

最具挑战性的挑战莫过于提升自我。—— 迈克尔·F·斯特利

     前面我们已经知道基本的数据存储格式,要读取数据库中数据文件的数据,我们首先要知道自己要读取的表叫什么名字,数据存储的开始位置,数据存储的分布信息等。Oracle(11g)数据库启动时,首先会去读取0号数据文件(一般都是system01文件)的520号块存储的内容,即表BOOTSTRAP$。BOOTSTRAP$表里面记录了基础数据字典表的创建分布位置:例如CLUSTER C_OBJ#,该簇中分布有核心表tab$和col$;C_OBJ#的开始块为144,即从144块读取,可以读取出核心表tab$和col$表的内容。对于obj$表,其开始块为240,从240块开始,我们可以读取到obj$的内容。

一,表列格式描述

eb4 tab[32] = {
        O_NUMBER, O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,
        O_NUMBER, O_NUMBER,O_NUMBER,O_VARCHAR2,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,
        O_NUMBER, O_NUMBER,O_DATE,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,
        O_NUMBER };

eb4 col[24] = {
        O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_VARCHAR2,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,
        O_NUMBER, O_NUMBER,O_NUMBER,O_LONG,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,O_NUMBER,
        O_NUMBER, O_NUMBER,O_NUMBER,O_DATE
};

eb4 obj[] = {
        O_NUMBER, O_NUMBER,O_NUMBER,O_VARCHAR2,O_NUMBER,O_VARCHAR2,O_NUMBER,O_DATE,O_DATE,O_DATE,
        O_NUMBER, O_VARCHAR2,O_VARCHAR2,O_NUMBER,O_RAW,O_NUMBER,O_NUMBER,O_NUMBER,O_VARCHAR2,O_VARCHAR2,
        O_DATE
};

    建立了3个数组全局变量,通过里面的值,去匹配tab$,col$和ojb$表每列的类型。

struct sysblock{
    struct kcbh   v_sb_kcbh;
    struct ktech  v_sb_ktech;
    struct ktemh  v_sb_ktemh;
    struct ktetb  *p_sb_ktetb;
    ub4    v_sb_blkid;
    ub2    v_sb_fieid;
    ub2    sb_ktetb_len;
    ub1    v_sb_blktyp;
};


struct datablock{

    struct kcbh   v_db_kcbh;
    struct ktbbh  v_db_ktbbh;
    struct ktbbhitl *p_db_ktbbhitl;
    struct kdbh   v_db_kdbh;
    struct kdbt   *p_db_kdbt;
    eb4    v_db_tbnam;
    ub4    v_db_blkid;
    ub2    v_db_fieid;
    ub2    db_ktbbhitl_len;
    ub2    db_kdbt_len;
    sb2    *p_db_kdbr;
    ub2    db_kdbr_len;
    ub1    v_db_blktyp;
};

    声明两个结构,分别用来读取段头块和数据块的信息。根据段头块信息,可以获取到所有区及数据块的分布信息。根据数据块的信息,可以知道数据块存在几个表,有多少行数据等。

二、核心代码

int main(int argc, char *argv[]){


    startReadData();

    return 0;
}
void startReadData(){
    blkhdr v_blkhdr;
    datablk v_datablk;



    FILE *fp;
    fp = getOracleFile("/opt/oracle/oradata/tpdb/system01.dbf", "r");
    if(fp == NULL){
        exit(EXIT_FAILURE);
    }


    v_blkhdr.v_sb_fieid = 1;


    v_blkhdr.v_sb_blkid = T_OBJ_BLOCK;
    v_datablk.v_db_blktyp = SYS_BLOCK;
    v_datablk.v_db_tbnam = O_OBJ;
    readBlockData(fp, &v_blkhdr, &v_datablk);



    v_blkhdr.v_sb_blkid = C_OBJ_BLOCK;
    v_datablk.v_db_blktyp = CLUSTER_BLOCk;
    v_datablk.v_db_tbnam = O_TAB;
    readBlockData(fp, &v_blkhdr, &v_datablk);

    fclose(fp);
}

    

void readBlockData(FILE *fp, blkhdr *pbh, datablk *pdb){
    ub4 extnum;
    struct ktetb *pktetb_t;
    int i;
    pbh = readBlockHeader(fp, pbh);
    extnum = pbh->v_sb_ktech.extents_ktech;
    pbh->p_sb_ktetb = allocKtetbArray(extnum);
    if( pbh->p_sb_ktetb  == NULL){
        exit(EXIT_FAILURE);
    }
    pbh->sb_ktetb_len = extnum;
    pbh = readKtetbArray(fp , pbh);

    pktetb_t = pbh->p_sb_ktetb;

    for(i=0; iktetbdba);
        pdb->v_db_fieid = ktelocate1.ktefid;
        pdb->v_db_blkid = ktelocate1.ktebid;
        blknums = pktetb_t->ktetbnbk;

        for(j=0; jv_db_kdbh.kdbhntab;
            allrows = pdb->v_db_kdbh .kdbhnrow;

            if(pdb->v_db_kdbh.kdbhntab <= 0)
                continue;



            pdb->p_db_kdbt = allocKdbtArray(tabnums);
            pdb->db_kdbt_len = tabnums;
            pdb = readKdbtArray(fp, pdb);

            pdb->p_db_kdbr = (sb2 *)malloc(sizeof(sb2)*allrows);
            pdb->db_kdbr_len = allrows;
            pdb = readKdbrArray(fp, pdb);


            readObjectTab(fp, pdb);

            pdb->v_db_blkid += 1;


            free(pdb->p_db_kdbr);
            free(pdb->p_db_kdbt);
            free(pdb->p_db_ktbbhitl);


        }


    }
    free(pbh->p_sb_ktetb);

}
void readRowData(FILE *fp, FILE *write, struct datablock *pdb, const size_t idx, const int *tab){
//    sb2 tabnrow = pkdbt[idx]->kdbtnrow;
//    sb2 taboffset = pkdbt->kdbtoffs;
//    ub4 blkoffset = bid * blocksize;


    sb2 tabnrow = (pdb->p_db_kdbt)[idx].kdbtnrow;
    sb2 taboffset = (pdb->p_db_kdbt)[idx].kdbtoffs;
    ub4 blkoffset = pdb->v_db_blkid * blocksize;




//    struct kdtrh kdtrh1;
    unsigned  char colhdr[4];
    int i, j;
    ub2 colhdrlen;
    ub2 colgap = KCBH_LEN + KTBBH_LEN + (pdb->db_ktbbhitl_len)*KTBBHITL_LEN;
    if(pdb->v_db_blktyp == CLUSTER_BLOCk)
        colhdrlen = 4;
    else
        colhdrlen = 3;


    unsigned char *collen = NULL;
    unsigned char *coldata = NULL;

    for(i=0; ip_db_kdbr[taboffset + i];
        if(rowoffset == 0xffff || rowoffset < pdb->v_db_kdbh.kdbhtosp){
            continue;
        }
        long col0;
        ub4 coloffset;
        ub2 truecollen;


        printf("the row is %d\n", i);

        if(pdb->v_db_blktyp == CLUSTER_BLOCk){
            readTabRowHeader(fp, blkoffset + rowoffset + colgap, colhdr, 4);
            col0 = readObjectCobj(fp, pdb, colhdr[3]);
            printf("the col %2d value is %10ld", 0, col0);
            fprintf(write, "the col %2d value is %10ld", 0, col0);
        }
        else
            readTabRowHeader(fp, blkoffset + rowoffset + colgap, colhdr, 3);
        if(colhdr[2] == 0){
            continue;
        }

        coloffset = blkoffset + rowoffset + colgap + colhdrlen;

        for(j=1; jv_db_tbnam){
        //if table name is TAB$
        case O_TAB:
            tabfp = getOracleFile("/tmp/tab.dat","a+");
            readRowData(fp, tabfp, pdb, 1, tab);
            break;
        case O_COL:
            tabfp = getOracleFile("/tmp/col.dat","a+");
            readRowData(fp, tabfp, pdb, 5, col);
            break;
        case O_OBJ:
            tabfp = getOracleFile("/tmp/obj.dat", "a+");
            readRowData(fp, tabfp, pdb, 0, obj);
            break;
        default:
            break;
    }

    fclose(tabfp);




}

三,数据展现

    tab$数据展现

c语言进阶-利用c语言解构oracle底层数据(不开库)-读取字典表tab$,col$表和obj$表_第2张图片

    obj$表数据展现

c语言进阶-利用c语言解构oracle底层数据(不开库)-读取字典表tab$,col$表和obj$表_第3张图片 

    col$表数据展现

c语言进阶-利用c语言解构oracle底层数据(不开库)-读取字典表tab$,col$表和obj$表_第4张图片 

 

你可能感兴趣的:(C/C++,Oracle,深入学习,oracle,数据库,c语言)