参考:https://dev.mysql.com/doc/refman/5.7/en/innodb-architecture.html
结构图:
一 内存中结构
1 缓冲池
缓冲表和索引数据,高频数据,缓冲池写磁盘时候一般直接写入系统表空间的双写缓冲区。对数据库数据进行操作时都是先读取到内存缓冲区进行操作后再写入磁盘。
缓冲池划分为若干页(链表)存储多行数据,采用LRU算法(最近最少使用)管理页。若需要增加页时,最近最少使用的页移除并且将新页添加在链表中间将链表划分为两块,新表5/8和旧表3/8。链表头部是常访问的,链表尾部是较低频次访问的,新页作为旧部的头。若旧部的页被访问到,则移动该页到链表头部,若链表中某页长时间不访问则移动到链表尾部。
2 变更缓冲区
用来存储二级索引变更的数据结构(缓冲池没有该内容),可能由insert,update,delete等dml操作造成的。后面会由读操作将页面加载到缓冲池合并。缓冲池周期性地将更改地索引页写进磁盘。在内存中,变更缓冲区属于缓冲池一部分,磁盘上,缓冲区属于系统表空间一部分,当数据库服务拓机时,索引变更存储在内存变更缓冲区。
3 自适应哈希索引
由系统变量 innodb_adaptive_hash_index开启。哈希索引由索引的前缀构建成。
4 日志缓冲区
记录要写进磁盘日志文件的数据,日志缓冲区大小由变量innodb_log_buffer_size配置,默认大小是16MB。日志缓冲区地内容周期性地写进磁盘日志文件中(redo),较大地日志缓冲区可以支持事务在提交前不必直接写磁盘redo文件,因此若有较多地dml操作事务,建议增大缓冲区减少磁盘IO。系统变量innodb_flush_log_at_trx_commit控制如何将缓存区内容写进磁盘,变量innodb_flush_log_at_timeout控制写磁盘地频率。
二 磁盘中结构
1. 表
InnoDB表和其索引一般创建在系统表空间中,独立表空间或者通用表空间。当参数innodb_file_per_table开启时并且是默认时,表被创建在独立的表空间。相反地,当参数没有开启时,表显式地创建在系统表空间。当创建一个InnoDB表时,在数据库目录MySQl会创建一个 .frm文件,当表创建在独立表空间时,默认会在数据库目录创建一个 .ibd表空间文件。
MySQL将表的数据词典信息存储在数据库目录的 .frm文件中。InnoDB还在系统表空间中自己的内部数据字典中对表的信息进行编码。
默认的行格式由参数innodb_default_row_format=DYNAMIC确定。若要使用Dynamic和compressed格式,参数innodb_file_per_table必须开启,innodb_file_format为Barracuda。或者,可以采用建表语句显式指定通用表空间,它支持所有行格式。
页大小为16kB时,一个表能够包含最大1017列(5.6.9版本前是1000),最大64个二级索引,如果大索引开启则能支持最大3072字节索引长度,否则是767字节长度,这些索引现在同样受限于联合索引。当页大小变为8KB或者4KB时,大索引长度按比例缩小至1536字节,768字节。联合索引最多16列。16KB页大小,不包括变长列的最大行长度为8000字节,64KB(65535 byte)页大小时,相应增长到16000字节。LONGBLOB,LONGTEXT小于4GB,包括BLOB和TEXT的列总长度小于4GB。当行长度小于页大小一半时,所有列存储内页内,若超过则变长列存储在溢出页。表空间大小大于10MB,最大依赖页大小,同样也是表的最大大小。行格式为Compressed的,页大小最大16KB。不同也大小的数据文件和日志文件不兼容。
InnoDB Page Size |
Maximum Tablespace Size |
4KB |
16TB |
8KB |
32TB |
16KB |
64TB |
32KB |
128TB |
64KB |
256TB |
2. 索引
2.1 聚集索引和二级索引
InnoDB表上的主键作为聚集索引,如果表上没有主键则InnoDB寻找到一个non-null且unique列作为聚集索引。如果都没有,则自主创建一个包含行ID的隐藏聚集索引。
一般情况下,根据聚集索引获取行会比较快,它会直接指向全部行数据存储的页。二级索引包含主键和用户定义的索引,走二级索引时先查出二级索引表中的主键,再回表根据主键去聚集索引查找数据。
2.2 InnoDB 索引的物理结构
InnoDB索引采用B-tree数据结构,空间索引采用R-tree数据结构,专为多维数据设计。索引记录存储在B-tree或者R-tree的叶子节点。
当由新记录插入InnoDB的聚集索引,InnoDB会尝试为后来的记录保留1/16空间。如果记录是有序插入,则索引页则可以存储15/16页大小,若无序,则可存储1/2到15/16页大小。
2.3 构建索引
三阶段构建索引,一,扫描聚集索引生成一个索引项并且将其添加到排序缓冲区。当缓冲区满了时,条目排序后会被写入一个临时中间文件。这个过程也称为运行(run)。二,当一个或多个运行写入临时中间文件时,对文件中所有条目执行合并排序。三,最终阶段,有序的条目插入到B-tree中。
2.4 FULLTEXT索引
FULLTEXT索引建立在CHAR, VARCHAR, TEXT列上,以加速查询和DML操作。FULLTEXT索引可以在建表时添加也可以修改表添加,搜索时用MATCH()…AGAINST语法。