本篇从MySQL架构入手进行记录说明。
一、体系结构
这里我们从逻辑上把它划分为四层:
- 用户请求层(客户端);
- Server层;
- 存储引擎层;
- 文件系统层。
图1
二、模块作用
连接器
管理客户端的连接,权限验证。
查询缓存
建立连接之后发去查询,如果缓存里有则直接返回,否则进行下一步。
分析器
和编译器中的分析器同理,包括词法分析、语法分析。
词法分析就是查询语句每个词是否写错,语法器就是分析这条语句的语法是否对。
优化器
对查询语句的优化,索引选择等。
执行器
将查询语句与引擎进行交互,获取返回结果。
三、存储结构
这里我们只针对InnoDB存储引擎来讲。InnoDB将存储的数据按表空间来进行存放。
【物理存储结构】
InnoDB表由以下部分组成:
- 共享表空间(ibdata1)。
- 独占表空间文件(ibd),包括索引和数据文件。
- 表结构文件文件(.frm)。
- 日志文件(redo文件等)。
InnoDB对文件的存储方式如下:
图2
设置如下参数时
[mysqld]
innodb_data_file_path = /db/ibdata1:2000M;
所有基于InnoDB存储表的数据都会记录到共享空间表
InnoDB share tablespace中,即ibdata1。
当设置如下参数时
[mysqld]
innodb_file_per_table=ON;
则会产生单独的.ibd独立表空间文件。这些独立的表空间文件仅存储该表的数据、索引和插入缓冲BITMAP等信息,其它信息还是存放在共享表(InnoDB share tablespace)中。
【逻辑存储结构】
从InnoDB存储引擎的逻辑存储结构来看,所有数据都被逻辑地存放在一个表空间中。
表空间组成部分如下:
- 段(segment)
- 区(extent)
- 页(page),有些文档中称为块(block)
InnoDB逻辑存储结构大致如下图:
图3
表空间
表空间可看着是InnoDB存储引擎逻辑结构的最高层,所有的数据都存放在表空间中。如上文所速,在默认情况下InnoDB存储引擎有一个共享表空间ibdata1
,所有的数据都存放在这个表空间内。
如果用户启用了参数innodb_file_per_table=ON
,则每张表内的数据单独存到一个表空间内,记住表内只存放数据、索引和插入缓冲Bitmap页,其它类的数据,如回滚(undo)信息,插入缓冲索引页、系统事务信息,二次写缓冲(Double write buffer)等还是存放在原来的共享表内。
段
表空间是由各个段组成的,常见的端有数据段、索引段、回滚段等。InnoDB存储引擎表是索引组织的,因此数据即索引,索引即数据。数据段则是B+树的叶子节点(图3中Leaf node segment),索引段则是B+树的非索引节点(图3中Non-leaf node segment)。在InnoDB存储引擎中,对段的管理都是由引擎自身完成的。
区
区是有连续页组成,在任何情况下每个区的大小都为1MB。为保证区中页的连续性,InnoDB存储引擎一次从磁盘申请4~5个区。
默认情况下,InnoDB存储引擎页的大小为16KB,即一个区中一共有64个连续的页。
InnoDB 1.0.x版本开始引入压缩页,即每个页的大小可以通过参数KEY_BLOCK_SIZE
设置为2K、4K、8K,因此每个区对应页的数量就应该为512、256、128。
InnoDB 1.2.x版本新增了参数innodb_page_size,通过该参数可以将默认页的大小设置为4K、8K,但是页中的数据不是压缩的,这时区中页的数量同样也为256、128。总之,不论页的大小怎么变化,区的大小总是为1M。
页
对页的大小相关参数,在上诉区中已介绍。这里记住一点,如果通过innodb_page_size
设置了页的大小,则表中页的大小都为innodb_page_size大小,不可以对其再次进行修改。除非通过mysqldump导入和导出操作来产生新的库。
在InnoDB存储引擎中,常见的页类型有:
- 数据页(B-tree Node)
- undo页(undo Log Page)
- 系统页(System Page)
- 事务数据页(Transaction system Page)
- 插入缓冲位图页(Insert Buffer Bitmap)
- 插入缓冲空闲列表页(Insert Buffer Free List)
- 未压缩的二进制大对象页(Uncompressed BLOB Page)
- 压缩的二进制大对象页(compressed BLOB Page)
行
InnoDB存储引擎是面向列的(row-oriented),也就是说数据是按行进行存放的。每个页存放的行记录也是有硬性规定的,最多允许存放16KB/2-200行记录,即7992行。