插件式存储引擎架构,灵活的处理方式,高度可定制化及完全开放的实现
MySQL存储引擎概述
MyISAM存储引擎是MySQL默认的存储引擎。它的前身是ISAM,是ISAM的升级版本。
在MySQL 5.1之前(不包括5.1),存储引擎必须在MySQL安装的时候和MySQL一起被编译并同时被安装。
5.1版之前,虽然存储引擎层和sql层的耦合已经非常少了,基本上完全是通过接口来实现交互的,但是这两层之间仍然没办法分离,即使在安装的时候也是一样。
从MySQL 5.1开始,MySQL AB对其结构体系做了较大的改造,并引入了一个新的概念:插件式存储引擎体系结构。MySQL AB 在改造架构的时候,让存储引擎层和SQL层各自更为独立,耦合更小,甚至可以做到在线加载新的存储引擎,完全可以将一个新的存储引擎加载到一个正在运行的MySQL中,且不影响MySQL的正常运行。
插件式存储引擎的架构,使得存储引擎的加载和移出更为灵活方便,也使自行开发存储引擎更为方便简单。
插件式存储引擎的架构只有MySQL实现了。
MySQL的插件式存储引擎包括MyISAM、InnoDB、NDB Cluster、Maria、Falcon、Memory、Archive、Merge、Federated等。
使用最为广泛的是MyISAM和InnoDB。
MyISAM是MySQL最早的ISAM存储引擎的升级版本,也是MySQL默认存储引擎。
InnoDB是Innobase软件公司(2005年被Oracle收购)开发的,提供了事务控制等特性。
其他一些存储引擎应用于某些特定的场合,NDB Cluster也支持事务,但是主要用于分布式环境,属于一个share nothing的分布式数据库存储引擎。
Maria是MySQL最新开发(还没有发布最终的GA版本)的MyISAM的升级版存储引擎,Falcon是MySQL公司自行研发的替代当前InnoDB存储引擎的一款带有事务等高级特性的数据库存储引擎,目前正在研发阶段。
Memory存储引擎的所有数据和索引均存储于内存中,主要是用于一些临时表,或者对性能要求极高,但是允许在系统崩溃(crash)的时候丢失数据的特定场合。
Archive是一个数据经过高比例压缩存放的存储引擎,主要用于存放过期而且很少访问的历史信息,不支持索引。
Merge和Federated严格上并不能算作存储引擎。Merge存储引擎主要用于将几个基表中的数据合并(merge)到一起,对外作为一个表来提供服务,基表主要基于MyISAM存储引擎。
Federated有点类似于Oracle的dblink,主要用于远程存取其他MySQL服务器上面的数据。
MyISAM存储引擎简介
MyISAM存储引擎的每一个表都被存放为三个以表名命名的物理文件。
首先有任何存储引擎都不可缺少的存放表结构定义信息的.frm文件,.MYD(表的数据)和.MYI索引数据文件。
每个表都有且仅有这样三个文件作为MyISAM存储类型的表的存储,也就是说不管这个表有多少个索引,都存放在同一个.MYI文件中。
MyISAM存储引擎简介——索引——B-Tree索引
所有的索引节点都按照balance tree的数据结构来存储,所有的索引数据节点都在叶节点。
MyISAM存储引擎简介——索引——R-Tree索引
R-Tree索引的存储方式和b-tree索引有一些区别,主要设计用于为存储空间和多维数据的字段做索引,目前的MySQL版本仅支持geometry类型的字段作索引。
MyISAM存储引擎简介——索引——Full-text索引
Full-text索引(全文索引),它的存储结构也是b-tree。主要是为了解决当须要用like查询时的低效问题。
MyISAM存储引擎简介——索引——总结
最经常使用的是B-Tree索引,偶尔用到Full-text,R-Tree索引很少用到。
MyISAM的B-Tree索引有一个较大的限制,那就是参与一个索引的所有字段的长度之和不能超过1 000字节。
MyISAM存储引擎简介——.MYD文件
虽然每一个MyISAM的表都是存放在一个相同后缀名的.MYD文件中的,但是每个文件的存放格式并不完全一样,MyISAM的数据存放格式分为静态(FIXED)固定长度、动态(DYNAMIC)可变长度及压缩(COMPRESSED)。
三种格式是可以任由选择,在创建表的时候通过ROW_FORMAT
来指定{COMPRESSED| DEFAULT}
,也可以通过MyISAMpack工具来进行压缩,默认是不压缩的。
而在非压缩的情况下,是静态还是动态,和表中字段的定义相关。只要表中有可变长度类型的字段存在,该表就肯定是DYNAMIC格式的,如果没有任何可变长度的字段,则为FIXED格式,可以通过Alter Table命令,强行将一个带有VARCHAR类型字段的DYNAMIC的表转换为FIXED,但是所带来的结果是原VARCHAR
字段类型会被自动转换成CHAR
类型。相反如果将FIXED转换为DYNAMIC,也会将CHAR
类型字段转换为Varchar
类型,所以强行转换时一定要谨慎。
MyISAM存储引擎简介——MyISAM存储引擎的表可靠性
如下情况时可能会出现的表文件损坏:
(1)当MySQL正在做写操作的时候被中止(kill)或其他情况造成异常终止;
(2)主机崩溃(crash);
(3)磁盘硬件故障;
(4)MyISAM存储引擎中的Bug。
MyISAM存储引擎的某个表文件出错之后,仅影响到该表,不会影响到其他表,更不会影响到数据库。
如果数据库正在运行过程中发现某个MyISAM表出现问题了,可以在线通过Check Table命令来尝试校验它,并可以通过repair table命令来尝试修复。
在数据库关闭状态下,也可以通过myisamchk工具来对数据库中的某个(或某些)表进行检测或修复。
建议不到万不得已不要轻易对表进行修复操作,修复之前尽量做好可能的备份工作,以免带来不必要的后果。
MyISAM存储引擎的表理论上是可以被多个数据库实例同时使用同时操作的,但是不建议这样做。
InnoDB存储引擎简介
InnoDB作为第三方公司所开发的存储引擎,和MySQL遵守相同的开源许可证协议。
InnoDB存储引擎简介——特点
- 支持事务安全
实现了SQL92标准所定义的所有4个级别的要求(READ UNCOMMITTED、READ COMMITTED、REPEATABLE和SERIALIZABLE)。 - 数据多版本读取
InnoDB在事务支持的同时,为了保证数据的一致性及并发的性能,通过UNDO信息实现了数据的多版本读取。 - 锁定机制的改进
InnoDB改变了MyISAM的锁机制,实现了行锁。InnoDB行锁机制的实现是通过索引来完成的,但在数据库中,99%的SQL语句都是要使用索引来做数据检索的。
行锁定机制也无疑为InnoDB在承受高并发压力的环境下增强了不小的竞争力。 - 实现外键
InnoDB实现了外键引用这一数据库的重要特性,使在数据库端控制部分数据的完整性成为可能。建议使用外键。
InnoDB存储引擎简介——物理存储
.frm文件来存放表结构定义相关的元数据,表数据和索引数据是存放在一起的。
每表单独使用独享表空间存放还是所有表一起使用共享表空间,完全由用户决定(通过特定配置),同时还支持符号链接。
InnoDB存储引擎简介——物理结构
- 数据文件(表数据和索引数据)
存放在数据表中的数据和所有的索引数据,包括主键和其他普通索引。
InnoDB的表空间分为两种形式。一种是共享表空间,也就是所有表数据、索引数据、各种元数据及事务的UNDO数据都被存放在同一个表空间(一个或多个数据文件)中,通过innodb_data_file_path来指定,增加数据文件须要停机重启。
另外一种是独享表空间,也就是每个表的数据和索引被存放在一个单独的.ibd
文件中,该文件包括每个表的表数据、索引数据及该表相关的事务UNDO数据。
可以自由选择使用共享表空间还是独享表空间来存放数据,但是共享表空间是必须存在的,因为InnoDB各表的很多元数据信息都是存放在共享表空间中的。
共享表空间的数据文件可以设置固定大小和可动态扩展两种形式,动态扩展形式的文件可以设置文件的容量和每次的扩展量。
在创建自动扩展的数据文件时,建议最好加上最大尺寸的属性,一是因为文件系统本身是有一定大小限制的(但是InnoDB并不知道),另一个原因就是自身维护的方便。
当共享表空间快要用完的时候,必须要为其增加数据文件。
共享表空间增加数据文件的操作比较简单,只须要在innodb_data_file_path
参数后面按照标准格式设置好文件路径和相关属性即可,InnoDB在创建新数据文件的时候是不会创建目录的,如果指定的目录不存在,则会报错,导致MySQL无法启动。
InnoDB在给共享表空间增加数据文件之后,必须要重启数据库系统才能生效,如果是使用裸设备,还须要重启两次。
2.日志文件
InnoDB的日志文件类似Oracle的REDO日志,采用轮循策略来写入,在老版本中还有和Oracle一样的日志归档特性。
如果使用了InnoDB的表,那么千万别删除InnoDB的日志文件,因为这很可能会让数据库崩溃,且无法重新启动。
由于InnoDB是事务安全的存储引擎,所以系统崩溃对它来说并不能造成非常严重的损失,由于REDO日志的存在,且有checkpoint机制的保护,InnoDB完全可以通过REDO日志将数据库崩溃时已经完成但还没有来得及将内存中已经修改的但未完全写入磁盘的数据进行重做操作(Rodo)写入数据文件,也能够将所有已部分完成并写入磁盘的未完成事务进行回滚操作(Undo),保证数据的一致性。
InnoDB存储引擎简介——配置
InnoDB的所有参数都带有前缀“innodb_
”,不论是和InnoDB数据及日志相关的,还是和其他一些性能、事务等相关的参数都是一样。
skip-innodb
屏蔽MySQL中的InnoDB存储引擎,这样即使在安装编译的时候将InnoDB存储引擎安装进去了,使用者也无法创建InnoDB的表。
NDB Cluster存储引擎简介
NDB存储引擎(NDB Cluster存储引擎),用于MySQL Cluster分布式集群环境,Cluster是MySQL从5.0版本才开始提供的新功能。
MySQL Cluster就是在无共享存储设备的情况下实现的一种内存数据库Cluster环境。
NDB Cluster存储引擎简介——组成
- 负责管理各个节点的Manage节点主机
管理节点负责整个Cluster集群中各个节点的管理工作,包括集群的配置,启动关闭各节点,以及实施数据的备份恢复等。
管理节点会获取整个Cluster环境中各节点的状态和错误信息,并且将各Cluster集群中各个节点的信息反馈给整个集群中其他的所有节点。
由于管理节点上保存在整个Cluster环境的配置,同时担任了集群中各节点的基本沟通工作,所以它必须是最先被启动的节点。
SQL层的SQL服务器节点(SQL节点)——MySQL Server
主要负责实现一个数据库在存储层之上的所有事情,比如连接管理,query优化和响应,Cache管理,只有存储层的工作会交给NDB数据节点去处理。在纯粹的MySQL Cluster环境中的SQL节点,可以被认为是一个不须要提供任何存储引擎的SQL服务器,因为它的存储引擎由Cluster环境中的NDB节点来担任。
SQL层各SQL服务器的启动与普通的MySQL启动有一定的区别,必须添加ndbcluster项,可以添加在my.cnf配置文件中,也可以通过启动命令行来指定。Storage层的NDB数据节点——NDB Cluster
NDB是一个内存式存储引擎,它会将所有的数据和索引数据都加载到内存中,也会将数据持久化到存储设备上。
最新版本已经支持非索引字段数据不用全部加载到内存中了。
NDB节点主要是实现底层数据存储的功能,保存Cluster的数据。每一个NDB节点保存完整数据的一部分(或者一份完整的数据,视节点数目和配置而定),在MySQL CLuster里面叫做fragment。
每一个fragment,正常情况来讲都会在其他的主机上面有一份(或者多份)完全相同的镜像存在。这些都是通过配置来完成的,所以只要配置得当,MySQL Cluster在存储层就不会出现单点的问题。
NDB节点被组织成一个一个的NDB Group,一个NDB Group实际上就是一组存有完全相同的物理数据的NDB节点群。
NDB各个节点对数据的组织,可能每个节点都存有全部的数据,也可能只保存一部分数据,主要是受节点数目和参数来控制的。首先在MySQL Cluster主配置文件(在管理节点上面config.ini
)中,参数NoOfReplicas
指定了每一份数据被冗余存储在不同节点上面的份数,该参数一般也只须设置成2。
一个节点上面是保存所有的数据还是一部分数据,还受到存储节点数目的限制。
NDB存储引擎首先保证NoOfReplicas参数配置的要求来对数据冗余,并使用存储节点,然后再根据节点数目将数据分段来继续使用多余的NDB节点,分段的数目为节点总数除以NoOfReplicas所得。
Merge存储引擎
MRG_MyISAM存储引擎。
Merge存储引擎对结构相同的MyISAM表通过一些特殊的包装对外提供一个单一的访问入口,从而达到减小应用复杂度的目的。
要创建MERGE表,不仅基表的结构要完全一致,包括字段的顺序、基表的索引也必须完全一致。
MERGE表本身并不存储数据,仅仅是为多个基表提供一个统一的存储入口。在创建MERGE表的时候,MySQL只会生成两个较小的文件,一个是.frm的结构定义文件,还有一个.MRG文件,用于存放参与MERGE表的名称(包括所属数据库schema)。
之所以需要所属数据库的schema,是因为MERGE表不仅可以实现合并(merge)同一个数据库中的表,还可以合并不同数据库中的表,只要权限允许,并且在同一个MySQL Inctance中,就可以进行合并。MERGE表在被创建之后,仍然可以通过相关命令来更改底层的基表。
MERGE表不仅可以提供读取服务,也可以提供写入服务。要让MERGE表提供可INSERT服务,必须在表被创建的时候就指明INSERT数据要被写入哪一个基表,可以通过insert_method参数来控制。如果没有指定该参数,任何尝试往MERGE表中插入(insert)数据的操作,都会出错。
无法通过MERGE表直接使用基表上面的全文索引,要使用全文索引,必须通过基表本身的存取操作才能实现。
Memory存储引擎
Memory存储引擎是一个将数据存储在内存中的存储引擎。
Memory存储引擎不会将任何数据存放到磁盘上,在磁盘上仅仅存放了一个表结构相关信息的.frm文件。
一旦MySQL崩溃(crash)或主机崩溃之后,Memory的表就只剩下一个结构了。Memory表支持索引,并且同时支持Hash和B-Tree两种格式的索引。
由于是存放在内存中,所以Memory都是按照定长的空间来存储数据的,而且不支持BLOB和TEXT类型的字段。
Memory存储引擎实现页级锁定。
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*))
BDB存储引擎
BDB存储引擎(BerkeleyDB存储引擎)由Sleepycat Software公司提供,是开源存储引擎,同样支持事务安全。
BDB存储引擎的数据存放也是每个表两个物理文件,一个.frm和一个.db的文件,数据和索引信息都是存放在.db文件中。
BDB为了实现事务安全,也有自己的REDO日志,、可以通过参数指定日志文件存放的位置。
在锁定机制方面,BDB实现页级锁定。
由于BDB存储引擎实现了事务安全,那么它肯定也需要自己的check point机制。BDB在每次启动的时候,都会做一次check point操作,并且将之前的所有REDO日志清空。在运行过程中,也可以通过执行flush logs来手工对BDB进行check point操作。
FEDERATED存储引擎
FEDERATED存储引擎所实现的功能和Oracle的DBLINK基本相似,主要用来提供对远程MySQL服务器上面的数据的访问接口。使用源码编译安装MySQL,必须手工指定启用FEDERATED存储引擎,MySQL默认不启用该存储引擎。
创建一个FEDERATED表的时候,在本地仅仅创建了表的结构定义信息文件,所有数据均实时取自远程MySQL服务器上面的数据库。
当通过Query操作FEDERATED表的时候,实现过程基本如下:
a. Query调用本地接口
b. 本地接口调用MySQL Server API
c. MySQL Server调用客户端API访问远程数据库
d. 远程数据库调用MySQL客户端API
e. 转换结果包(如果有的话)到相关格式
f. MySQL Server API返回结果行或受行影响行计数信息
ARCHIVE存储引擎
ARCHIVE存储引擎主要用于通过较小的存储空间来存放过期的很少访问的历史数据。ARCHIVE表不支持索引,包含一个.frm的结构定义文件,一个.ARZ的数据压缩文件,还有一个.ARM的元数据信息文件。由于其所存放的数据的特殊性,ARCHIVE表不支持删除、修改操作,仅支持插入和查询操作。锁定机制为行级锁定。
BLACKHOLE存储引擎
BLACKHOLE存储引擎就像Unix系统下“/dev/null”设备一样,不管写入任何信息,都是有去无回。
用途:
a.在数据迁移过程中,数据须要经过一个中转的MySQL服务器做一些相关的转换操作,然后再通过复制移植到新的服务器上面。如果没有足够的空间来支持这个中转服务器的运作。这时候就可以使用BLACKHOLE,它不会记录下任何数据,但是会在binlog中记录下所有的Query。而这些Query最终都会被复制利用,并实施到最终的slave端。
b. Query语法的验证。
c. 测试二进制日志记录的性能开销,如通过比较允许二进制日志功能的BLACKHOLE与禁止二进制日志功能的BLACKHOLE的性能来实现。
d. 查找与存储引擎自身不相关的性能瓶颈,因为BLACKHOLE本质上是一个“no-op”的存储引擎。
CSV存储引擎
CSV存储引擎操作的是一个标准的CSV文件,它不支持索引。
把数据库中的数据导出一份报表文件,而CSV文件是很多软件都支持的一种标准格式,可以先在数据库中建立一张CVS表,然后将生成的报表信息插入该表,即可得到一份CSV报表文件了。
小结
多存储引擎是MySQL有别于其他数据库管理软件的最大特色,不同的存储引擎有不同的特点,可以应对不同的应用场景。