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

本文原创为freas_1990,转载请标明出处:http://blog.csdn.net/freas_1990/article/details/45843615


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。



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。