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

6 篇文章 0 订阅
2 篇文章 0 订阅

最具挑战性的挑战莫过于提升自我。—— 迈克尔·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; i<extnum; i++, pktetb_t++){
        int j;
        ub4 blknums = 0;
        size_t kdbroffset;
        struct ktelocate ktelocate1;

        getExtLocate(&ktelocate1, pktetb_t->ktetbdba);
        pdb->v_db_fieid = ktelocate1.ktefid;
        pdb->v_db_blkid = ktelocate1.ktebid;
        blknums = pktetb_t->ktetbnbk;

        for(j=0; j<blknums; j++){
            ub2 tabnums = 0, allrows = 0;
            pdb = readDBlockHeader(fp, pdb);
            tabnums = pdb->v_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; i<tabnrow; i++){
        ub2 rowoffset = pdb->p_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; j<colhdr[2] + 1; j++){
            collen = readByteArry(fp, coloffset, 1);


            if(*collen == 255){

                if(tab[j-1] == O_NUMBER){
                    printf("the col %2d value is %10s", j, "NULL");
                    fprintf(write, "%10s    ", "NULL");
                } else
                    printf("the col %2d value is %20s", j, "NULL");
                fprintf(write, "%20s    ", "NULL");

                coloffset += 1;
                free(collen);
                continue;
            }else if(*collen == 0xFE){
                coloffset += 1;
                coldata = readByteArry(fp, coloffset, 2);
                truecollen = *((ub2 *)coldata);
                free(coldata);
                coloffset += 2;
                coldata = readByteArry(fp, coloffset, truecollen);

            } else{
                coloffset += 1;
                coldata = readByteArry(fp, coloffset, *collen);
                coloffset += (*collen);
                truecollen = (*collen);
            }


            switch (tab[j-1]){
                case O_NUMBER:
                {
                    long rowdat = blockHexToNumber(coldata, truecollen);
                    printf("the col %2d value is %10ld", j, rowdat);
                    fprintf(write,"%10ld    ", rowdat);
                    break;
                }
                case O_DATE:{
                    char *rowdat = blockHextoDate(coldata, truecollen);
                    if(rowdat == NULL){
                        printf("the col %2d value is %20s", j, "NULL");
                        break;
                    }
                    printf("the col %2d value is %20s", j, rowdat);
                    fprintf(write, "%20s    ", rowdat);
                    free(rowdat);
                    break;
                }
                case O_CHAR:
                    break;
                case O_VARCHAR2:{
                    char *rowdat = blockHextoString(coldata, truecollen);
                    printf("the col %2d value is %20s", j, rowdat);
                    fprintf(write, "%20s    ", rowdat);
                    free(rowdat);
                    break;
                }
                case O_LONG:{

                }
                case O_RAW:{
                    printf("the col %2d value is %20s", j, "RAW");
                    fprintf(write, "%20s    ", "RAW");
                }
                default:
                    break;
            }

            free(collen);
            free(coldata);
        }
        printf("\n");
        fprintf(write, "\n");


    }




}


void readObjectTab(FILE *fp, datablk *pdb){

    FILE *tabfp;


    switch (pdb->v_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$数据展现

    obj$表数据展现

 

    col$表数据展现

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值