MySQL数据库源代码分析及存储引擎的设计

MySQL数据库源代码分析及存储引擎的设计

ID:77232358

大小:1.56 MB

页数:62页

时间:2024-01-05

上传者:笑似︶ㄣ無奈
MySQL数据库源代码分析及存储引擎的设计_第1页
MySQL数据库源代码分析及存储引擎的设计_第2页
MySQL数据库源代码分析及存储引擎的设计_第3页
MySQL数据库源代码分析及存储引擎的设计_第4页
MySQL数据库源代码分析及存储引擎的设计_第5页
MySQL数据库源代码分析及存储引擎的设计_第6页
MySQL数据库源代码分析及存储引擎的设计_第7页
MySQL数据库源代码分析及存储引擎的设计_第8页
MySQL数据库源代码分析及存储引擎的设计_第9页
MySQL数据库源代码分析及存储引擎的设计_第10页
资源描述:

《MySQL数据库源代码分析及存储引擎的设计》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库

南京邮电大学硕士学位论文摘要学科、专业:研究方向:无线数据与移动计算作者:2009级硕士研究生王威指导教师:马明栋教授题目:MySQL数据库源代码分析及存储引擎的设计英文题目:MySQLdatabasesourcecodeanalysisanddesignofthestorageengine主题词:MySQL,数据库,源代码,插件式存储引擎Keywords:MySQL,database,sourcecodes,plug-instorageengine 南京邮电大学硕士研究生学位摘要摘要MySQL是一种关系型数据库系统,相比较其他数据库系统而言,MySQL是目前运行速度最快的数据库系统之一。其优势在于源代码开放,任何人都可以依据GeneralPublicLicense,下载并根据个性化的需求对源代码进行修改。插件式存储引擎是MySQL数据库系统最显著的特色之一,作为数据库服务器中的组件,它负责为数据库执行数据I/O操作,解决了关系型数据库物理层优化这个难题。数据库专业人员可根据数据读取模式的特定需求,来选择专门的存储引擎。不同的存储引擎具有不同的能力,应用程序是与之分离的。本文针对MySQL源代码展开研究,深入分析MySQL内核的设计与实现。论文首先介绍关系型数据库基础知识以及MySQL数据库系统总体架构。然后研究MySQL内核的实现方法,分析代码的核心类和核心算法,重点剖析插件式存储引擎体系结构,介绍两种经典存储引擎:MyISAM和InnoDB。最后开发设计出自定义存储引擎Nanjupt,引擎能够实现表操作、数据操作及索引功能。关键字:MySQL,数据库,源代码,插件式存储引擎I 南京邮电大学硕士研究生学位ABSTRACTABSTRACTMySQLisarelationdatabaseandcurrentlyoneofthemostrapiddatabasewhencomparedwithotherdatabases.ThebiggestadvantageofMySQLliesonitsopensourcecodes,soanyonecandownloaditunderthepermissionofGPLandmodifyitaccordingtopersonalizedrequirements.Plug-instorageengineisthemostobviouscharacterofMySQLdatabasesystem.Asthecomponentofdatabaseserver,itisresponsiblefortheI/Ooperationofdatabase,sothatitsolvetheissueofrelationdatabaseoptimizationonphysicallayer.Databaseprofessionalsselectaspecializedstorageengineaccordingtospecificapplication'srequirementsondatabasereadmode,differentstorageenginesseparatedfromtheapplicationhavedifferentcapabilities.ThisarticlewillopenaresearchbasedonMySQLopensourcecodesandanalyzethedesignandrealizationofMySQLkerneldeeply.Firstly,ourresearchfocusondatabasefoundationofknowledgeandMySQLsystemframework,secondly,itstudiesMySQLkernelmethodandanalyzesthekeyclassesandalgorithm,thenfurtherresearchtheentireconstructionofplug-instorageengine,introducedtwoclassicstorageengines:MyISAMandInnoDB.Finally,customizedstorageengineNanjuptisdesigned.KeyWords:MySQL,database,sourcecodes,plug-instorageengineII 南京邮电大学硕士研究生学位目录目录摘要.......................................................................................................................................................IABSTRACT........................................................................................................................................II第一章绪论........................................................................................................................................11.1课题背景................................................................................................................................11.2研究现状及发展趋势............................................................................................................11.3研究目的和意义....................................................................................................................21.4论文安排................................................................................................................................2第二章数据库系统的分类与架构....................................................................................................32.1数据库系统分类....................................................................................................................32.1.1面向对象型数据库......................................................................................................32.1.2关系型数据库..............................................................................................................42.1.3对象关系型数据库......................................................................................................52.2关系型数据库系统总体架构................................................................................................62.2.1客户端应用程序..........................................................................................................62.2.2查询语句处理..............................................................................................................72.2.3模块协作......................................................................................................................82.2.4RDBMS的结构............................................................................................................92.3MySQL数据库体系............................................................................................................102.4本章小结..............................................................................................................................11第三章MySQL的核心类及其重要算法.......................................................................................123.1MySQL代码目录................................................................................................................123.1.1代码目录结构............................................................................................................123.1.2主要关键目录............................................................................................................123.2MySQL代码的核心类........................................................................................................153.2.1线程类........................................................................................................................153.2.2Item类........................................................................................................................173.2.3表描述类-TABLE......................................................................................................183.2.4Field类.......................................................................................................................193.3MySQL的核心算法............................................................................................................203.3.1Bitmaps-位图..............................................................................................................203.3.2表连接缓冲................................................................................................................213.3.3MySQL排序实现......................................................................................................223.4本章小结..............................................................................................................................26第四章MySQL的存储引擎...........................................................................................................274.1存储引擎概述......................................................................................................................274.2MyISAM存储引擎..............................................................................................................284.2.1MyISAM引擎的特点................................................................................................284.2.2数据文件....................................................................................................................284.2.3索引文件....................................................................................................................294.3InnoDB存储引擎.................................................................................................................334.3.1InnoDB的功能特征...................................................................................................334.3.2InnoDB的架构及代码分布.......................................................................................34III 南京邮电大学硕士研究生学位目录4.3.3InnoDB文件格式.......................................................................................................354.3.4InnoDB记录结构.......................................................................................................364.3.5InnoDB页结构...........................................................................................................374.4本章小结..............................................................................................................................39第五章自定义存储引擎Nanjupt的设计.......................................................................................405.1初始化存储引擎..................................................................................................................405.1.1创建Nanjupt源文件.................................................................................................405.1.2把Nanjupt存储引擎加入到MySQL服务器..........................................................405.1.3编译Nanjupt存储引擎.............................................................................................415.2表操作..................................................................................................................................435.2.1修改头文件ha_nanjupt.h..........................................................................................435.2.2修改类文件ha_nanjupt.cc........................................................................................435.3索引功能..............................................................................................................................465.4本章小结..............................................................................................................................50第六章结束语..................................................................................................................................516.1课题研究总结......................................................................................................................516.2进一步研究方向..................................................................................................................52致谢....................................................................................................................................................53参考文献............................................................................................................................................54IV 南京邮电大学硕士研究生学位第一章绪论第一章绪论1.1课题背景在众多的开源数据库管理系统中,MySQL数据库是其中最主流的产品。该数据库是关系型数据库管理系统的一种,关系型数据库不是将所有数据放在一个大仓库内,而是将数据保存在不同的表中,如此就加快了运行速度并且提高了存储灵活性。MySQL使用结构化查询语言SQL,是用于访问数据库最常用的标准化语言。MySQL由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,从微型的嵌入式系统到中小型的Web网站,至大型的企业级应用都可以见到其身影,大多数人都认为在不需要事务化处理的情况下,MySQL是管理内容最好的选择。[1][2]由于MySQL是开放源代码的,因此用户可以在GeneralPublicLicense的许可下随时下载,并根据特定的需要对代码进行修改。MySQL5.0发布之后,MySQL已经完全支持存储过程,但是MySQL目前没有自己专用的存储引擎。MySQL与其他数据库最大的区别就是使用可插取的存储引擎,它根据特定的需求利用不同的存储引擎技术把特定的数据存储在文件或者内存中。MySQL有多种存储引擎:MyISAM、InnoDB、MERGE、MEMORY(HEAP)、BDB(BerkeleyDB)、EXAMPLE、FEDERATED、ARCHIVE、CSV、BLACKHOLE。可以采用内存存储引擎存储临时数据,采用事务存储引擎来完成事务处理,相对于其它的一些数据库系统,能够灵活的选择不同的存储引擎来存储和检索数据,对于用户来说是十分受欢迎的。1.2研究现状及发展趋势随着开源产品的流行,开放源代码的数据库系统得到越来越广泛的应用。MySQL、[3][4]MaxDB和PostgreSQL是目前主要的开源数据库产品,其中以MySQL最为普及。MySQL关系型数据库的第一个Windows可使用版本发行于1998年1月,它使用多线程机制,提供完全的多线程运行模式,并且提供了面向C、C++、Perl、PHP、Eiffel、Java、Python和Tcl等等编程语言的编程接口;能够支持多种字段类型,并且提供了完整的操作符支持查询操作。基于MySQL的新应用程序在4.0版本中获得了更加广泛的应用,在这个版本中将有以下新的特性被提供:新的表定义文件格式、高性能的数据复制功能、更加强大的全文搜索[5][6]功能,并对ANSI92/ANSI99标准完全兼容。MySQL5.0版本出现之后,MySQL数据库1 南京邮电大学硕士研究生学位第一章绪论的功能越来越多样化,并逐渐向企业级市场拓展,凭借其优异的可移植性和价格优势,MySQL的市场正在扩大。在不久的将来,在中小企业用户市场的推动下,MySQL数据库有望走向应用的主流。1.3研究目的和意义MySQL最大的用户群是Web站点。MySQL之所以能成为Web站点开发者最常使用的数据库管理系统,是因为MySQL数据库的安装配置都非常简单,其使用过程中的维护也不像很多大型商业数据库管理系统那么复杂,而且其性能出色。MySQL数据库的插入和查询都非常高效,在使用MyISAM存储引擎的时候,二者可以做到互不锁定,具有很高的并发性能。所以,对需要大量插入和查询日志记录的系统,比如处理用户的登录日志和操作日志的时候,都是非常适合的应用系统。嵌入式环境对系统最大的限制是硬件资源非常有限,在嵌入式环境下运行的软件系统,必须是轻量级低消耗的软件。MySQL在资源方面的使用伸缩性非常大,它可以在资源非常充裕的环境下运行,也可以在资源非常少的环境下正常运行。对于嵌入式环境来说,它是一种非常合适的数据库系统,而且MySQL有专门针对嵌入式环境的版本。1.4论文安排论文共分六个部分。第一章主要介绍本课题的研究背景以及研究的意义和目的。第二章概述数据库系统的分类、关系型数据库系统架构、MySQL数据库系统架构以及MySQL各个子系统之间的联系。第三章深入分析MySQL源代码,剖析MySQL的核心类和核心算法。第四章重点研究MySQL插件式存储引擎体系结构,并阐述两种经典存储引擎MyISAM和InnoDB。第五章设计出自定义存储引擎Nanjupt。第六章总结与展望,总结本文所做的工作,并展望未来的研究方向。2 南京邮电大学硕士研究生学位第二章数据库系统的立体视图第二章数据库系统的分类与架构2.1数据库系统分类2.1.1面向对象型数据库面向对象的概念首先是在程序语言的设计中提出的。“面向对象”将客观世界看作由不同种类的许多对象构成的,是一种认识客观事物的方法和对客观事物的模拟。每一个对象都有着自己的内部机理和作用规律,各个对象之间的联系和相互之间的作用就构成了完整的客观世界。面向对象的方法学引入的对象、方法、实例、继承性、类以及封装性等一系列概念,为我们设计和实现大型软件系统打下了坚实的理论基础和操作可行性。在数据库系统中应用面向对象技术,既是数据库系统发展的需要,也是面向对象技术和数据库技术发展的必然趋势。面向对象技术在数据库系统中的应用在两个方面:数据库管理系统和数据库应用开发工具,即面向对象数据库管理系统和开发面向对象的数据库的应用工具。面向对象数据库系统是一种持久可用并且可以共享对象库的存储器和管理器,而对象库是面向对象模型所定义对象的集合体。由于是基于面向对象的思想,所以这类数据库系统也有封装、类、类层次、消息等概念。面向对象型数据库系统在存储和读取数据时,采用面向对象的形式,即操作的数据为对象。这类数据库系统较好的完成了面向对象系统的数据持久化工作。然而,由于缺少较好的查询语句,这些系统一直没有得到很广泛的运用,在市场上只占相当小的份额。面向对象数据库主要用于存储彼此没有内在联系的数据对象。面向对象的数据库系统使人们可以使用某种程序设计语言去直接访问这种程序设计语言所定义的数据对象,还使人们可以在无需进行格式转换的情况下把这类对象存储在数据库里,这有助于保持有关对象的原来格式。这点是在关系型数据库系统里无法做到的,关系型数据库系统里的数据只能被存放在结构化的关系表里。在工程设计系统中,面向对象数据库系统被广泛的应用。工程设计本身是在不断变化的,不断的纠正错误或者修改设计会使设计更加的完美,这是工程设计系统的特征之一,而当设计者对问题及其解决方案有更深刻的理解的情况下,设计者也会选择修改数据库模型。如果采用关系型数据库,意味着随时都要改变表结构。经过多年的开发、研究和应用,面向对象数据库当前的状况是:3 南京邮电大学硕士研究生学位第二章数据库系统的立体视图(1)对面向对象数据库的核心概念逐步取得了共识,标准化的工作也已经逐步展开;(2)随着核心技术问题的得到逐步解决,外围应用工具正在开发,面向对象数据库系统正在走向试用阶段;(3)担忧仍然存在,主要针对性能和形式化理论。由此可以看出,面向对象数据库系统在实际应用中仍然面临着各种新技术问题的挑战。2.1.2关系型数据库关系数据库,是建立在关系数据库模型基础上的数据库,借助于集合代数等概念和方法来处理数据库中的数据。现实世界中的各种实体以及实体之间的各种联系均用关系模型来表示。关系型数据库基于表的特性,大大方便了用户使用查询语言(SQL)进行查询、插入、删除和修改等操作。关系型数据库是建立在严格的数学理论基础上的,它采用简单的表结构,使许多厂商较容易地开发出产品来。关系型数据库系统总结起来有如下优点:(1)应用灵活性且易于建库:一方面,从软件设计的长远角度来分析,关系数据库的编程接口对于用户来说是易于实现的。当前,由于大多数的数据库管理系统使用标准话查询语言SQL,因此用户能够在不同的产品之间存储和提取信息,使用的方法几乎没有差别。同时,外围应用软件采用相似的程序访问机制与关系型数据库接口,并且提供大量标准的数据存取方式。(2)结构简单:另一方面,从数据建模的角度来分析,关系数据库拥有相当简洁清晰的结构,因此可为用户或程序提供多个复杂的视图,这样,数据库的设计和规范化过程将变得简单易行和易于理解。由于关系数据库多方面的功能,已经实现了支持大量的数据库应用。相应的,关系型数据库也存在先天性的缺点:(1)数据类型单一。这是由关系型数据库的前提决定的。从理论上看,关系数据库模型不能直接支持复杂的数据类型,这是由于关系型数据库的大前提——第一范式的要求,所有的数据必须转换成简单的类型,如整数、实数、双精度数和字符串。因此,目前大多数的RDBMS产品已成熟的应用于商业系统,因为这些领域不要求很高和很复杂的数据模型。从下一代应用软件的发展方向来看,关系型数据库的最大缺陷是,缺乏针对不同应用构造与之相适应的数据类型。这种能力的缺乏将会导致有害的结果:比如,大多数数据库4 南京邮电大学硕士研究生学位第二章数据库系统的立体视图管理系统采用简单的数据类型,但是在重构复杂数据的过程中将会出现性能问题;数据库开发过程中额外添加的复杂性;数据库管理系统和编程语言在数据类型方面的不一致。对于工程应用来说,这样的缺陷尤为明显,由于不能够支持复杂的数据类型,其典型结果就是需要额外的工作来分解复杂数据的结构,这些数据被分解之后,其结构不能直接表示为现成的应用数据,而且基本成分重构的工作也非常繁琐。(2)复杂信息查询繁琐。关系型数据库系统的优点是用SQL语言为数据查询提供很好的方法,但是在查询复杂信息时过程将会十分繁琐,这时优点会变成它的不足。除此之外,通常情况下,在工程应用中数据规范化的过程都会产生大量的简单数据表,这时查询操作需要处理大量的表和繁琐的码连接运算。除非这些查询以固定的例行程序方式提供,否则用户就必须对SQL非常熟悉,以便适当的浏览数据库,查出所需的信息。然而,一旦查询方式按固定例行程序进行,用户最终就要进行应用软件的常规维护。但应用或人机接口软件的变化有可能要求经常修改例行的查询,数据库结构的变化也可能导致例行查询程序以及应用或人机接口软件的失效。在出现以上各类情况时,关系型数据库系统的维护开销将会变的十分巨大,而关系型数据库无法提供足够的构造能力及性能,因此在设计较为复杂的数据库系统过程中,无法将工程类问题直接分解成简单的表。同时,由于缺少指针直接存取方式,所以查询相关的信息时需要花费更多的时间。(3)缺乏环境应变能力。在设计不同的程序时,经常发生需要系统环境不断更换,例如前文所提到的工业设计系统,其关系系统成本高且修改困难。关系型数据库管理系统不容易支持模式的演变,而这种功能在工程应用的实现中是十分重要的。此外,如果关系型数据库和编程语言提供了不一致的数据类型,那么在环境转换的过程中将会需要增加多至30%的额外代码。2.1.3对象关系型数据库是将关系型数据库技术引入面向对象技术,融合在一起之后就成为对象关系型数据库。对象关系型数据库既支持SQL存取和查询功能,并且增加了基本数据类型的数量,增加了对复杂对象的继承性并实现对规则系统的支持等等,因此在对复杂数据类型和复杂查询操作过程中,关系对象型数据更加适合。虽然在存储数据时,它成为对象型数据库的一种可替代方案,但它并未能够从根本上解决问题。归纳起来,目前的关系型数据库大多都支持[7]面向对象的概念,在MySQL中,也引入了OpenGIS的支持。5 南京邮电大学硕士研究生学位第二章数据库系统的立体视图2.2关系型数据库系统总体架构RDBMS是存储和获取数据的功能集合,它支持大量的用户同时读或者写同一份数据。因此DBMS需要合理的处理并发情况。只有采用了缓冲技术的DBMS才能提供大并发量下的快速访问。并发访问要求数据库系统的内存管理系统采用类似于操作系统的虚拟内存管理方式和算法。在网络方面,DBMS的网络协议被设计成能够高速的解析客户端的查询。DBMS是一个庞大的系统软件,其众多的子模块相互协作并实现DBMS繁多且复杂的功能。不同的DBMS功能也不尽相同。大型系统功能完备,小型系统则常常对系统功能做了剪裁。DBMS主要的功能模块如图2-1所示。图2-1DBMS的基本功能模块2.2.1客户端应用程序大部分DBMS的客户端应用程序作为一个独立的可执行文件,通过网络连接到DBMS,而有些客户端通过接口连接到DBMS,此时数据库系统成为系统的一部分。在这种情况下,则称为嵌入式数据库系统。[8]在通过通信方式连接DBMS的系统中,大部分采用通用的连接器,例如ODBC。[9]MySQL还支持JDBC和微软的.NET方式连接。不管采用何种连接方式,客户端应用程序都是要发送命令到数据库系统且获得命令的执行结果集。如图2-2所示,客户端通过ODBC连接器发送命令,而ODBC驱动程序通过定义好的网络协议将这些命令发送到数据库服务器。6 南京邮电大学硕士研究生学位第二章数据库系统的立体视图图2-2客户端与服务器的通信机制2.2.2查询语句处理当数据库系统运行在一个客户机/服务器模式下时,数据库服务器负责处理客户端所提出的查询和将结果集返回给客户端。首先由客户端把SQL命令传送至服务器中,然后服务器中的进程将会完成对该语句的解析工作。这个解析的工作是在服务器端完成的,详细步骤如下:(1)语句合法性检查如果数据库服务器的进程无法在高速缓存之中查找到相应的SQL语句,则该进程就会对这条语句进行合法性检查。这里的检查主要是针对SQL语句的语法规则进行的,如果此条SQL语句被服务器进程判断为语句不符合语法规则,那么检查出现错误的信息将会被反馈并发送至客户端。(2)语义检查如果SQL语句经过检查并且没有出现语法错误的话,那么服务器进程下一步的工作是对SQL语句中的字段和表等其他内容进行检查,检查确认这些字段和表是否存在于数据库系统,当表名与列名被检查出有错误的时候,数据库就会反馈错误信息并发送至客户端。因此可得到如下结论,在服务器执行SQL语句的过程中,如果遇到语法与表名同时出现错误的情况,那么系统就会先提示语法出现错误,发送至客户端,在语法修改正确之后,7 南京邮电大学硕士研究生学位第二章数据库系统的立体视图然后再提示表名出现的错误。这种机制和编程语言的编译、连接、执行类似。(3)获得对象解析锁数据库系统的主要的任务之一就是保证大量的并发情况的数据完整性。在检查完语法和语义并都得到正确结果之后,系统接下来的任务就是对将要查询的对象加锁。这样做的目的是为了保障前后数据的一致性,可以防止查询过程中出现的其他用户改变对象结构的现象。(4)数据访问权限的核对经过对语法、语义的检查工作之后,在客户端取得所需数据之前,服务器进程还会检查所连接的用户对这个数据是否具有访问的权限。在应用软件开发调试的过程中可能会经常遇到这样的情况,即连接服务器的用户被服务器进程检查得出并不具有该数据的访问权限,那么客户端就无法取得这些数据。2.2.3模块协作如图2-3所示,描述了DBMS各个功能模块的功能,以及模块如何协同合作。图2-3数据库模块协作图客户端应用程序将SQL语句通过某种通信方式发送到DBMS;DBMS通过接口接受访问和接受语句;将此语句通过内部的“查询处理”模块进行语法、词法检查;根据解析出8 南京邮电大学硕士研究生学位第二章数据库系统的立体视图来的结果,DBMS生成大量查询计划并从其中选取最高效的查询计划;最后执行查询计划,并访问数据存储文件。2.2.4RDBMS的结构RDBMS的层次结构随着数据库管理系统的不同会出现各种差异,图2-4描述了其普遍意义上的层次结构,该图包括了与RDBMS密切相关的各个层次。图2-4RDBMS的层次结构如图2-4所示,位于第一层的是应用层,处于RDBMS的最外层。该层是RDBMS与终端用户和应用程序的接口层,其作用是处理各种各样的数据库外围应用。SQL语言翻译处理层位于系统的第二层。该层的工作是处理的对象为数据库描述语言,通过调用处于下层的基本模块,然后生成可执行代码,生成代码后运行即可完成数据库SQL语句的各类功能要求。其具体作用是对数据库SQL语言的各种语句进行:语法分析、视图转换、权限检查、完整性检查、查询优化等操作。位于第三层的是数据存取层。数据表的单行为该层处理的对象,该层能够把第二层的集合操作转换成为单行的记录操作,具体能够执行扫描、排序、数据查找、插入、修改、删除等一系列基本操作,并且可以完成数据记录的存取、存取路径维护、并发控制、事务管理等工作。9 南京邮电大学硕士研究生学位第二章数据库系统的立体视图位于第四层的是数据存取层。该层的作用是执行文件的逻辑打开、关闭、读页、写页、缓冲读和写、页面淘汰等一系列操作,其操作的对象是数据页和系统缓冲区,并且完成缓冲区管理、内外存交换、外存的数据管理等功能。作为RDBMS存在和运行的基础,操作系统的作用是对物理文件进行读写操作,并且要保证将RDBMS对数据逻辑上的读写能够真实的映射到物理文件上。因此,操作系统处理的对象是数据文件的物理块,它提供的基本存取方法和存取原语通常被用于数据库管理系统的存储层接口。2.3MySQL数据库体系因为MySQL采用的是客户机/服务器体系结构,所以在使用MySQL进行存取数据操作时,必须至少使用两个或者是两类程序:(1)一个是位于存放数据的主机上的程序——数据库服务器。数据库服务器在网络上监听来自客户机的请求,然后根据客户机的这些请求访问数据库数据,访问之后再向客户机提供它们想得到的信息。(2)连接到数据库服务器的程序——客户机,这些程序是作为用户和服务器之间交互信息的工具,并且告诉服务器需要查询信息的内容。MySQL的架构可以描述为层次性子系统组合。MySQL的源代码不是按照单组件或者模块的方式编写的,但是各个层次的源代码还是能够被分离出来,大部分的子系统依赖于一些通用的底层库。MySQL包含以下子系统:网络连接和网络通信协议子系统;线程、进程和内存分配子系统;查询解析和查询优化子系统;存储引擎接口子系统;各类存储引擎子系统;安全管理子系统;日志子系统;mysys核心库文件等。当一个客户端通过网络连接MySQL数据库服务时,网络连接子系统执行一系列的与网络协议有关的底层任务。然后网络连接子系统将控制权交给线程子系统,线程子系统提供一个线程来处理这个连接,这个连接称之为连接线程。随后连接线程得到控制权,它首先调用安全管理子系统来验证用户访问的合法性。连接线程将获得的数据传给控制系统,其中一些请求在内核代码中被称作命令。这些命令中的一部分可以由这个控制系统直接完成,对于不可以直接由系统分发来完成查询的,分发系统将调用解析子系统对SQL语句进行解析。同时,如果在配置MySQL系统时采用了日志功能,那么分发系统还会调用日志系统去记录此次的信息。随后解析子系统将解析结果传给调用优化子系统以优化SQL语句。接着进行表操作,并将一系列请求发往存储引10 南京邮电大学硕士研究生学位第二章数据库系统的立体视图擎接口子系统。存储引擎接口子系统将上述调用自动转化为某个具体的存储子系统方法。上述过程完成后,相应的模块将SQL执行结果发往客户端,最后再由服务器将控制权交给连接线程,连接线程完成某些清理工作,并在此等待客户端的连接或者其他查询,直到客户端输入Quit命令为止,到此本次通话才会结束。2.4本章小结本章先从广义上的数据库系统分类展开,讲述各类数据库系统的特点,随后介绍主流的关系型数据库系统,并描述了典型关系型数据库的内部结构视图,最后以各个子系统为主线,解释了MySQL架构。11 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法第三章MySQL的核心类及其重要算法3.1MySQL代码目录3.1.1代码目录结构打开MySQL源代码文件,可以看到所有的MySQL子文件夹,如图3-1所示:图3-1MySQL源代码目录结构3.1.2主要关键目录MySQL有以下几个主要文件夹:BUILD,clint,storage,mysys,sql,vio。(1)BULID目录BUILD是编译和安装脚本目录,里面有各种平台使用的编译脚本。目录中的文件数目很少,文件也较小,大部分文件名称以compile-开头,compile文件是对MySQL源代码进行各种编译的脚本文件。(2)clint目录clint目录下文件较少,包括mysql.cc,mysqlcheck.c,mysqladmin.cc,mysqlshow.c等文件,是客户端程序所在的目录。在这个目录中还包括了密码确认功能get_password.c、SSL连接12 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法可行性检查等功能。(3)storage目录这个目录包含了MySQL各类存储引擎(storageengine)代码。MySQL实现了一个抽象接口层,叫做handler(sql/handler.h),其中定义了接口函数,比如:ha_open,ha_index_end,ha_create等等,存储引擎需要实现这些接口才能被系统使用。其目录包括:archive、blackhole、csv、example、federated、heap、ibmdb2i、innobase、myisam、myisamrg、myisam和ndb。其中,innobase,innodb的目录,是支持事务的存储引擎,最新版本的默认存储引擎;myisam,是最早的MySQL存储引擎,早期版本的默认引擎。Heap是基于内存的存储引擎;CSV存储引擎的源代码存放在csv目录。(4)mysys目录该目录包含了对于系统调用的封装,其作用是能够容易实现平台间的跨越。Mysys代表MySQLsystemlibrary,是MySQL的库函数文件,即将预先按照可再使用的原则编译好的函数放入同一个集合中,这个集合就是库函数。在mysys目录中,共有125个.c文件,随着系统功能的扩充和升级,库函数也在不断的增大。这些库函数在编译以后在Windows上是.lib和.dll文件,在Linux和Unix上是.so和.a文件。该目录下的库文件包括:mf_qsort.c;mf_tempfile.c;charset-def.c;charest.c。其作用分别是用于快速排序;用于临时文件的管理;定义客户端编译时,采用的字符集类型;字符集加载、初始化等工作。Mysys目录是一个功能库文件的集合,包括文件打开、数据读写、内存分配、OS/2系统特别优化、线程控制、权限控制、RaidTable、动态字符串处理、队列算法、网络传输协议、初始化函数、错误处理、平衡二叉树算法、符号连接处理、唯一临时文件名生成、hash函数、排序算法、压缩传输协议等。(5)sql目录sql目录包含了数据库的主程序mysqld,是MySQL源代码中需要经常变化的目录之一,目前大多数已存在的bug也来自这个目录中的文件。sql目录是MySQL服务器内核最为核心和重要的目录,大部分的系统流程都发生在这里。目录包含mysqld.cc文件,也包含了sql_insert.cc,sql_update.cc,sql_select.cc等各类SQL语句的解析和实现,分别实现了对应的SQL命令。其中sql_lex.cc是词法解析模块,sql_yacc.yy是语法解析模块。lex是一个词法分析程序的自动生成工具。它输入描述构词规则的一系列正则表达式,然后构建有穷自动机和这个有穷自动机的驱动程序,进而生成一个词法分析程序。yacc是Unix/Linux上的一个用来13 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法生成编译器的编译器。这两个文件决定了MySQL如何解析输入的字符流和SQL语句。并最终获得解析树。目录中还包含了存储引擎接口模块的代码。Storage下的各存储引擎目录中,存在的是各类存储引擎的实现代码,而sql目录下存放的是处理接口handler。其关系如图3-2所示:图3-2handler类和各存储引擎实现类的关系各类SQL语句的执行代码也可以在sql目录中找到,此类文件一般以sql_开头:sql_delete.ccdelete语句sql_do.cc操作语句sql_help.cc帮助语句sql_insert.cc插入语句sql_select.ccselect语句sql_show.ccshow语句sql_update.ccupdate操作(6)vio目录vio意思是指virtualI/O,该目录封装了virtualI/O接口,主要是封装了各种协议的网络14 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法操作。virtualI/O使得各种模块的网络协议能够无缝的调用I/O功能。MySQL网络子系统将调用这里的方法。(7)执行流图3-3所示的是一个用户执行SELECT语句之后,MySQL的执行流。图3-3各源代码文件夹的用途如图3-3,该图描述了以上几个主要目录在MySQL提供服务的过程中起到的作用:(1)首先,由客户端应用程序mysql发送一个SQL语句;(2)MySQL服务器通过vio模块收到了网络传输过来的SQL语句;(3)接着,Lex和YACC将SQL语句解析并生成语法树,此语法树最终由底层sql目录中sql_select.cc执行。(2)独立的handler.cc接受到最后的请求,并执行这个语句。(5)Handler依靠storage目录下的具体存储引擎代码和函数读取数据。3.2MySQL代码的核心类3.2.1线程类线程是MySQL中的一个重要概念,其作用是处理来自客户端的连接,线程和连接是1:1对应的关系,线程和THD对象也是1:1对应的关系。如果操作系统本地线程库已实现了优先级功能,那么调用pthread_setschedparam()可以设置优先级,如sql/mysql_priv.h中所定15 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法义,mysqld内的线程可以运行在4个优先级:#defineINTERRUPT_PRIOR10#defineCONNECT_PRIOR9#defineWAIT_PRIOR8#defineQUERY_PRIOR6THD类MySQL线程描述类符,其中包含线程的特征信息。THD类在sql/sql_class.h中定义,由文件sql/sql_class.cc来实现该类。THD类型的对象在各类函数调用和参数中出现,该类由大量成员字段和少量成员方法组成。Statement类是THD类的父类,THD类从Statement类继承成员变量,主要成员变量名称和作用说明如下:Lex的作用是指向当前查询的查询解析树的指针;Query,该变量从Statement类中继承,以字符串的形式记录当前查询;Killed,要将一个进程结束,设置其为true。任何一个线程进行大量耗时工作时,需要经常确认这个变量,如果设置了true,则线程必须马上进行线程清理工作,并退出线程;slave_thread,如果该线程为从服务器线程,设置为true;system_thread,线程不是由客户端请求引起的,设置这个值为2,其他还有从服务器线程、时间安排器、NDB等线程,线程若是由客户端请求引起的,设置该值为0;real_id,该线程在操作系统上的线程号;thread_id,MySQL服务器分配给该线程的id号,使用者通过showprocesslist看到的id列就是thread_id的值;query_ID,内部表示的查询号,查询号以递增的方式进行操作;warn_list,某些查询语句会产生较多警告,这些警告会被保存在这个列表中;db_charset,当前数据库的字符集描述符;user_tables,优化器常常引用这个参数,使用位图方式显示各表的开闭状态;last_insert_id,Autoincrement设置后,MySQL会为每次插入赋予一个值,可以执行Selectlast_insert_ID()来查看最近插入的ID是多少;user_connect,用户连接的限制,MySQL可以设置某个用户能够发起的连接数量和单位时间内执行查询的次数;next_insert_ID,Autoincrement设置后,next_insert_ID就是下次插入时该列的值;server_status,位图型变量,这个状态将发送到客户端;current_statement,预处理语句的描述符,常被设置为0;st_transactionstransaction,事务描述符,用于管理表更新日志;Di,延迟插入的操作符,执行INSERTdelay操作,在数据表被锁时,使得客户端能够插入数据;open_tables,线程所使用表的链表,表为常规表,;handler_tables,线程使用handleropen操作打开的表,Handler命令提供了直接访问底层表存储引擎的机会,这样的访问跳过了优化器的控制;temporary_tables,线程所使用的临时表的链表,临时表的会话时间处于会话期内;derived_tables,线程所使用的衍生表,衍生表由查询语句的子语句生成;lock,MySQL16 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法隐式锁,MYSQL_lock结构体包含了被锁定表的链表,MySQL的许多操作,例如select、insert、update等操作常需要锁定表;locked_tables,MySQL显示锁,使用了locktables命令后,显示锁定的表将被记录在这个结构体内,若设置了这个变量,lock变量值为0;command,当前服务器的命令类型;server_ID,所有参与复制功能的MySQL服务器都被赋予一个服务器ID号,当主服务器执行更新操作的时候,它将原始数据库的ID号记录到二进制日志中去;db_access,定义了当前连接使用的当前数据库对于该客户端有何种权限,该变量同样采取比特位掩码的方式;col_access,变量记录用户执行showtables时,过滤掉没有权限查看的表;master_access,在MySQL权限控制机制中,用户被赋予全局的、库级的、表级的权限;client_capabilities,在网络通信的初始阶段,客户端和服务器端协商双方通信能力时,所使用的描述变量;proc_info,用于描述线程当前进行的状态;host,发起连接的客户端主机名;user,发起连接的客户端传入的认证用户名;priv_user,该变量中保存的变量是通过用户链接时指定的-u变量查询mysql.user表获得;db,当前所在的数据库,未指定时,变量值为NULL;db_length,变量db的长度;ip,发起连接客户端IP的字符串表示;host_or_ip,对IP进行DNS反向查询;packet,用于网络I/O的动态缓冲;Net,客户端连接描述符;protocol,网络通信协议描述符。3.2.2Item类Item是MySQL表达式的核心,用于实现表达式,如查询条目、函数、where、order、group字句等等。Item是一个类,每个Item类的实例都包含:SQL语句成分,如where;一个值;数据类型描述符。Item的成员变量和成员方法如下:str_value,该变量的主要作用是将变量缓存到save_in_field中;name,select语句中的名称;orig_name,如果设置过别名,该变量就是select语句中的别名;Next,Item链表;max_length,Name变量的最大长度;name_length,Name变量的长度;maybe_null,该Item是否有可能会是null;Null_value,该Item是否是null;Fixed,该Item是否由fix_fields设置成固定值;is_autogenerated_name,该Item的名称是否自动生成还是由用户设置;collation,用于字符串排序;with_subselect,该Item是否为一个子查询或包含子查询;cmp_context,上下文比较。在源代码中,以下所有的SQL语句和元素均可作为Item的对象:字符、数据表的列、会话级变量和全局变量、存储过程变量、各类参数、SQL函数以及各类操作符。Item类的定义在sql/item.h里,其大部分子类和子类的子类也在sql目录下,如图3-4所示,Item类17 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法与其子类的继承关系。图3-4Item和它的部分子类3.2.3表描述类-TABLE表类定义了MySQL数据库在内存中的形式,表以打开或者关闭两种形态存在,表在使用时候需要先打开,表描述类在表打开时创建。表描述类创建后置于表缓存中,等待下一个查询的重用,提高访问效率。表描述类的定义在sql/table.h文件中,常在查询解析、查询优化、访问控制和查询缓存代码中被引用,TABLE类的成员及作用如下:Field,由表内所有列组成的数组;file,指针指向表在存储引擎的位置;fields,表内列的数量;reclength,记录长度,这里描述的长度是指记录在优化器中的长度;rec_buff_length,18 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法为操作一个记录而分配的临时缓冲;keys,表内索引的数量;key_parts,数据库中若某列数据是一个索引的组成部分,则称为索引分量;primary_key,主键在索引数组里面的位置;null_fields,可包含null值的列数;blob_fields,数据类型是blob或text列的数量;In_use,使用该表的线程;Frm_version,表定义文件frm的版本号;Query_id,当前使用该表的查询ID。quick_keys,局部优化所使用的索引位图。3.2.4Field类Field类是一个抽象类,用于描述表中的列或者属性,是对列数据类型以及属性的定义,如图3-5所示,Field类有许多的具体子类,几乎每种类型的列都有对应的Field子类。图3-5Field类与其子类Field类在代码文件sql/field.h中定义,并由sql/field.cc部分实现,而其虚函数由其各子类实现。Field类的成员变量及其作用如下:Ptr,数据记录的内存地址;null_ptr,指针指向包含Null字段的记录;table_name,字段所属表;field_name,字段名称;comment,定义该字段时使用的注释;query_id,通TABLE19 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法类一样,查询ID;Unireg_check,字段类型定义,存储在frm文件中;Field_length,该字段能够存储的最大长度;Flags,位图,记录字段定义时的其它选项;key_start,若位图的第n位被设定为1,那么这个字段是第n个索引的第一部分;part_of_key,若位图的第n位被设定为1,那么这个字段是第n个索引的一部分;part_of_sortkey,B树索引使用。除了上述描述的类之外,类LEX、TABLE_LIST、NET、Protocol、JOIN和handler都是关键的类,这些类之间的联系如图3-6所示:图3-6各种类之间存在的关系类LEX、TABLE_LIST、Item和SQL语法分析以及SQL语句的抽象表示,Item用于实现表达式,如查询条目、函数、where、order、group子句等,TABLE_LIST类则用来表达JOIN操作;Protocol类实现数据库服务器和客户端的通信协议,例如构建协议包;NET提供网络支持,如原始数据的读写;TABLE_SHARE表示表的元信息,例如字段定义、索引定义;TABLE代表一个打开的表实例;handler是存储引擎的接口,JOIN是SQL的执行引擎,查询的执行要经历准备、优化、执行几个阶段。3.3MySQL的核心算法3.3.1Bitmaps-位图上一节中曾经提到过位图的概念,比特位图的作用是使用少量的空间而提供大量的信息,Bitmaps可以理解为位映射,举例说明其工作原理:在某个程序中,我们需要8个变量存储一些信息,这8个变量分别是:BooleanisFemale,BooleanisJobless,BooleanisFat,BooleanisTall,BooleanisStudent,BooleanisGraduate,BooleanisBeijinger,BooleanisMarried。一般情况下,这8个变量至少要占用8个字节,但若采用位图,只需要一个字节。位图用一个比特位代表true和false值,上述8个变量可以缩写成01000010,表示的意思该男性目前处于未婚失业状态,户口在北京且无研究生学历。只共占用一个字节,这样不仅节省空间,也提高了处理速度。在MySQL中,mysys/目录下的my_bitmap.c文件包含了各种操作20 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法位图的函数:bitmap_init、bitmap_free,设置和拆除操作;bitmap_set_bit、bitmap_fast_test_and_set、bitmap_clear_all、bitmap_set_all,设置和清理整个比特图或某个具体的比特位;bitmap_cmp、bitmap_intersect、bitmap_subtract、bitmap_union,对两个比特位图进行比较操作。但是目前比特位图仍然存在很多限制:(1)每次系统为位图分配空间时,采用的最小单位是字节,即8个比特位。所以在某些情况下8*n比特不能用完,这样的情况下就无法知道位图的最后几位是否有意义。(2)比特位图的比较操作bitmap_union所操作的两个比特位图必须等长。(3)整个比特位图包含了大量有用的关键信息,多个线程对同一个比特位图变量操作时,要借助于互斥锁的协助,但是互斥锁可能导致线程的串行化。3.3.2表连接缓冲在没有使用表连接缓冲的MySQL服务器上,执行表连接操作:SELECT*FROMt1,t2,t3WHEREt2.key1=t1.collANDt3.key1<40;图3-7说明了在没有使用表连接缓冲的情况下,MySQL执行上述查询语句的流程,其中虚线隔开的列表示表扫描,由实线连接的小块表示表中的行。图3-7执行的流程从上图中可以发现,表tbl2被多次扫描,但每次扫描都是表的不同位置,而表tbl3被21 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法多次扫描,且每次扫描都是一样的内容。表tbl3的第二、第三次扫描是多余的,因为每次扫描并没有带来新的东西,只是做简单的重复劳动。因此,没有必要为每一个新的tbl1、tbl2组合而重新扫描tbl3,而应该先缓存tbl1和tbl2的有效组合,然后对表tbl3只做一次扫描,这个就是表连接缓冲提供的功能,如图3-8所示,采用缓冲之后的新算法:图3-8采用缓冲后的表连接算法3.3.3MySQL排序实现查询语句中包含大量的orderby操作。如何写出高效率的算法也是MySQL和其他数据库努力的方向。排序功能不仅仅用于orderby,groupby中也需要进行排序,MySQL有两类方式进行排序:(1)第一类是使用range、ref、index读写方式,explain的输出range、ref、index是描述对索引列的读取方式。这些方式获得的输出都是按照索引的排序排列的,所以这类方式读取后,就不需要进行排序操作。(2)第二类方式,使用filesort排序算法。filesort算法就是将一组记录或元素按照快速排序算法放入到内存缓存,然后这几个内存缓存按照合并算法排序。filesort算法能够使用的内存数由系统参数sort_buffer_size控制。若被排序数据大于sort_buffer_size,filesort算法会创建一个临时表来存放数据,这样将导致系统性能下降。22 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法filesort的数据通常来自一个表,如果数据来自多个表,filesort的做法就会略有不同。系统首先将多个表中的数据放入到临时表内,然后调用filesort对这个临时表进行操作。filesort的操作模式也有两种,分为直接模式和指针模式。直接模式是指要求排序的数据完全读取,经过排序后的数据就是我们需要的结果;指针模式是排序时,数据或临时表以(sort_key、rowid)的形式存在,按照sort_key排序之后,根据rowid找到数据记录,最后读取需要的数据。结果排序后,包含的所有列是需要的列。MySQL大多数使用直接模式,指针模式只在直接模式不可行时才被采用,当被排序的记录包含Blob等变长字段时,直接模式就不可行。下面以orderby或groupby的join操作为例,说明MySQL如何进行排序。结合前几节描述的算法,对于带orderby或groupby的join操作,MySQL有三种排序执行方法,如表3-1所示表3-1三种排序方法方法Explain的输出1.使用已排序索引Explain不会提及任何filesort2.在表单上使用filesortusingfilesort3.将JOIN结果先放入临时表,然后使用filesortusingtemporary;usingfilesort在第一种方法中,表JOIN操作中的第一个表有索引且索引就是orderby的某一列,且orderby的其他字段也包含在其他表中,那么我们采用该算法。如图3-9所示,图中的不同列表示orderby的不同列。23 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法图3-9使用第一种方法这种方法对比其他的两种方法有明显的优势,索引已经排序完成,所以读出来的数据就不必再经过排序这一步了。当使用的orderby列均在JOIN操作的第一个表上时,MySQL可能会采用第二种方法排序,在这种情况下,MySQL先对第一个表进行排序,然后将排序的表与其他表进行连接。如图3-10所示,先对tbl1进行排序,后将排序好的结果与tbl2、tbl3进行JOIN。24 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法图3-10采用第二种方法排序如果表记录会有Blob等变长字段,那么filesort算法使用指针算法。这时,MySQL的算法如图3-11所示:图3-11filesort算法使用指针算法先将三个表JOIN到一个临时表中,然后filesort算法在这个临时表的基础上进行。25 南京邮电大学硕士研究生学位第三章MySQL的核心类及其重要算法3.4本章小结本章主要介绍了MySQL的代码分及其关键元素:核心类和算法,分析了THD、Field、表描述类、位图等重要概念。在理解了MySQL内核的实现方法的同时,也是本文第一次涉及到源代码,这为下章深入剖析MySQL的存储引擎打下基础。26 南京邮电大学硕士研究生学位第四章MySQL的存储引擎第四章MySQL的存储引擎4.1存储引擎概述MySQL使用各种技术把不同的数据存储在文件或者内存之中,每一种存储技术都能够提供大量的功能,并且拥有各自不同的索引技巧、锁定水平和存储机制。为了能够有效的提高运行的速度,改善应用的整体性能,选择合理的存储技术是很重要的。在MySQL中,这些存储技术以及与之相适应的各种功能被称作存储引擎,也可称为表类型。MySQL本身提供了许多存储引擎。存储引擎的配置方法有很多种,可以选择预先设置,也可以选择适用于服务器、数据库和表的存储引擎,以便能够在存储、检索以及选择所需要的性能时获得最高的效率和最大的灵活性。与其他关系型数据库系统不同的是,MySQL拥有插件式的存储引擎,这也是它最显著的特点。MySQL插件式存储引擎架构提供了一系列标准的管理和服务支持,这些标准是数据库系统本身所必需的,与存储引擎本身无关。图4-1是插件式存储引擎体系结构,存储引擎是底层物理结构的实现,每个存储引擎开发者都可以按照自己的意愿来进行开发。图4-1插件式存储引擎体系结构27 南京邮电大学硕士研究生学位第四章MySQL的存储引擎4.2MyISAM存储引擎4.2.1MyISAM引擎的特点MyISAM存储引擎是通过ISAM功能增强之后得到的,处理非事务安全的表,它能够提供高速的存储与检索,并且具有全文检索的能力。任何一个MyISAM表都被存储在三个文件之中:索引存储在.MYI文件中,数据存储在.MYD文件中,而表的定义则存储在.fm文件中。MyISAM存储引擎有如下特点:数据存储时,低字节置于前面;能够减少行碎片,通过自动合并相邻被删除的块从而实现;引擎的每一个表可以最多有64个索引,而每个索引最多可以建在16个列上,这些可以通过重新编译MySQL来设定;BLOB和TEXT列也可以被索引。被索引的列允许为NULL值;为了能够获得更高的索引压缩,所有数字键的高字节先被存储;AUTO_INCREMENT列在内部处理,MyISAM将自动地更新它,这使得AUTO_INCREMENT列的更新速度更快。序列顶部的值一经删除之后将不会再次使用;AUTO_INCREMENT值可以用ALTERTABLE重新设置。MyISAM表的索引文件里有指示表是否被正确关闭的标志。4.2.2数据文件MyISAM的数据文件存放在以.MYD为扩展名的文件中,其文件格式为数据和元数据相互穿插存储,MyISAM支持三种不同存储格式,分别为静态的、动态的和压缩的。(1)静态表静态表格式是MyISAM表的默认格式。当表中不包含BLOB、TEXT、VERHAR等可变长度的列元素时采用这种格式,表中每一行都采用固定数值的字节数进行存储。在3种存储格式中,静态格式是最简单安全的一种格式,也是磁盘格式中速度最快的,也就是说数据文件中的行能够在磁盘上快速查找到。根据索引中的行号就能够查找行元素,行号和行长度的乘积就是行的位置。而且,当进行表扫描时,磁盘读操作很容易读取行元素的一个常数行号。当MySQL服务器在写一个固定格式的MyISAM文件时计算机崩溃了,myisamchk能够方便的判断每一行的起始和结束的位置,因此能够很容易的重新声明所有的行。静态格式的表具有如下的特点:速度快,易于缓存,系统崩溃后容易重构,因为行的28 南京邮电大学硕士研究生学位第四章MySQL的存储引擎位置固定,比动态格式的表需要更多的存储空间。(2)动态表如果MyISAM表中含有可变长度的列,或者表是由带有ROW_FORMAT=DYNAMIC选项创建的,那么就要用动态存储格式。动态存储格式相比静态存储格式要复杂一些,因为每一行都有一个表名长度的头,如果行元素是作为更新的结果进行存储的话,有可能存储为碎片形式,即不是连续存放的。为了避免行元素被存储为碎片形式,我们可以使用OPTIMIZE或者myisamchk_r命令。如果要存取的表或者反复更改的表中有固定长度的列,为了避免出现碎片行,可以将这些可变长度的列元素移动到另外的表中。动态格式的表有如下特征:所有字符串类型的列都是可变长的,除去长度小于4的列;每一行都有一副位图先说明哪些列中包含空字符串,或者哪些列是0,如果字符串型的列在除去尾部之后长度为0,或者数字型列的值为0,该列就会被标记在位图中,而不存储在磁盘中,非空字符串按照长度加字符串内容存储;动态存储格式比固定长度的表占空间小;每一行的存储仅占用必须的空间,然而,如果行变长了,就会根据需要拆分,这将导致行碎片的产生;在系统崩溃后,比静态格式表的还原要困难;每一个连接可能要占6个字节的空间,当更新操作导致行的长度增大时,系统就会为可变长度行创建相应的连接,每一个新连接至少20个字节,因此下一次行更新有可能使用同一个连接,否则就会创建新的连接,myisamchk-ed命令可以查看连接的数目,所有的连接均可以通过OPTIMIZETABLE或者myisamchk-r命令清除。(3)压缩表压缩存储格式是myisamchk工具创建的一种只读格式,压缩后的表可以通过myisamchk命令解压缩。压缩后的表具有如下特征:占据空间较小,采用压缩表格式,能够占用最小的磁盘空间;每一行都是独立压缩的,因此访问开销很小,根据表中最大行的大小,每一行要有1~3个字节的头,每一列的压缩形式是不同的,通常每一列都有一颗不同的哈夫曼树;压缩表可采用固定长度或者可变长度的行。4.2.3索引文件MyISAM存储引擎的每个表都对应一个索引文件,索引文件包含两部分:头部信息和索引值。(1)头部信息在MySQL术语中,索引即为使用create[UNIQUE]index创建的数据。索引文件以其头29 南京邮电大学硕士研究生学位第四章MySQL的存储引擎部信息开始,记录了该表的索引选项、索引文件大小和索引定义。myisamdef.h文件定义了索引文件的格式,mi_create.c文件通过调用mi_open.c文件去创建索引文件的头部信息,其格式如图4-2所示。图4-2头部信息的格式如图4-2所示,头部代码分为state段、Base段、Keydef段和recinfo段。State段的结构由结构体st_mi_state_info描述,表4-1是对该结构体字段的说明。表4-1st_mi_state_info结构体字段说明变量和结构体成员说明five_versionmyisam_file_magic数组中有定义options表示HA_OPTION_COMPRESS_RECORDheader_length头部信息的长度state_info_lenghMyisamdef.h中定义的MI_STATE_INFO_SIZEbase_info_lengthMyisamdef.h中定义的MI_BASE_INFO_SIZEbase_posBase段在MYI文件中的起始位置key_parts索引若由多个列组成,则其中一列成为索引组成部分unique_key_parts0keysT表中共有两个索引,I1和I2language索引采用的语言max_block_sizefulltext_keys全文索引的数量填充位补全任何未对齐的8位数字state->open_countstate->changed表被更新时设置该值:如果该表被关闭则复零30 南京邮电大学硕士研究生学位第四章MySQL的存储引擎state->sortkey按该索引排序state->state.records表内记录行的数量state->state.del表内被删除的记录数量state->version索引创建时的时间戳state->recover_time上一次恢复时间state->check_time上一次checktable的时间base段的结构在myisamdef.h中被定义成st_mi_base_info,然后由mi_open.c中的mi_base_info_write()将st_mi_base_info结构写入到MYI文件。相应的结构是myisamdef.h中的MI_BASE_INFO结构体。mi_base_info_write先申请一个base结构体大小的缓冲buf,然后将相应的base结构体成员经过处理后写入到ptr指向的buf,最后mi_base_info_write将buf写入到MYI文件file。keydef段的结构被定义为myisandef.h文件中的MI_KEYDEF结构体,keydef段由mi_open.c中的mi_keydef_write()写入到MYI文件。每个索引对应一个MI_KEYDEF结构体,表4-2给出了keydef结构的定义和说明。表4-2keydef结构的定义和说明变量和结构体成员说明I1的索引结构体keydef->keysegs表示本索引只由一个字段组成,即S1keydef->key_alg本索引的算法—R树或者B树索引keydef->flag索引属性keydef->block_length头部信息的长度keydef->keylengthsizeof(ROWID)有关索引I1的组成字段S1的定义keyseg->typeI1(S1)size(S1)=1,列=1keyseg->flagHA_NULL_PART+HA_PART_KEYkeyseg->lengthS1的长度=1keyseg->start在行中的位置keyseg->null_posNull的位置I2的索引结构体keydef->keysegs该索引由两列组成—S2和S331 南京邮电大学硕士研究生学位第四章MySQL的存储引擎keydef->key_alg本索引的算法—R树或B树索引keydef->flag索引属性keydef->block_length头部信息的长度keydef->keylengthsizeof(ROWID)keydef段由mi_open.c中的mi_recinfo_write()写入MYI文件。相应结构是myisamdef.h中的COLUMNDEF结构体。Recinfo出现的次数取决于所有索引的字段数总和加上一个额外字段。(2)MYI索引值索引值是按页面(Page)形式存储的,每一页只存储来自于同一个索引的值。I1索引页面从MYI文件的偏移量0x0400开始,而I2索引页面从MYI文件的偏移量0x0800开始。表4-3给出了I1和I2索引页面的说明。表4-3I1、I2索引页面的说明名称值说明I1索引页面块头部000e第一个字节00指这是B树中的叶节点第一个索引值0131索引值ASCII码,值为1第一个索引指针00000000指向记录的编号是#0000第二个索引值0133索引值的ASCII码,值为3第二个索引指针00000002指向记录的编号是#0002其它无用信息1010……其余的1KB容量未被使用I2索引页面块头部0018第一个字节00指这是B树中的叶节点,18指大小第一个索引值01616101622020索引值ASCII码,值为aa/b第一个索引指针00000000指向记录的编号是#0000第二个索引值01616101626262索引值ASCII码,值为aa/bbb第二个索引指针00000002指向记录的编号是#0002其它无用信息1010……其余的1KB容量未被使用32 南京邮电大学硕士研究生学位第四章MySQL的存储引擎4.3InnoDB存储引擎4.3.1InnoDB的功能特征InnoDB是具有可回滚和防崩溃能力的事务型存储引擎,使用行级锁,并在SELECT语句提供多版本并发控制功能。在SQL查询中,InnoDB类型的表可以和其他类型的MySQL表混合起来,甚至在同一个查询中也可以混合。InnoDB的设计参照了Oracle的架构和功能,并具备其独有的特征:双写入、插入缓存和适应式哈希索引。这些特性为InnoDB存储引擎带来了更好的性能和更高的可靠性。双写入这一技术指的是的当InnoDB的进行表空间数据写操作时会将数据写两次。当数据库宕机时,可能发生部分写实效情况,即数据库正在写一个页面,而此页面只写了一部分。当写实效发生时,先通过页的副本来还原该页,再进行重做,这就是双写入,其体系架构如图4-3所示:图4-3InnoDB存储引擎doublewrite架构插入缓存的存在减少了数据库在对非主索引插入数据时造成的磁盘随机读写情况。InnoDB存储引擎的索引类型为自适应哈希索引。如果一个表能完全载入到主内存,在其上执行查询最快的方法就是使用哈希索引,InnoDB有一个自动机制,它监视对表上索引的查找,如果观察到建立哈希索引可以带来速度的提升,则建立哈希索引,所以称之为自适应的。自适应哈希索引通过缓冲池的B+树构造而来,InnoDB存储引擎会自动根据访问的频率和模式来为某些页来建立哈希索引。33 南京邮电大学硕士研究生学位第四章MySQL的存储引擎4.3.2InnoDB的架构及代码分布如图4-4所示,InnoDB是一个庞大的系统,它包含许多子系统且代码分布在几十个目录中,采用层次结构的设计。图4-4InnoDB架构在第一层,HandleAPI的存在,使得InnoDB能够顺利插入到MySQL服务器中,同时InnoDB还为应用系统提供了API,在这种情况下,用户可以直接将InnoDB存储引擎嵌入到他的应用系统中。第二层是事务层。在InnoDB中,所有的行为都发生在事务中。如果我们在my.cnf中配置了auto-commit这一属性,那么我们执行的每个SQL语句都是一个单独的事务。SQL关键字COMMIT、ROLLBACK等被查询解析子系统解析为InnoDB特有查询语句。第三层是锁功能层。该层完成锁功能和事务管理的功能,如回滚、提交等操作。InnoDB采用行级的读写锁。Lock目录下的lock0lock.c处理所有锁功能。InnoDB和特意使用一个锁表来跟踪各种各样锁的情况。第四层是缓存管理。缓存管理层的主要目标是高效的将数据存放在内存之中。该层的功能由目录buf中的源文件实现,Buf0buf.c提供了缓存池以备将文件分页存入内存。第五层是存储空间IO管理。该层的目标是为文件读写提供接口并维护表空间和日志空间的大小。该层的代码主要分布在fil目录下。InnoDB为了提供高效的磁盘访问,采用和RAID0相似的条带化方法将逻辑块数据分布到不同的几个物理文件中。图4-5描述的是InnoDB的代码分布目录:34 南京邮电大学硕士研究生学位第四章MySQL的存储引擎图4-5InnoDB代码目录除了以上所提层次相关的源代码以外,其他目录还包括:Ha目录:哈希表是InnoDB内部经常使用的数据结构。Ha目录是创建和管理哈希表的代码目录。该目录提供了各种哈希表的简单操作方法,例如删除表项、插入表项等。dyn目录:动态分配数组的工具目录。ut目录:ut是utilities的缩写。目录提供了字符串、内存和随机数等处理函数。此外一些其他常见的函数,如排序、时间戳、打印缓存内容等操作。com目录:这是线程通信相关的源代码目录。目录中的com0com.c包含了线程通信的普通接口,而com0shm.c包含了以共享内存方式实现的通信接口。thr和sync目录:这两个目录分别是线程目录和线程同步目录。sync包含了自旋锁和读写锁有关的代码。log目录:该目录是处理InnoDB日志功能的源代码目录,日志功能需要完成将缓存中的数据写入到日志文件和将事务型操作记录到日志文件。4.3.3InnoDB文件格式InnoDB以多种格式在磁盘上存储文件,涉及表空间、页、集合、行等多个概念。InnoDB的表空间可由多个文件或者裸分区组成,系统表空间至少包含以下内容:内部数据词典、Undo日志、插入缓存、双写入缓存、MySQL复制功能信息。InnoDB表空间、段、结合和行之间的关系如图4-6所示。表空间在逻辑上可分割成段,段又由许多页组成。InnoDB为35 南京邮电大学硕士研究生学位第四章MySQL的存储引擎了方便管理这些大量的页又以64个单位组成集合,下面将重点分析页结构。图4-6InnoDB表空间、段、集合和行之间的关系4.3.4InnoDB记录结构表4-4为物理记录的三个部分,分别是字段偏移量、额外字段和记录内容。表4-4物理记录的组成组成部分大小字段偏移量字段*1或字段*2字节额外字段6字节记录内容取决于内容字段偏移量是一个数字记录,该数字标志了新纪录的开始位置。它是一个目录列表,每一个目录是一个相对于记录起点的偏移量,这些目录是反向储存的,也就是说每一个字段的偏移量是存储在该列表的最后一个目录。每个目录的长度是一个或者两个字节,只有当记录的总长度小于127时,才可以设置目录长度为一个字节,在额外字段中会指出目录的长度是一个字节还是两个字节。偏移的最高位通常是标志位,只起到标志作用。当偏移量是一个字节时,第一个比特位如果是0,字段是非NULL;如果是1,字段是NULL;后几个比特位实际的偏移值范围是1~127。当偏移量是两个字节时,第一个比特位如果是0,字段是非NULL;如果是1,字段是NULL;第二个比特位如果是0,字段存储36 南京邮电大学硕士研究生学位第四章MySQL的存储引擎在同一页;如果是1,字段存储在不同的页,只有当记录包含大字段对象时才可能出现这一情况;后14个比特位实际的偏移值范围是0~16383。额外字节是定长的,占6个字节,表4-5是额外字节的详细说明。表4-5额外字节的详细说明字段名称大小(比特)说明信息位空白2保留将来之用删除标志1当记录被删除时,设置该记录最小长度记录1设置为1,则说明该行为表中设置的最小行包含数量4包含的数量记录在索引页中的位置13记录在索引页中的位置列数量10本记录中的列数,1~1023偏移长度标志1偏移量所用位数,若设为1,则为1个字节指针位最后16个字节16是一个指针,指向同页面中的下一个记录记录内容是用来存放记录的实际数据,按照定义的顺序进行存放。有了前两个部分的帮助,在记录内容中,各个列之间都不存在特殊的标志。4.3.5InnoDB页结构如图4-6所示,InnoDB将所有的记录存放在数据库页中,一般情况下,非压缩页的大小是16KB。一个InnoDB页包含7个部分:文件头、页头、最小以及最大虚记录、用户记录、自由堆、页目录和文件尾。可以看出,一个页包含两队头部和尾部,其中页头和页目录与页管理有关,而文件页头和文件页尾与文件页管理紧密相连。在头部和尾部之间的是记录和未使用的空间。一个页的最开始处为两个不变的记录,称之为最小和最大虚记录,接下去存储才是用户的记录。用户记录和页目录之间的空间用来存储未来的新记录。头文件包含8个部分,如表4-6所示。表4-6头文件说明字段名大小说明FIL_PAGE_SPACE4页所在表空间的ID号37 南京邮电大学硕士研究生学位第四章MySQL的存储引擎FIL_PAGE_OFFSET4页在表空间的偏移量FIL_PAGE_PREV4该页的前一页在表空间的偏移量FIL_PAGE_NEXT4该页的后一页在表空间的偏移量FIL_PAGE_LSN8页中最新日志的日志序列号FIL_PAGE_TYPE2页类型FIL_PAGE_FILE_FLUSH_LSN8当日志写入到磁盘时,只写入到此日志位FIL_PAGE_ARCH_LOG_NO4只用于FIL_PAGE_UNDO_LOG类型的页FIL_PAGE_SPACE是必要的标示符,这是因为不同的页很可能属于同一个文件的不同表空间。FIL_PAGE_PREV和FIL_PAGE_NEXT为前一页和后一页的入口。页头的主要内容如表4-7所示,共14个部分。表4-7页头的组成字段名大小说明PAGE_N_DIR_SLOTS2记录槽的数量,初始值为2,因为页至少具有最小虚记录与最大虚记录,最大值为65535PAGE_HEAP_TOP2记录指针,指向内存中的第一个记录PAGE_N_HEAP2内存记录的数量,初始值为2,也是因为页至少具有最小虚记录与最大虚记录PAGE_FREE2记录指针,指向第一个已删除记录PAGE_GARBAGE2已删除记录中的字节数PAGE_LAST_INSERT2记录指针,指向最后一个被插入的记录PAGE_DIRECTION2插入时顺序PAGE_N_DIRECTION2连续在同一个方向插入的记录数PAGE_N_RECS2用户记录数量PAGE_MAX_TRX_ID8事务最大IDPAGE_LEVEL2在索引中的位置PAGE_INDEX_ID8记录该页所属的索引IDPAGE_BTR_SEG_LEAF10PAGE_BTR_SEG_TOP10对于InnoDB来说,最小虚记录和最大虚记录,即是所谓的负无穷大和正无穷大。这两个记录是在页创建的时候创建的,并且永远不会被删除。它们的作用在于作为查询的界限,38 南京邮电大学硕士研究生学位第四章MySQL的存储引擎避免出现越界的情况。同时最小虚记录也可以作为临时记录锁定的虚拟目标。在用户记录的区域中,可以找到所有用户插入的记录。查找的方式有两种,分别是有序和无序。InnoDB不会在该区域按照记录进行B树的key排序,所以插入时时直接将新行插入到现有行的后面,或者使用空闲记录的空间。但是B树的定义是记录必须按照key值进行排序,因此每个记录都含有一个指针指向下一条记录,即这些记录有一个单向链表。所以InnoDB在查找时可以按照key排序的方式进行查找。页目录中包含了可变数量的记录指针,有时候记录指针也可以称为槽或记录槽。不同于其他的数据库系统,InnoDB不会为每一个记录分配一个目录,而是每六个记录分配一个目录。槽追踪了记录的逻辑顺序,因为槽是按关键字排序的,而且每个槽的大小是固定的,所以在一个页中通过槽进行二分查找就很容易了。因为并不是每一个记录都对应一个槽,二分查找也只能定位到一个大概的位置,接下去则需要使用next指针。InnoDB的少量槽机制在记录结构中的额外字节也会碰到多个使用的情况,这表明更多的记录需要被遍历。文件尾作为一个页的结尾,它的存在可能是因为InnoDB的设计师考虑到完整性。其实由于日志恢复机制的一致性约束,出现页的部分写入或者崩溃基本上都是不可能的。但是一旦真的出现问题,有这样一个校验和的存在会更加的安全。4.4本章小结本章主要介绍了存储引擎的基本知识并重点分析了MySQL中使用最为广泛的存储引擎:MyISAM和InnoDB。其他存储引擎,如Memory、NDB、Archive等在某些情况下也有着自己的优势,限于篇幅无法再深入讨论。对两种引擎的文件格式、存储原理和机制的理解也为下一章设计自定义存储引擎做好铺垫。39 南京邮电大学硕士研究生学位第五章自定义存储引擎Nanjupt的设计第五章自定义存储引擎Nanjupt的设计5.1初始化存储引擎这个阶段的目的是能够将Nanjupt存储引擎插入到MySQL服务器并通过编译,该阶段的存储引擎需要满足指定ENGINE的功能,同时还能打开基本的frm文件,为以后能够继续扩展Nanjupt存储引擎做好了编译和测试的准备。5.1.1创建Nanjupt源文件首先在storage目录下创建一个名称为nanjupt的文件夹。复制storage/example目录下的*.cc和*.h到storage/Nanjupt目录去。这时在storage/nanjupt目录下有两个文件,分别是ha_example.cc和ha_example.h。ha_的前缀意味着这些类是从handler类继承并代表一种表类型的表处理器。重命名为这两个文件为ha_nanjupt.cc和ha_nanjupt.h,然后将两个文件夹里的example和EXAMPLE替换为nanjupt和NANJUPT,并将ha_nanjupt.h包含到ha_nanjupt.cc中。5.1.2把Nanjupt存储引擎加入到MySQL服务器接下来修改的是源代码目录下的configure文件,在修改时,可以复制csv对应的部分,在OptionalPackages部分找到csv,在它的后面添加如下代码:--with-csv-storage-engineenablecsvstorageengine(defaultis"yes")--with-nanjupt-storage-engineenablenanjuptstorageengine(defaultis"yes")--with-blackhole-storage-engineenableblackholestorageengine(defaultis"no")继续找到处理makefile的地方,在csv部分之后,添加这段代码:#Checkwhether--with-nanjupt-storage-engineor#-without-nanjupt-storage-enginewasgiven.iftest"${with_nanjupt_storage_engine+set}"=set;thenwithval="$with_nanjupt_storage_engine"40 南京邮电大学硕士研究生学位第五章自定义存储引擎Nanjupt的设计elsewith_nanjupt_storage_engine='"yes"'fi;echo"$as_me:$LINENO:checkingwhethertouseNanjuptstorageengine">&5echo$ECHO_N"checkingwhethertouseNanjuptstorageengine...$ECHO_C">&6iftest"${mysql_cv_use_nanjupt_storage_engine+set}"=set;thenecho$ECHO_N"(cached)$ECHO_C">&6elsemysql_cv_use_nanjupt_storage_engine=$with_nanjupt_storage_engine在编译之前,还需要对MySQL服务器文件进行修改,首先打开my_config.h文件,为nanjupt存储引擎添加#define,然后打开handler.h文件,在legacy_db_type_enum类型中添加nanjupt类型,再打开handler.cc文件,修改show_table_alias_st结构体,最后打开mysql_priv.h文件,添加nanjupt存储引擎的宏定义#ifdef。5.1.3编译Nanjupt存储引擎编译时使用到的工具有MicrosoftVisualStudio2008、ULTRAEDIT和cmake-2.8。编译步骤如下:使用CMAKE生成vs2008解决方案(.sln文件),如图5-1所示;用ULTRAEDIT打开D:mysql-5.5.18sqlsql_local.cc文件,另存为UTF-8格式,覆盖原文件;修改文件D:mysql-5.5.18sqlmysqld.cc中的test_lc_time_sz函数;用Visualstudio2008打开D:mysql-5.5.18MySql.sln,编译。图5-1CMAKE生成vs2008解决方案编译成功之后,启动MySQL服务器,测试安装情况,输入如下SQL语句:mysql->showstorageengines;mysql->usetest;mysql->createtablet1(col_aint,col_bvarchar(20),col_cint)engine=nanjupt;mysql->showcreatetablet1;41 南京邮电大学硕士研究生学位第五章自定义存储引擎Nanjupt的设计droptablet1;测试结果如图5-2所示,存储引擎nanjupt成功插入到MySQL服务器中,并且能够指定ENGINE。图5-2存储引擎初始化结果42 南京邮电大学硕士研究生学位第五章自定义存储引擎Nanjupt的设计5.2表操作这一部分的目的是使得初始化的存储引擎能够创建、打开、关闭和删除数据文件,并且完成对数据的修改和删除能力。在这个阶段里,我们完成了存储引擎对数据文件的操作,以及使存储引擎能够与存储文件顺利的合作。5.2.1修改头文件ha_nanjupt.h打开ha_nanjupt.h,将nanjupt_data.h文件包含进去,然后添加对象引用结构,更改后的内容如下:#include"nanjupt_data.h"#ifdefUSE_PRAGMA_INTERFACE#pragmainterface/*gccclassimplmenttechnical*/#endif...typederstructst_nanjupt_share{char*table_name;uinttable_name_length,use_count;pthread_mutex_tmutex;THR_LOCKlock;Nanjupt_data*data_class;}NANJUPT_SHARE;5.2.2修改类文件ha_nanjupt.cc打开文件ha_nanjupt.cc,定位到get_share()函数。因为现在在共享结构中有了对象引用,所以创建共享结构时,需要初始化Nanjupt_data类。在Get_share()函数中,设置这个共享结构的被引用计数为0,共享结构的内存被释放,修改结果如下:staticNANJUPT_SHARE*get_share(constchar*table_name,TABLE*table){NANJUPT_SHARE*share;uintlength;char*tmp_name;43 南京邮电大学硕士研究生学位第五章自定义存储引擎Nanjupt的设计pthread_mutex_lock(&NANJUPT_mutex);//createalockforsingleaccesslength=(uint)strlen(table_name);if(!(share=(NANJUPT_SHARE*)hash_search(&NANJUPT_open_tables,(byte*)table_name,length))){if(!my_multi_malloc(MYF(MY_WME|MY_ZEROFILL),&share,sizeof(*share),&tmp_name,length+1,NullS)){pthread_mutex_unlock(&NANJUPT_mutex);returnNULL;}定位到函数rnd_init(),在这里可以设置表扫描的初始条件,在这里我们设置当前位置为0和记录数量为0。修改后的代码如下:intha_nanjupt::rnd_init(boolscan){DBUG_ENTER("ha_nanjupt::rnd_init");current_position=0;records=0;ref_length=sizeof(longlong);DBUG_RETURN(0);}position()函数记录了Nanjupt存储引擎读取数据文件的当前记录位置:voidha_nanjupt::position(constbyte*record){DBUG_ENTER("ha_nanjupt::position");my_store_ptr(ref,ref_length,current_position);DBUG_VOID_RETURN;}position方法存储和获得位置由my_store_ptr()和my_get_ptr()来实现,rnd_pos()方法是按照指定位置读取记录的方法:intha_nanjupt::rnd_pos(byte*buf,byte*pos)44 南京邮电大学硕士研究生学位第五章自定义存储引擎Nanjupt的设计{DBUG_ENTER("ha_nanjupt::rnd_pos");ha_statistic_increment(&SSV::ha_read_rnd_next_count);current_position=(off_t)my_get_ptr(pos,ref_length);share->data_class->read_row(buf,current_position,-1);DBUG_RETURN(0);}完成这些函数的修改之后编译和测试代码,测试结果如图所示。图5-3用Nanjupt创建表图5-4实现了在表中插入数据:图5-4在表中插入数据图5-5实现了表中数据的修改及所有数据行的删除:45 南京邮电大学硕士研究生学位第五章自定义存储引擎Nanjupt的设计图5-5数据的修改及删除5.3索引功能这一阶段数据库要实现索引功能。在这个阶段需要将Nanjupt_index类加入到存储引擎中。第一步要做的是将Nanjupt_index类加入到项目的makefile中,编辑在storage/Nanjupt目录下的Makefile.am和Makefile.in两个文件,将nanjupt_index的信息添加进去。Makefile.am文件修改如下:noinst_HEADERS=ha_nanjupt.hnanjupt_data.hnanjupt_index.hlibnanjupt_a_SOURCES=ha_nanjupt.ccnanjupt_data.ccnanjupt_index.ccMakefile.in文件修改如下:noinst_HEADERS=ha_nanjupt.hnanjupt_data.hnanjupt_index.hlibnanjupt_a_SOURCES=ha_nanjupt.ccnanjupt_data.ccnanjupt_index.ccam_libnanjupt_a_OBJECTS=ha_nanjupt.$(OBJEXT)nanjupt_data.$(OBJEXT) anjupt_index.$(OBJEXT)Nanjupt_index类的原理是在索引文件中保存了数据记录在Nanjupt_data中的位置的指针。当服务器通过索引查找某个数据记录时,MySQL通过索引文件先找到这个记录的位置指针,然后再调用Nanjupt_data的记录读取函数。Nanjupt_index类保存了记录所在的位置指针以及索引的键值。首先要将nanjupt_index这个类包含到ha_nanjupt.h头文件中去,在ha_nanjupt.cc中,需要修改的方法有index_read()、index_read_idx()、index_next()、index_prev()、index_first()和index_last()。46 南京邮电大学硕士研究生学位第五章自定义存储引擎Nanjupt的设计现在完整的nanjupt存储引擎已经编写完成(代码略),下面是使用SQL语句来测试引擎的索引功能:图5-6加入主键key图5-7通过索引修改数据47 南京邮电大学硕士研究生学位第五章自定义存储引擎Nanjupt的设计图5-8通过索引删除行48 南京邮电大学硕士研究生学位第五章自定义存储引擎Nanjupt的设计图5-9通过索引对数据进行条件性操作图5-10通过索引对表格进行重命名49 南京邮电大学硕士研究生学位第五章自定义存储引擎Nanjupt的设计5.4本章小结本章完成了自定义存储引擎Nanjupt的设计,并了解到如何构建一个能够读写数据并且支持并发访问的存储引擎,通过编译和SQL语句的测试,证明该引擎正确可用。50 南京邮电大学硕士研究生学位第六章结束语第六章结束语6.1课题研究总结当前,开放源代码的数据库系统得到越来越广泛的应用,作为开源数据库的主流产品,MySQL的特点是:运行速度快、易使用、优异的可移植性和低廉的成本等等。MySQL的存储引擎是可以选择的插件,针对不同类型的数据可以采用不同的存储引擎技术。基于以上特点,MySQL在用户群中是十分受欢迎的,并且得到多方面的关注。本课题在分析MySQL源代码的基础之上,深入剖析MySQL内核的设计与实现,并结合对其他经典存储引擎的理解,设计出自定义的存储引擎Nanjupt。它的基本思路是,以MySQL的存根引擎exanple为基础,在初始阶段创建和添加基本的数据读写功能,然后再添加对索引的支持。在论文设计期间,本人主要完成了以下工作:1.在论文的前期工作中,大量搜集并学习了有关MySQL的文献资料,并安装使用MySQL数据库系统,对于MySQL的框架有了基本的了解;研究了关系型数据库的基本架构,并在功能、性能以及易用性方面将MySQL和其他主流的数据库做一个基本的比较;熟悉了MySQL系统架构,包括SQL层和存储引擎层;着重学习了MySQL的各个子系统,包括连接和网络子系统、服务器线程和资源管理子系统、查询解析与优化器子系统和安全管理子系统。2.下载MySQL源代码,版本为5.5.18,使用MicrosoftVisualStudio2008、ULTRAEDIT和cmake-2.8等工具将代码在Windows系统下编译成功;接下来是对源代码的分析,由于论文时间的限制,本文仅对MySQL的核心类、核心算法以及两种经典的存储引擎的代码做出分析;核心类包括线程类、Item类、表描述类和Field类,核心算法包括位图、表连接缓冲和排序实现,两种存储引擎分别是MyISAM和InnoDB。3.设计自定义存储引擎Nanjupt。第一步是创建Nanjupt源文件并将其添加到项目管理文件中,编译通过之后从而实现存储引擎的初始化;第二步是使得初始化的存储引擎能够创建、打开、关闭和删除数据文件,通过修改头文件ha_nanjupt.h和类文件ha_nanjupt.cc,而后编译得以实现;第三步是添加索引功能,方法是将类文件Nanjupt_index加入到项目makefile中,编辑Makefile.am和Makefile.in两个文件。4.每一步添加和修改文件后都要重新编译源程序,通过控制台,使用MySQL语句测试编译结果并记录。51 南京邮电大学硕士研究生学位第六章结束语6.2进一步研究方向本存储引擎在设计的过程中,只实现了数据操作等基本功能,对于支持事务处理功能的问题没有得到解决,在今后的研究工作中,该引擎有待于进一步的完善,主要可以从以下几个方面做出改进:1.对引擎代码进行进一步的改进和调试,优化代码使之更加健壮,避免出现系统卡死等情况。2.添加事务支持之后数据库才能够成为完全功能的关系型数据库。3.MySQL的代码并非是结构化的,因此除了系统自带的引擎外,在添加引擎的时候需要修改复杂的配置文件并且重新编译,而不是随即插取;随着MySQL数据库版本的不断更新,希望不久的将来自定义存储引擎可实现真正“插件式”。52 南京邮电大学硕士研究生学位致谢致谢光阴荏苒,岁月如梭,两年多的硕士研究生学习生涯即将结束,我的学生时代也将划上句号。经过大半年时间的磨砺,我的硕士毕业论文终于完稿,回首这其中的种种,有过搜集资料的繁琐,有过思维停滞的苦恼,有过编写代码的枯燥。一路走来,我得到了许多的关怀和帮助,现在要向他们表达我最诚挚的谢意。首先,我要深深感谢我的导师马明栋教授,在我论文的选题、研究和撰写阶段,马老师都倾注了极大的心血。在论文的写作过程中,每当我有所疑问,马老师总会放下手中繁忙的工作,耐心地指导我;在我完成论文初稿后,他又对我的论文认真批改,句句把关,提出了许多宝贵的意见以使我的论文不致偏离了课题的方向;在经过马老师多次认真批改后我的论文才最终定稿。借此机会,我谨向马老师致以深深的谢意。其次,我要感谢同在一个教研室的师兄师姐、师弟师妹们。在两年多的研究生生涯中,我们在学习上互相切磋,共同提高,拓展了我的思维,开阔了我的视野;在生活上,我们互相关怀,在我困难的时候曾得到了你们无私的帮助,使我感到了学校大家庭的温暖。在此我真诚地说一声,谢谢。最后,我要感谢参与我论文评审答辩的各位专家老师,他们给了我一次机会,使我得以审视两年多来的学习成果,为今后的奋斗和努力明确方向。祝他们一生幸福安康!53 南京邮电大学硕士研究生学位参考文献参考文献[1]RickF.vanderLans,许杰星,李强等.MySQL开发者SQL权威指南.北京:机械工业出版社,2008[2](美)RussellJ.T.Dyer.MySQL核心技术手册.李红军译.北京:机械工业出版社,2010[3]李立功,赵扬.MySQL程序设计与数据库管理.北京:科学出版社,2001[4]唐汉明.深入浅出MySQL数据库开发,优化与管理维护.北京:人民邮电出版社,2001[5]高海茹.MySQL网络数据库技术精粹.北京:机械工业出版社,2002[6]薛军超.MySQL网络数据库开发.北京:人民邮电出版社,2001[7](美)PaulDuBois.MySQL网络数据库指南.钟鸣泽译.北京:机械工业出版社,2000[8]简朝阳.MySQL性能调优与架构设计.北京:电子工业出版社,2009[9]简朝阳.基于MySQL的高可用可扩展架构探讨.《程序员》杂志,2010年06期[10]杨涛.MysQL权威指南.北京:机械工业出版社,2004[11](美)HughE.WILLIAMSDavidLANE.PHP&MySQLWeb数据库应用开发指南.南京:东南大学出版社,2006[12]黄经纬.PHP&MySQL网站建设宝典.北京:清华大学出版社,2010[13]仲进平,寿加炎.PHP+MySQL网络开发技术.北京:人民邮电出版社,2000[14](美)LeonAtkinson.MySQL核心编程.北京:清华大学出版社,2003[15](美)matthewstucky.MySQL:创建用户接口.北京:人民邮电出版社,2002[16]滑玉.MySQL网络数据库开发.北京:人民邮电出版社,2001[17]BaronSchwartz,PeterZaitsev,VadimTkachenko,Jeremy.高性能MySQL(第2版).北京:电子工业出版社,2010[18]Bell.C,Kindahl.M,Thalann.L,宁青.高可用MySQL:构建健壮的数据中心.北京:电子工业出版社,2011[19]PaulDuBois,杨晓云,王建桥,杨涛.MySQL技术内幕(第4版).北京:人民邮电出版社,2011[20]姜承尧.MySQL技术内幕:InnoDB存储引擎.北京:机械工业出版社,2011[21]SasbaPacbev,李芳,于红芸,邵健.深入理解MySQL核心技术.北京:中国电力出版社,2009[22]LukeWelling,LauraThomson,武欣.php和mysqlweb开发.北京:机械工业出版54 南京邮电大学硕士研究生学位参考文献社,2009[23]PaulDuBois.MySQLCookbook(中文版).北京:电子工业出版社,2008[24]赵廷涛,刘冰,孙兴义等.Linux下的MySQL数据库编程.北京:清华大学出版社,2010[25]张定泽,张海,黄健晶.MySQL核心内幕.北京:清华大学出版社,2010[26]W.Jason,Gilmore,朱涛江等.PHP与MySQL程序设计(第4版)北京:人民邮电出版社,2011[27]吴津津,刘昊,田睿,等.PHP与MySQL权威指南.北京:机械工业出版社,2011[28]聂庆鹏,毛书朋,王志乐.PHP+MySQL动态网站开发与全程实例.北京:清华大学出版社,2007[29]吴吉义,王中友.程序员突击:MySQL原理与Web系统开发.北京:清华大学出版,2009[30]MicheleE.Davis,JonA.Phillips.学习PHP&MySQL(第2版).南京:东南大学出版社,2008[31]王炎武,陈虎,唐海浩,奚建清.MySQL中多线程存储引擎Falcon的测试与分析.计算机科学,2008年V01.35NQ.11(专刊)[32]陈小辉,文佳,邓杰英.MySQL的体系结构及InnoDB表引擎的配置.FUJIANCOMPUTER,2009年第7期[33]马永成,肖诗斌,王弘蔚,施水才.MySQL存储引擎的研究和实现.计算机科学,2007年Voi.34No.12(专刊)55

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
大家都在看
近期热门
关闭