汤敏丽
(凯里学院,贵州 凯里 556011)
基于MySQL数据库的物理存储格式的研究与解析
汤敏丽
(凯里学院,贵州 凯里 556011)
M ySQL数据库是一个开源的数据库.M ySQL以其小巧灵活著称,其内部代码都是开源的,使用M ySQL不仅仅可以节约开发成本,而且还可以从开源的代码中学到很多开发精髓.为了更好的了解mysql的物理存储结构,我们直接研究了M ySQL数据库的内核代码.本文主要是讲解MySQL数据库是物理存储格式以及如何进行数据解析.
mysql;物理存储格式;解析
随着计算机开源技术的不断发展,目前开发者越来越热衷于使用开源软件.基于开源的软件的实现的所有代码全部对外公开,且所有人员均可对开源软件进行自定义的修改.这无疑是软件开发界的福音.本文重点研究的MySQL数据库也是开源的数据库软件.同样,它的所有代码也都是开源的.
MySQL数据库是一种关系型数据库管理系统.它不是将所有数据存放到一个大仓库内,而是将具有一定意义的数据相对独立的存放到不同的表中.而表与表之间建立关联关系.它由于其体积小,速度快,成本低等特点,成为很多中小型网站的绝佳选择.MySQL是使用C/C++编写的,并使用了多种编译器进行测试,保证源代码的可移植性.还可以处理拥有上千万条记录大型数据库.
MySQL数据库的一个显著的特点就是插件式的表存储引擎.它的好处是:每个存储引擎都有各自的特点,能够根据具体的应用建立不同的存储引擎表.在windows下,默认使用InnoDB的数据存储引擎.如果你的表只有*.frm文件,则存储引擎是innodb.同样,*.frm这个文件也是表定义文件,数据信息和索引信息放在ibdata1文件里.Ibdata1是InnoDB存储引擎默认情况下的共享表空间文件,即所有的数据都放在这个表空间内.本文主要是针对MyISAM存储引擎做解析.MySQL的体系结构图如图1所示.
图1 MySQL的体系结构图
安装MySQL.打开mysql后输入密码.执行如下的语句:
创建数据库maqianli
mysql>Create database maqianli;
更改数据库
mysql>Use maqianli;
创建表
mysql>create table mytest(t1 varchar(10),t2 varchar(10),t3 char(10),t4 varchar(10));
往表中插入数据
mysql>insert into mytest values('a','bb','bb','cc');
mysql>insert into mytest values('d','ee','ee','fff');
这样我们会发现在MySQL的安装路径下data目录下生成了一个maqianli的文件夹,mysql文件夹是系统安装时默认生成的.在maqianli文件夹下有一个mytest.frm的文件.这个文件中记录了mytest表结构定义的信息.和data同层的有个ibdata1文件,里面记录了表数据信息.我们生成的文件默认是InnoDB存储引擎生成的,我们可以将其改变为MyISAM存储引擎.用如下语句
mysql>alter table mytest engine=myisam;
我们发现在MyISAM存储引擎下,会生成如下三个文件.Frm扩展名结尾的是表定义文件.Myd扩展名结尾的是数据文件,myi扩展名结尾的是索引文件.
图2 MyISAM存储引擎生成的文件
3.2.1 下载MySQL源码.下载地址是:http://www.mysql.com/downloads/mysql/文件名是mysql-5.5.12.tar.gz.
3.2.2 生成工程文件
安装CMake软件,下载地址是:http://www.cmake.org.然后安装 Bison:下载地址是 http://gnuwin32.sourceforge.net/packages/bison.htm.安装完成后,运行CMake.第一个edit里面选择源文件目录,第二个选择要生成的目录.下面的“Configur“e按钮可以选择你要生成的编译环境的版本,我们选择VC6作为我们的开发环境,然后点击“Generate”就开始生成工程文件.这样就生成了MySQL.dsw的工程,我们打开这个工程,然后搜索读取frm文件的主要内容及其其他相关代码.
MyISAM存储引擎一个表生成了3个文件,扩展名分别是.frm,.myd,.myi.Frm扩展名结尾的是表定义文件.Myd扩展名结尾的是数据文件,myi扩展名结尾的是索引文件.下面我们一一介绍三个文件的文件格式.
在源码中我们能够找到FRM创建文件的代码,sql/table.cc,create_frm()里记录了如何创建一个FRM文件的详细过程.open_table_def函数是读取frm表定义信息的函数.其中调用了open_binary_frm函数是其主要的实现关键.该函数在sql able.cc文件里.函数原型如下:static int open_binary_frm(THD*thd,TABLE_SHARE*share,uchar*head,File file).在sql able.cc创建frm的文件的函数create_frm.函数原型如下:
create_frm(THD*thd,const char*name,const char*db,const char *table, uint reclength, uchar *fileinfo,HA_CREATE_INFO*create_info,uint keys,KEY*key_info)
下面我们罗列出FRM文件格式.由于文件中每个字节所代表的含义很多.所以我们只罗列关键字节含义.
表1 FRM文件格式
由上表我们可以看出,FRM文件里面存储了MySQL版本,存储引擎名,列等等信息.由于我们只是读取表中字段,我们只需要关注相关信息即可.
表列信息:由表可以发现,从2152开始记录了表列头信息.根据我们对照生成frm的原始文件和上表格式,发现2152记录的是第一个列名的大小,紧接着记录的是列名,其次空了三个字段又是列名大小+列名.如下所示:
图3 MYTEST.FRM文件二进制格式-列信息
“06”表示的是sname的长度,后面的“05”表示的是ssex的长度.图3中的2102处记录了列数.有了列数,有了列信息,我们就很容易得读出表的列信息.
表行信息:图3中2168字节处记录了表行的字段类型,由于一个表可能有很多列.每列的类型都有可能不同,所以结合图3,读源码,和我们生成的原始文件做了如下分析:
图4 MYTEST.FRM文件二进制格式-行信息
红色标记的是记录的字段大小信息,蓝色标记记录的是字段类型信息.我们创建表的时候sql语句是:create table info(sname char(3),ssex char(2),sclass char(3));可以看出sname是char型,大小为3.ssex是 char型,大小为 2,sclass是char型,大小为3.和我们刚分析的一致.
综上所述,我们知道的信息有:列数,列名,字段大小,字段类型.
MYI文件格式比较复杂,下面是一部分myi格式的信息,我们在读文件的时候只使用了行数这个信息,读myi文件的代码我们直接用的是mysql的源码:
我们读源码,得知在0033字节记录了行数信息.源码中保存在了MI_STATUS_INFO结构体中的records成员里.MySQL读写MYI文件的函数在storagemyisammi_open.c文件里,函数原型分别是:
uchar*mi_state_info_read(uchar*ptr,MI_STATE_INFO*state);// 读
uint mi_state_info_write(File file,MI_STATE_INFO*state,uint pWrite);// 写
由于任务要求只读出表字段便可,我们对这个文件的其他key信息没有关注.仅仅通过MYI文件得到了行数信息.
表2 MYI文件格式
得到了上面所有的行列信息,下面我们开始根据这些信息,找到字段值信息.Myd文件可以分为固定大小字段格式和可变大小字段格式,目前我们只研究了固定格式的.可变大小字段格式的需要根据总大小和未使用大小信息相减得到所用的大小来读取字段值.
由于myd需要根据数据类型的格式来确定每个字节的信息.下表我们只是罗列出第一列为int型,第二列为char型的格式.其他格式类似:
表3 myd文件格式
MySQL中支持很多种类型,这些类型在include/mysql_com.h里枚举enum_field_types定义.每种类型所占用的字节数不同,int为4位,char为1位.Float为4位,double为8位等等.
我们读取MYD文件的时候,跳过第一字节后就开始记录字段值信息了.如果为int型,我们读4个字节的信息,如果为char型,我们读取(1*字段大小)字节个信息.
本文我们主要分析了MySQL数据库的物理存储格式,由于MySQL是可插入的存储引擎方式,本文重点研究了MyISAM存储引擎的物理存储格式.其他存储引擎物理存储格式的研究与本文方法类似,都是需要查看MySQL的开源代码和相关文档介绍.
〔1〕Baron Scbwartz,王小东,等.高性能 M ySQL(High Performance M ySQL).电子工业出版社,2010.
〔2〕张萍.M yISAM存储引擎的分析与改进[A].全国第20届计算机技术与应用学术会议(CACIS?2009)暨全国第1届安全关键技术与应用学术会议论文集(下册)[C].2009.
〔3〕鲍丽春.可插式数据存储引擎:M ySQL走向企业级的保障[N].计算机世界,2007.
〔4〕姜承尧.MySQL技术内幕-InnoDB存储引擎.机械工业出版社,2011.
〔5〕顾治华,忽朝俭.MySQL存储引擎与数据库性能[J].计算机时代,2006(10).
〔6〕M ichael Kofler, 杨晓云, 等.MySQL5权威指南(The Definitive Guide to M ySQL5).人民邮电出版社,2006.
〔7〕马永成,肖诗斌,王弘蔚,施水才.M ySql嵌入式存储引擎的研究和实现[A].第三届全国信息检索与内容安全学术会议论文集[C].2007.
TP3-05
A
1673-260X(2012)07-0028-03