第3章 MySQL存储引擎简介
3.1 MySQL 存储引擎概述
MyISAM存储引擎是MySQL默认的存储引擎,也是目前MySQL使用最为普遍的存储引擎之一。他的前身就是咱们在MySQL发展历程中所提到的 ISAM,是 ISAM的升级版本。在MySQL 最开始发行的时候是ISAM存储引擎,并且实际上在最初的时候,MySQL甚至是没有存储引擎这个概念的。MySQL在架构上面也没有像如今这样的sql layer和storage engine layer 这两个结构清晰的层次结构,当时无论是代码自己仍是系统架构,对于开发者来讲都很痛苦的一件事情。到后来,MySQL意识到须要更改架构,将前 端的业务逻辑和后端数据存储以清晰的层次结构拆分开的同时,对ISAM作了功能上面的扩展和代码的重构,这就是MyISAM 存储引擎的由来。
MySQL在5.1(不包括)以前的版本中,存储引擎是须要在MySQL安装的时候就必须和 MySQL一块儿被编译并同时被安装的。也就是说,5.1以前的 版本中,虽然存储引擎层和sql 层的耦合已经很是少了,基本上彻底是经过接口来实现交互,可是这两层之间仍然是没办法分离的,即便在安装的时候也是同样。
可是从MySQL5.1开始,MySQL AB对其结构体系作了较大的改造,并引入了一个新的概念:插件式存储引擎体系结构。MySQL AB 在架构改造的时候,让存储引擎层和sql层各自更为独立,耦合更小,甚至能够作到在线加载信的存储引擎,也就是彻底能够将一个新的存储引擎加载到一个正在 运行的MySQL中,而不影响MySQL的正常运行。插件式存储引擎的架构,为存储引擎的加载和移出更为灵活方便,也使自行开发存储引擎更为方便简单。在 这一点上面,目前尚未哪一个数据库管理系统可以作到。
MySQL的插件式存储引擎主要包括MyISAM,Innodb,NDB Cluster,Maria,Falcon, Memory,Archive,Merge,Federated等,其中最著名并且使用最为普遍的 MyISAM和Innodb两种存储引擎。MyISAM是MySQL最先的ISAM存储引擎的升级版本,也是MySQL默认的存储引擎。而Innodb实 际上并非MySQ公司的,而是第三方软件公司Innobase(在2005年被Oracle公司所收购)所开发,其最大的特色是提供了事务控制等特性, 因此使用者也很是普遍。
其余的一些存储引擎相对来讲使用场景要稍微少一些,都是应用于某些特定的场景,如NDB Cluster虽然也支持事务,可是主要是用于分布式环境,属于一个share nothing的分布式数据库存储引擎。Maria是MySQL最新开发(尚未发布最终的GA版本)的对MyISAM 的升级版存储引擎,Falcon是 MySQL公司自行研发的为了替代当前的Innodb存储引擎的一款带有事务等高级特性的数据库存储引擎,目前正在研发阶段。Memory存储引擎全部数 据和索引均存储于内存中,因此主要是用于一些临时表,或者对性能要求极高,可是容许在主机Crash的时候丢失数据的特定场景下。Archive是一 个数据通过高比例压缩存放的存储引擎,主要用于存放过时并且不多访问的历史信息,不支持索引。Merge和Federated在严格意义上来讲,并不能算 做一个存储引擎。由于Merge存储引擎主要用于将几个基表 merge到一块儿,对外做为一个表来提供服务,基表能够基于其余的几个存储引擎。而Federated实际上所作的事情,有点相似于Oracle的dblink,主要用于远程存取其余MySQL服务器上面的数据。
3.2 MyISAM 存储引擎简介
MyISAM存储引擎的表在数据库中,每个表都被存放为三个以表名命名的物理文件。首先确定会有任何存储引擎都不可缺乏的存放表结构定义信息的.frm文件,另外还有.MYD和.MYI文件,分别存放了表的数据(.MYD)和索引数据(.MYI)。每一个表都有且仅有这样三个文件作为MyISAM存储类型的表的存储,也就是说无论这个表有多少个索引,都是存放在同一个.MYI文件中。
MyISAM支持如下三种类型的索引:
一、B-Tree索引
B-Tree索引,顾名思义,就是全部的索引节点都按照balance tree的数据结构来存储,全部的索引数据节点都在叶节点。
二、R-Tree索引
R-Tree索引的存储方式和b-tree索引有一些区别,主要设计用于为存储空间和多维数据的字段作索引,因此目前的MySQL版原本说,也仅支持geometry类型的字段做索引。
三、Full-text索引
Full-text索引就是咱们长说的全文索引,他的存储结构也是b-tree。主要是为了解决在咱们须要用like查询的低效问题。
MyISAM上面三种索引类型中,最常用的就是B-Tree索引了,偶尔会使用到Full-text,可是R-Tree索引通常系统中都是不多用到的。另外MyISAM的B-Tree索引有一个较大的限制,那就是参与一个索引的全部字段的长度之和不能超过1000字节。
虽然每个MyISAM的表都是存放在一个相同后缀名的.MYD文件中,可是每一个文件的存放格式实际上可能并非彻底同样的,由于MyISAM的数据存放格式是分为静态(FIXED)固定长度、动态(DYNAMIC)可变长度以及压缩(COMPRESSED)这三种格式。固然三种格式中是否压缩是彻底能够任由咱们本身选择的,能够在建立表的时候经过ROW_FORMAT来指定{COMPRESSED | DEFAULT},也能够经过myisampack工具来进行压缩,默认是不压缩的。而在非压缩的状况下,是静态仍是动态,就和咱们表中个字段的定义相关了。只要表中有可变长度类型的字段存在,那么该表就确定是YNAMIC格式的,若是没有任何可变长度的字段,则为FIXED格式,固然,你也能够经过alter table命令,强行将一个带有VARCHAR类型字段的DYNAMIC的表转换为FIXED,可是所带来的结果是原VARCHAR字段类型会被自动转换成CHAR类型。相反若是将FIXED转换为DYNAMIC,也会将CHAR类型字段转换为VARCHAR类型, 因此你们手工强行转换的操做必定要谨慎。
MyISAM存储引擎的表是否足够可靠呢?在MySQL用户参考手册中列出在遇到以下状况的时候可能会出现表文件损坏:
一、当mysqld正在作写操做的时候被kill掉或者其余状况形成异常终止;
二、主机Crash;
三、磁盘硬件故障;
四、MyISAM存储引擎中的bug?
MyISAM存储引擎的某个表文件出错以后,仅影响到该表,而不会影响到其余表,更不会影响到其余的数据库。若是咱们的出据苦正在运行过程当中发现某个MyISAM表出现问题了,则能够在线经过check table 命令来尝试校验他,并能够经过repair table命令来尝试修复。在数据库关闭状态下,咱们也能够经过myisamchk工具来对数据库中某个(或某些)表进行检测或者修复。不过强烈建议不到万不得已不要轻易对表进行修复操做,修复以前尽可能作好可能的备份工做,以避免带来没必要要的后果。
另外MyISAM存储引擎的表理论上是能够被多个数据库实例同时使用同时操做的,可是不管是咱们都不建议这样作,并且MySQL官方的用户手册中也有提到,建议尽可能不要在多个mysqld之间共享MyISAM存储文件。
3.3 Innodb 存储引擎简介
在MySQL中使用最为普遍的除了MyISAM以外,就非Innodb莫属了。Innodb作为第三方公司所开发的存储引擎,和MySQL遵照相同的开源License协议。
Innodb之因此能如此受宠,主要是在于其功能方面的较多特色:
一、支持事务安装
Innodb在功能方面最重要的一点就是对事务安全的支持,这无疑是让Innodb成为MySQL最为流行的存储引擎之一的一个很是重要缘由。并且实现了SQL92标准所定义的全部四个级别(READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ和SERIALIZABLE)。对事务安全的支持,无疑让不少以前由于特殊业务要求而不得不放弃使用MySQL的用户转向支持MySQL,以及以前对数据库选型持观望态度的用户,也大大增长了对MySQL好感。
二、数据多版本读取
Innodb在事务支持的同时,为了保证数据的一致性已经并发时候的性能,经过对undo信息,实现了数据的多版本读取。
三、锁定机制的改进
Innodb改变了MyISAM的锁机制,实现了行锁。虽然Innodb的行锁机制的实现是经过索引来完成的,但毕竟在数据库中99%的SQL语句都是要使用索引来作检索数据的。因此,行锁定机制也无疑为Innodb在承受高并发压力的环境下加强了不小的竞争力。
四、实现外键
Innodb实现了外键引用这一数据库的重要特性,使在数据库端控制部分数据的完整性成为可能。虽然不少数据库系统调优专家都建议不要这样作,可是对于很多用户来讲在数据库端加如外键控制可能仍然是成本最低的选择。
除了以上几个功能上面的亮点以外,Innodb还有不少其余一些功能特点经常带给使用者不小的惊喜,同时也为MySQL带来了更多的客户。
在物理存储方卖弄,Innodb存储引擎也和MyISAM不太同样,虽然也有.frm文件来存放表结构定义相关的元数据,可是表数据和索引数据是存放在一块儿的。至因而每一个表单独存放仍是全部表存放在一块儿,彻底由用户来决定(经过特定配置),同时还支持符号连接。
Innodb的物理结构分为两大部分:
一、数据文件(表数据和索引数据)
存放数据表中的数据和全部的索引数据,包括主键和其余普通索引。在Innodb中,存在了表空间(tablespace)这样一个概念,可是他和Oracle的表空间又有较大的不一样。首先,Innodb的表空间分为两种形式。一种是共享表空间,也就是全部表和索引数据被存放在同一个表空间(一个或多个数据文件)中,经过innodb_data_file_path来指定,增长数据文件须要停机重启。 另一种是独享表空间,也就是每一个表的数据和索引被存放在一个单独的.ibd文件中。
虽然咱们能够自行设定使用共享表空间仍是独享表空间来存放咱们的表,可是共享表空间都是必须存在的,由于Innodb的undo信息和其余一些元数据信息都是存放在共享表空间里面的。共享表空间的数据文件是能够设置为固定大小和可自动扩展大小两种形式的,自动扩展形式的文件能够设置文件的最大大小和每次扩展量。在建立自动扩展的数据文件的时候,建议你们最好加上最大尺寸的属性,一个缘由是文件系统自己是有必定大小限制的(可是Innodb并不知道),还有一个缘由就是自身维护的方便。另外,Innodb不只可使用文件系统,还可使用原始块设备,也就是咱们常说的裸设备。
当咱们的文件表空间快要用完的时候,咱们必需要为其增长数据文件,固然,只有共享表空间有此操做。共享表空间增长数据文件的操做比较简单,只须要在innodb_data_file_path参数后面按照标准格式设置好文件路径和相关属性便可,不过这里有一点须要注意的,就是Innodb在建立新数据文件的时候是不会建立目录的,若是指定目录不存在,则会报错并没有法启动。另一个较为使人头疼的就是Innodb在给共享表空间增长数据文件以后,必需要重启数据库系统才能生效,若是是使用裸设备,还须要有两次重启。这也是我一直不太喜欢使用共享表空间而选用独享表空间的缘由之一。
mysql
二、日志文件
Innodb的日志文件和Oracle的redo日志比较相似,一样能够设置多个日志组(最少2个),一样采用轮循策略来顺序的写入,甚至在老版本中还有和Oracle同样的日志归档特性。若是你的数据库中有建立了Innodb的表,那么千万别所有删除innodb的日志文件,由于极可能就会让你的数据库crash,没法启动,或者是丢失数据。
因为Innodb是事务安全的存储引擎,因此系统Crash对他来讲并不能形成很是严重的损失,因为有redo日志的存在,有checkpoint机制的保护,Innodb彻底能够经过redo日志将数据库Crash时刻已经完成但尚未来得及将数据写入磁盘的事务恢复,也可以将全部部分完成并已经写入磁盘的未完成事务回滚并将数据还原。
Innodb不只在功能特性方面和MyISAM存储引擎有较大区别,在配置上面也是单独处理的。在MySQL启动参数文件设置中,Innodb的全部参数基本上都带有前缀“innodb_”,不管是innodb数据和日志相关,仍是其余一些性能,事务等等相关的参数都是同样。和全部Innodb相关的系统变量同样,全部的Innodb相关的系统状态值也一样所有以“Innodb_”前缀。固然,咱们也彻底能够仅仅经过一个参数(skip-innodb)来屏蔽MySQL中的Innodb存储引擎,这样即便咱们在安装编译的时候将Innodb存储引擎安装进去了,使用者也没法建立Innodb的表。
3.4 NDB Cluster 存储引擎简介
NDB存储引擎也叫NDB Cluster存储引擎,主要用于MySQL Cluster分布式集群环境,Cluster是MySQL从5.0版本才开始提供的新功能。这部分咱们可能并不只仅只是介绍NDB存储引擎,由于离开了MySQL CLuster整个环境,NDB存储引擎也将失去太多意义。 因此这一节主要是介绍一下MySQL Cluster的相关内容。
简单的说,Mysql Cluster实际上就是在无共享存储设备的状况下实现的一种内存数据库Cluster环境,其主要是经过NDB Cluster(简称NDB)存储引擎来实现的。
通常来讲,一个Mysql Cluster的环境主要由如下三部分组成:
a) 负责管理各个节点的Manage节点主机:
管理节点负责整个Cluster集群中各个节点的管理工做,包括集群的配置,启动关闭各节点,以及实施数据的备份恢复等。管理节点会获取整个Cluster环境中各节点的状态和错误信息,而且将各Cluster集群中各个节点的信息反馈给整个集群中其余的全部节点。因为管理节点上保存在整个Cluster环境的配置,同时担任了集群中各节点的基本沟通工做,因此他必须是最早被启动的节点。
b) SQL层的SQL服务器节点(后面简称为SQL节点),也就是咱们常说的Mysql Server:
主要负责实现一个数据库在存储层之上的全部事情,好比链接管理,query优化和响应,cache管理等等,只有存储层的工做交给了NDB数据节点去处理了。也就是说,在纯粹的Mysql Cluster环境中的SQL节点,能够被认为是一个不须要提供任何存储引擎的Mysql服务器,由于他的存储引擎有Cluster环境中的NDB节点来担任。因此,SQL层各Mysql服务器的启动与普通的Mysql启动有必定的区别,必需要添加ndbcluster项,能够添加在my.cnf配置文件中,也能够经过启动命令行来指定。
c) Storage层的NDB数据节点,也就是上面说的NDB Cluster:
NDB是一个内存式存储引擎也就是说,他会将全部的数据和索引数据都load到内存中,但也会将数据持久化到存储设备上。不过,最新版本,已经支持用户本身选择数据能够不所有Load到内存中了,这对于有些数据量太大或者基于成本考虑而没有足够内存空间来存放全部数据的用户来讲的确是一个大好消息。
NDB节点主要是实现底层数据存储的功能,保存Cluster的数据。每个NDB节点保存完整数据的一部分(或者一份完整的数据,视节点数目和配置而定),在MySQL CLuster里面叫作一个fragment。而每个fragment,正常状况来说都会在其余的主机上面有一份(或者多分)彻底相同的镜像存在。这些都是经过配置来完成的,因此只要配置得当,MysqlCluster在存储层不会出现单点的问题。通常来讲,NDB节点被组织成一个一个的NDB Group,一个NDB Group实际上就是一组存有彻底相同的物理数据的NDB节点群。
上面提到了NDB各个节点对数据的组织,可能每一个节点都存有所有的数据也可能只保存一部分数据,主要是受节点数目和参数来控制的。首先在Mysql Cluster主配置文件(在管理节点上面,通常为config.ini)中,有一个很是重要的参数叫NoOfReplicas,这个参数指定了每一份数据被冗余存储在不一样节点上面的份数,该参数通常至少应该被设置成2,也只须要设置成2就能够了。由于正常来讲,两个互为冗余的节点同时出现故障的几率仍是很是小的,固然若是机器和内存足够多的话,也能够继续增大。一个节点上面是保存全部的数据仍是一部分数据,还受到存储节点数目的限制。NDB存储引擎首先保证NoOfReplicas参数配置的要求对数据冗余,来使用存储节点,而后再根据节点数目将数据分段来继续使用多余的NDB节点,分段的数目为节点总数除以NoOfReplicas所得。
MySQL Cluster自己所包含的内容很是之多,出于篇幅考虑,这里暂时不作很深刻的介绍,在本书的架构设计部分的高可用性设计一章中将会有更为详细的介绍与实施细节,你们也能够经过MySQL官方文档来进一步了解部分细节。
3.5 其余存储引擎介绍
3.5.1 Merge存储引擎:
MERGE存储引擎,在MySQL用户手册中也提到了,也被你们认识为MRG_MyISAM引擎。Why?由于MERGE存储引擎能够简单的理解为其功能就是实现了对结构相同的MyISAM表,经过一些特殊的包装对外提供一个单一的访问入口,以达到减少应用的复杂度的目的。要建立MERGE 表,不只仅基表的结构要彻底一致,包括字段的顺序,基表的索引也必须彻底一致。
MERGE表自己并不存储数据,仅仅只是为多个基表提供一个赞成的存储入口。因此在建立MERGE表的时候,MySQL只会生成两个较小的文件,一个是.frm的结构定义文件,还有一个.MRG文件,用于存放参与MERGE的表的名称(包括所属数据库schema)。之因此须要有所属数据库的schema,是由于MERGE表不只能够实现将Merge同一个数据库中的表,还能够Merge不一样数据库中的表,只要是权限容许,而且在同一个mysqld下面,就能够进行Merge。MERGE表在被建立以后,仍然能够经过相关命令来更改底层的基表。
MERGE表不只能够提供读取服务,也能够提供写入服务。要让MERGE表提供可INSERT服务,必须在在表被建立的时候就指明 INSERT数据要被写入哪个基表,能够经过insert_method参数来控制。若是没有指定该参数,任未尝试往MERGE表中INSERT数据的操做,都会出错。此外,没法经过MERGE表直接使用基表上面的全文索引,要使用全文索引,必须经过基表自己的存取才能实现。
3.5.2 Memory存储引擎:
Memory存储引擎,经过名字就很容易让人知道,他是一个将数据存储在内存中的存储引擎。Memory存储引擎不会将任何数据存放到磁盘上,仅仅存放了一个表结构相关信息的.frm文件在磁盘上面。因此一旦MySQL Crash或者主机Crash以后,Memory的表就只剩下一个结构了。Memory表支持索引,而且同时支持Hash和B-Tree两种格式的索引。因为是存放在内存中,因此Memory都是按照定长的空间来存储数据的,并且不支持BLOB和TEXT类型的字段。Memory存储引擎实现页级锁定。
既然全部数据都存放在内存中,那么他对内存的消耗量是可想而知的。在MySQL的用户手册上面有这样一个公式来计算Memory表实际须要消耗的内存大小:
SUM_OVER_ALL_BTREE_KEYS(max_length_of_key + sizeof(char*) * 4)
+ SUM_OVER_ALL_HASH_KEYS(sizeof(char*) * 2)
+ ALIGN(length_of_row+1, sizeof(char*))
3.5.3 BDB存储引擎:
BDB存储引擎全称为BerkeleyDB存储引擎,和Innodb同样,也不是MySQL本身开发实现的一个存储引擎,而是由Sleepycat Software所提供,固然,也是开源存储引擎,一样支持事务安全。
BDB存储引擎的数据存放也是每一个表两个物理文件,一个.frm和一个.db的文件,数据和索引信息都是存放在.db文件中。此外,BDB为了实现事务安全,也有本身的redo日志,和Innodb同样,也能够经过参数指定日志文件存放的位置。在锁定机制方面,BDB和Memory存储引擎同样,实现页级锁定。
因为BDB存储引擎实现了事务安全,那么他确定也须要有本身的check point机制。BDB在每次启动的时候,都会作一次check point,而且将以前的全部redo日志清空。在运行过程当中,咱们也能够经过执行flush logs来手工对BDB进行check point操做。
3.5.4 FEDERATED存储引擎:
FEDERATED存储引擎所实现的功能,和Oracle的DBLINK基本类似,主要用来提供对远程MySQL服务器上面的数据的访问借口。若是咱们使用源码编译来安装MySQL,那么必须手工指定启用FEDERATED存储引擎才行,由于MySQL默认是不起用该存储引擎的。
当咱们建立一个FEDERATED表的时候,仅仅在本地建立了一个表的结构定义信息的文件而已,全部数据均实时取自远程的MySQL服务器上面的数据库。
当咱们经过SQL操做FEDERATED表的时候,实现过程基本以下:
a、SQL调用被本地发布
b、MySQL处理器API(数据以处理器格式)
c、MySQL客户端API(数据被转换成SQL调用)
d、远程数据库-> MySQL客户端API
e、转换结果包(若是有的话)处处理器格式
f、处理器 API -> 结果行或受行影响的对本地的计数
3.5.5 ARCHIVE存储引擎:
ARCHIVE存储引擎主要用于经过较小的存储空间来存放过时的不多访问的历史数据。ARCHIVE表不支持索引,经过一个.frm的结构定义文件,一个.ARZ的数据压缩文件还有一个.ARM的meta信息文件。因为其所存放的数据的特殊性,ARCHIVE表不支持删除,修改操做,仅支持插入和查询操做。锁定机制为行级锁定。
3.5.6 BLACKHOLE存储引擎:
BLACKHOLE存储引擎是一个很是有意思的存储引擎,功能恰如其名,就是一个“黑洞”。就像咱们unix系统下面的“/dev/null”设备同样,无论咱们写入任何信息,都是有去无回。那么BLACKHOLE存储引擎对咱们有什么用呢?在我最初接触MySQL的时候我也有过一样的疑问,不知道MySQL提供这样一个存储引擎给咱们的用意为什么?可是后来在又一次数据的迁移过程当中,正是BLACKHOLE给我带来了很是大的功效。在那次数据迁移过程当中,因为数据须要通过一个中转的MySQL服务器作一些相关的转换操做,而后再经过复制移植到新的服务器上面。可当时我没有足够的空间来支持这个中转服务器的运做。这时候就显示出 BLACKHOLE的功效了,他不会记录下任何数据,可是会在binlog中记录下全部的sql。而这些sql最终都是会被复制所利用,并实施到最终的slave端。
MySQL的用户手册上面还介绍了BLACKHOLE存储引擎其余几个用途以下:
a、SQL文件语法的验证。
b、来自二进制日志记录的开销测量,经过比较容许二进制日志功能的BLACKHOLE的性能与禁止二进制日志功能的BLACKHOLE的性能。
c、由于BLACKHOLE本质上是一个“no-op” 存储引擎,它可能被用来查找与存储引擎自身不相关的性能瓶颈。
3.5.7 CSV存储引擎:
CSV存储引擎实际上操做的就是一个标准的CSV文件,他不支持索引。起主要用途就是你们有些时候可能会须要经过数据库中的数据导出成一份报表文件,而CSV文件是不少软件都支持的一种较为标准的格式,因此咱们能够经过先在数据库中创建一张CVS表,而后将生成的报表信息插入到该表,便可获得一份CSV报表文件了。
3.6 小结
多存储引擎是 MySQL 有别于其余数据库管理软件的最大特点,不一样的存储引擎有不一样的特色,能够应对不一样的应用场景,这让咱们在实际的应用中能够根据不一样的应用特色来选择最有利的存储引擎,给了咱们足够的灵活性。经过这一章对 MySQL 各个存储引擎的初步了解,我想各位读者朋友应该已经对 MySQL 的主要存储引擎有了必定的认识,在后续的章节中对于一些经常使用的存储引擎还会有更为深刻的介绍。
sql
摘自:《MySQL性能调优与架构设计》简朝阳数据库
转载请注明出处:后端