直读Innodb datafile
这两天有空翻了翻大神写的《innodb存储引擎》,手痒亲身实践。由于此书出版了有段时日,没有用其推荐的python工具,通过点滴推敲,略微发现其中冰山一角的奥秘。对于今后对于一些问题查证或数据迁移可能会有帮助。话不多说,开码。
·大结构
innodb数据文件按照 :【segment,extent,page,row】层次来组合,中文解释就是【段、区、页、行】。
4大元素之间的关系:
Segment=N*[Extent];
Extent=64*Pages;
Page=16KB(Low-Level fs+Page Header+VarcharLength+Data);
Low-Level fs=38 Bytes;
Page-Header=78 Bytes;
Page-Header=【Page Header+虚拟记录mum】
Data=16*1024B-38B-78B-VcharLength
ibd文件由段组成,段有extent可以按需扩展,truncate能回收空间,但delete只做清零处理。
extent扩展inndo有自己的经验算法,这块代码还没找到,理论是1-4M,但实际有出现扩从512K突增到9M的情况。有64个PAGE组成。
Page大小16K,也就是16384个字节。按16进制,UltraEdit下步长起点如下:0000-4000-8000-C000
Page按代码由3部分组成,逻辑上PageHeader对infimum和supremum有拆分。也可以说是4部分组成。后面会讲。
·小结构
段和区都为固定功能且可以单调递增,暂不做解释。主要讲一下Page和Row。Row走最常见的compact格式,compact本质取消了一定规则内存对齐操作。
Page的构造如下:
这些结构体的文件系统底层定义在$MYSQL_SRC/storage/include/fil0fil.h中可以查到,主要这两个字段在分析中比较有用:
- Offset :记录着Page的偏移,也就是我这页是第几个页。
- Prev和Next:页的双向链表,实际存的不是指针,就是Offset的值。
- Type:帮助你了解这个页是干什么的。0x45bf,代码中是17855十进制。该值为最典型的数据PAGE。
- Space_id:这个表的ID,作为dict的唯一关联。
- LSN:在备份和恢复时非常有用,有助于定位问题。
再往下看,就是PageHeader。它的定义在$MYSQL_SRC/storage/include/page0page.h中可以查看
从0xc0205的0×0046 space_id开始算起,如上图所示,是所有page_header的定义和长度。这些定义主要是围绕了记录数的起始、大小、长度、位置等做的一些统计信息。
注意图中的3条红色虚线,它们分别指出了具体记录的起点和结束位置。这个位置是相对ROW_ID为基础的。
PAGE_HEAP_TOP:记录整个记录导出到buf堆时最后的指针停留位置,像上图中就是c000+00ec=c0ec。
PAGE_LAST_INSERT:记录着这个PAGE中最后一条记录的起始位置,像上图中就是c000+00be=c0be。
INFIMUM虚拟行记录头:记录着第一条记录的起始位置,像上图中就是c063+0023=c083。
另外,PAGE_N_RECS:记录着这个页中包含着多少条记录等等。通过这样1头1尾定位了所有的记录框架。
上图就是与我们记录完全翻译的16进制解码,下图是原始记录。
对于Row的字段定义在$MYSQL/storage/rem/rem0rec.cc和row0row.cc中有明确解释。
第一条记录全字段都被填满了,所以varchar_length预留了3个字节分别表示了t2,t3,t4存储的字符长度。
空值判断预留了1位。这个比较有意思,该值是一个bitmap。这两段实现可以rem0rec.cc中查到。
1个字节可以展示8个字段空与非空。2个字节就能支持到16个字段,以此类推。空了填1,不空填0,从右往左为视觉字段顺序。
Row_ID:默认行记录key表示。再跟交易trx_ID和回滚指针。
再往后就是varchar的变长真实数据和char的预留数据,char的预留数据为0×20空格,不是0。这个比较奇怪。
图中红、黄、绿分别代表了3条不同的记录,与其自身下图select对应。
至此,我们就可以对整个IBD文件进行了初步解析。
最新文章
- [ZigBee] 1、 ZigBee简介
- HttpClient 3.X 4.3 4.x超时设置
- CE选择目录对话框(转)
- Node.js建站笔记-使用react和react-router取代Backbone
- Luence简单实现1
- android4.0访问不能网络解决方法
- ASP.NET Mvc开发之EF延迟加载
- 百思不得其解—这些年做Web开发遇到的坑?
- 04_XML_02_XML语法
- Response.Redirec方法传递汉字出现乱码
- 粗谈shell脚本风格
- vue 从入门到精通(二)
- leetcode算法题1: 两个二进制数有多少位不相同?异或、位移、与运算的主场
- js网页判断移动终端浏览器版本信息是安卓还是苹果ios,判断在微信浏览器跳转不同页面,生成二维码
- centos 7 network.service control process exited
- Jmeter参数化的方法
- ES系列三、基本知识准备
- windows的网上邻居
- android-------高德地图两点路线和多个点路线绘制
- 小峰servlet/jsp(5)jsp自定义标签
热门文章
- 为什么OC语言很难
- zoj 3696 Alien&;#39;s Organ(泊松分布)
- Linus Torvalds来自开发商的消息:成就,不定
- hdu3037Saving Beans
- Think in Java(一):Java基础
- 3.1、Eclipse
- javascript小白学习指南0---1
- POJ 1026 Cipher(更换)
- UNIX网络编程卷1 server编程范式0 迭代server
- eclipse+Java2WSDL+WSDL2Java 2012-12-06 12:32:43| 分类: j2ee |报道|字体大小 认购 一、eclipse如何使用低axis生成wsdl 可以使用