1、MySQL逻辑架构
MySQL逻辑架构主要分为3层,如下图所示:
1.1、连接层
作用:用于与客户端的连接处理、授权认证、安全、权限校验等。
每个客户端连接,在MySQL服务器端都会有一个线程与其相互对应,这个线程负责处理这个客户端连接的操作。为了避免大量线程的创建和销毁,MySQL使用了线程池技术。客户端使用正确的认证信息与服务器端连接成功后,MySQL还会对其权限进行校验(例如是否允许访问某张具体的表)。
1.2、服务器层
作用:实现了MySQL的核心服务功能,包括查询解析、分析、优化、内置函数的实现(日期、时间、数学和加密等函数),此外,所有跨存储引擎层的功能也是在服务器层实现:存储过程、触发器、视图等。
MySQL会对查询进行解析、优化,比如重写查询、决定表的顺序、选择合适的索引。用户可以通过关键字(hint)提示优化器,影响MySQL的优化策略。同时,也可以使用关键字explain请求优化器解释优化过程中的各个因素,从而作为优化查询语句性能的依据。
对于查询语句,MySQL首先会查询缓存,如果缓存命中了,就不会再对查询语句进行解析、优化以及调用存储引擎层进行查询。
1.3、存储引擎层
作用:真正负责MySQL中数据的存储和读写。MySQL支持多个存储引擎,它们实现了一套相同的API(类似于Java的一个接口对应多个实现)。服务器层通过API与存储引擎通信,存储引擎内部实现对上层来说是透明的。
5.2+中MySQL中默认的存储引擎是InnoDB,这也是最常用的存储引擎,除非有特殊需求,否则不推荐使用其他存储引擎。
MySQL中支持创建多个数据库,每个数据库的数据保存在MySQL数据目录下面的一个子目录中。创建表时,MySQL会在数据的子目录中创建一个与表名同名的.frm文件保存表的定义。如下图所示。
2、MySQL常见存储引擎
通常来说,除非需要用到一些InnoDB不具备的特性,且没有其他办法替代,否则都应该选择InnoDB。例如,如果需要用到全文索引,可以使用Sphinx配合InnoDB,而非选择MyISAM。
如果不需要用到InnoDB的一些特性,且其他存储引擎能够更好的满足需求,也可以考虑使用其他引擎。
注意:尽量不要混合使用多个存储引擎,否则,在事务、备份等场景可能会导致不可预见的问题。
2.1、InnoDB
InnoDB是MySQL的默认事务型引擎。它采用MVCC(多版本并发控制)实现了高并发,并实现了四个标准的隔离级别,其默认隔离级别是可重复读。并且通过间隙锁策略避免了幻读。间隙锁不仅锁定了查询涉及的行,还对索引中的间隙进行了锁定,防止了幻影行的插入。
与其他存储引擎不同的是,InnoDB的表是基于聚簇索引构建的,因此对于主键查询具有很好的性能。不过,它的二级索引(非主键索引)中必须包含主键列,所以,如果主键列很大,其他的索引都会很大。因此,如果表上的索引较多,主键应该尽可能的小。
InnoDB内部采用了很多技术进行优化,比如:从磁盘读取数据时采用可预测性预读;能够自动在内存中创建hash索引以加速读操作的自适应哈希索引;能够加速插入操作的插入缓冲区。
此外,InnoDB支持真正的热备份。
2.2、MyISAM
MyISAM是MySQL5.1及之前版本中的默认存储引擎。它支持全文索引、压缩等多个特性,但是MyISAM不支持事务和行级锁,只支持表锁。而且它崩溃后,无法保证安全恢复数据。MyISAM比较适合于只读的场景,或者表比较小、能够忍受恢复操作的场景。但是,仍然建议使用InnoDB。
MyISAM将表的数据存放在两个文件中:数据文件和索引文件。
MyISAM只支持表锁,不支持行锁。读取时对整张表加共享锁,写入时对整张表加排他锁。但在表有读取查询的同时,MyISAM也支持对表进行插入,这就是MyISAM的并发插入(Concurrent Insert)。
2.3、其它存储引擎
MySQL内置了其他的存储引擎,包括:Archive引擎、Blackhole引擎、CSV引擎、Federated引擎、Memory引擎、Merge引擎、NDB集群引擎。此外,还有一些其他的三方引擎:OLTP类引擎、面向列的存储引擎等。
2.4、改变表的存储引擎
对于已经创建的表,如果需要修改其使用的存储引擎,通常有以下方法:
修改表的结构:alter table。耗时长,MySQL会对原表加上读锁,然后将数据按照行复制到一张新的表中,可能会消耗掉系统所有的IO资源。
导出与导入:使用mysqldump工具将工具导出到文件,然后修改create table语句的存储引擎选项,并修改表名,然后再对文件进行导入。
创建与查询:综合第一种的高效和第二种的安全,创建一张新表,然后使用insert .. select ...的语法,查询出原表中所有的数据并写入到新表中。如果数据量很大,这个过程可以分批进行。