C语言版Mysql存储块(page)格式读取工具(源代码)

本文详细介绍了使用C语言实现的Mysql存储块式读取工具源代码,包括如何通过指针进行数据读取和转换。通过分析程序输出的日志,了解了文件大小、页面偏移量、页面类型、表空间ID和页面层级等关键信息。特别关注了第75页块的状态变化,揭示了空白块的特征。

C版本的Mysql存储块格式读取工具源代码如下:

其中mysql块存储采用大端字节,所以需要做一定的转换,C语言指针强力转换方式如下:

#include <stdio.h>
#include <stdlib.h>

int readpage(unsigned char * page_hdr,int page_off,FILE *fd) {
  int ret = -1;
  if((ret = fseek(fd,page_off,SEEK_SET)) != 0) {	//fseek error may not be caught successfully here
    printf("fseek failed\n");
    exit(-1);
  }
  printf("now from our calclation page_off is %d\n",page_off);
  if(!(ret = fread(page_hdr,62,1,fd))) {
    printf("read page failed! ret is %d\n",ret);
    return -1;
  }
  return 1;
}

int main() {
  unsigned char page_hdr_tmp[62];
  unsigned char * tmp;
  unsigned int page_offset = 0;
  unsigned short page_type = 0;
  unsigned int tab_space_id = 0;
  unsigned short page_level = 0;
  int ret = -1;
  int page_count = 0;
  int filesize = 0;
  FILE *fd;
  if(!freopen("C:\\MinGW\\bin\\log.txt", "w", stdout)) {
    printf("log file created failed!\n");
  }
  
  if(!(fd = fopen("C:\\MinGW\\bin\\payment.ibd","rb"))) {
    printf("fopen failed!\n");
    return -1;
  } 
  if((ret = fseek(fd,0,SEEK_END)) != 0) {
    printf("fseek failed\n");
    exit(-1);
  }
  filesize = ftell(fd);
  
  printf("filesize is %d\n",filesize);
  
  while (page_count < filesize/1024/16) {
    printf("processing the %d [rd] page\n",page_count);
    if(ret = readpage(page_hdr_tmp, page_count*16*1024, fd)) {
      page_count++;
    } else {
      printf("readpage failed!\n");
      system("pause");
      exit -1;
    }
    //for page_offset
    tmp = (unsigned char *)&page_offset;
    tmp[0] = page_hdr_tmp[7];
    tmp[1] = page_hdr_tmp[6];
    tmp[2] = page_hdr_tmp[5];
    tmp[3] = page_hdr_tmp[4];
    
    //for page_type
    tmp = (unsigned char *)&page_type;
    tmp[0] = page_hdr_tmp[25];
    tmp[1] = page_hdr_tmp[24];
    
    //for tab_space_id
    tmp = (unsigned char *)&tab_space_id;
    tmp[0] = page_hdr_tmp[37];
    tmp[1] = page_hdr_tmp[36];
    tmp[2] = page_hdr_tmp[35];
    tmp[3] = page_hdr_tmp[34];
    
    //for page_level
    tmp = (unsigned char *)&page_level;
    tmp[0] = page_hdr_tmp[61];
    tmp[1] = page_hdr_tmp[60];
    
    printf("page_offset is %d\n",page_offset);
    printf("page_type is %x\n",page_type);
    printf("tab_space_id is %x\n",tab_space_id);
    printf("page_level is %x\n\n",page_level);
  }
  fclose(fd);
  system("pause");
  return 0;
}

我们打开程序输出的log来看,信息如下:

filesize is 10485760
processing the 0 [rd] page
now from our calclation page_off is 0
page_offset is 0
page_type is 8
tab_space_id is 11
page_level is b

processing the 1 [rd] page
now from our calclation page_off is 16384
page_offset is 1
page_type is 5
tab_space_id is 11
page_level is 0

processing the 2 [rd] page
now from our calclation page_off is 32768
page_offset is 2
page_type is 3
tab_space_id is 11
page_level is 0

processing the 3 [rd] page
now from our calclation page_off is 49152
page_offset is 3
page_type is 45bf
tab_space_id is 11
page_level is 0

其中page_type的45bf代表的是索引节点。而page_level是0,意思是,索引节点的层级为0。

到了第75 [rd]块的时候,所有块都是空白块了。

processing the 74 [rd] page
now from our calclation page_off is 1212416
page_offset is 74
page_type is 45bf
tab_space_id is 11
page_level is 0

processing the 75 [rd] page
now from our calclation page_off is 1228800
page_offset is 0
page_type is 0
tab_space_id is 0
page_level is 0

processing the 76 [rd] page
now from our calclation page_off is 1245184
page_offset is 0
page_type is 0
tab_space_id is 0
page_level is 0

测试的ibd文件是mysql 5.6自带的sakila库下的payment.ibd。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值