MySQL InnoDB Architecture 简要介绍

这篇具有很好参考价值的文章主要介绍了MySQL InnoDB Architecture 简要介绍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

MySQL InnoDB 存储引擎整体架构图:

一、内存存储结构

 1、Buffer Pool

buffer pool 是主内存中的一块儿存储区域,用于存储访问的表及索引数据。这样从内存中直接访问获取使用的数据可以极大的提升访问效率。在一些特殊专用的服务里,几乎 80% 的内存区域都被赋于 buffer pool。

为了提升大数据量读操作效率,buffer pool 被设计划分为能够存储多条记录的数据页。同时,基于链表结构存储实现,LRU算法支持,能够极大的提高缓存管理的效率。

Buffer Pool LRU 算法

buffer pool 使用基于LRU算法的列表数据结构实现。当需要添加新的数据页,最近最少使用的数据页会淘汰,新的数据页会被插入到列表的中间。

中间插入策略会把列表当成两个子列表:

  • 头部用于存储新的最新访问的数据页。

  • 尾部用于存储旧的最少访问的数据页

如下图:Buffer Pool List


算法会将频繁访问的数据页放在新的子列表;最少访问的记录存放在旧列表,并逐渐淘汰。

通常 LRU 算法按如下方式运行:

  • buffer pool 总量的 3/8 会分配给旧列表。

  • 列表的中间包括新列表的尾部和旧列表的头部。

  • 当 InnoDB 读入一个新的数据页时,会先将其插入列表中间(旧列表的头部)。

  • 旧的子列表数据访问会改变其数据特性,并将其移动到新的子列表头部(预读操作除外)。

  • 随着数据库操作的执行,buffer pool 中未被访问的页数据会逐渐移动到列表的尾部,并淘汰。

通常情况下,被访问的数据会转移到新的子列表,这样就能在 buffer pool 中待更长的时间。一些特定的情景,如 mysqldump 操作导致的表扫描或者没有附加 where 条件的 select 查询会导致大量的数据写入 buffer pool,并淘汰旧的记录。但是这些新的记录可能永远不会被使用。

2、Change Buffer

change buffer 用于缓存那些不在 buffer pool 存储的二级索引页数据变化。并最终会合并到 buffer pool(当这些页数据被其它读操作载入后)。

如下入示意 Change Buffer:


和聚簇索引不同的是,二级索引通常都非唯一,并且写入顺序随机。同样的,删除和更新操作可能会影响不相邻的多个索引页数据。因此,在其它读操作将受影响的索引页数载入 bufer pool 时合并缓存的索引变更,可以避免再次从磁盘随机IO读取二级索引页数据。

purge operation 会周期性的把更新的页数据批量写入磁盘,这样比即时单条写入更有效率。

当涉及二级索引变更记录比较多时,Change buffer 数据合并可能会花费几个小时。在此期间,磁盘 IO 会增加,进而会影响磁盘密集型查询。

在内存中,change buffer 会占用一部分的 buffer pool 存储使用。在磁盘里,change buffer 是 system tablespace 的一部分,用以存储数据库服务器关机时产生的索引变化数据。

3、 Adaptive Hash Index

自适应哈希索引使得 InnoDB 支持基于内存的数据库,通过 innodb_adaptive_hash_index 配置启用。

基于当前的搜索模式,哈希索引使用索引键前缀来构建。前缀可长可短,根据实际查询需求而定。

4、Log Buffer

存储内存日志数据,用于磁盘日志文件数据写入。配置:innodb_log_buffer_size。默认大小 16MB。log buffer 的数据会周期性的刷盘。较大的 log buffer 有利于较大的事务日志数据写入需求。对于执行大批量更新、写入或删除操作的事务可以适当调高 log buffer 以减少磁盘IO。

二、磁盘存储结构

1、Index 索引

a)聚簇索引及二级索引

基于 InnoDB 引擎的表使用一种称之为聚簇索引的特殊索引来存储行数据。通常情况下,聚簇索引等同于主键索引。

  • InnoDB 会使用表上定义的主键来作为聚簇索引,如果当前表没有能够作为主键的列(数据逻辑唯一非空的单列或者多列组合),则可以添加自增列作为非业务主键。
  • 如果表未定义主键,则 InnoDB 会使用首个唯一索引(所有列非空)作为聚簇索引。
  • 如果表既没有主键也没有合适的唯一索引,则 InnoDB 会为表创建一个隐藏的聚簇索引 GEN_CLUST_INDEX,该索引基于 InnoDB 为表自动添加的包含行ID值的列,所有表数据会基于该ID值排序。行ID值是一个6字节数值,会随着数据的插入单调递增,因此基于此列排序的表在物理上保持着数据插入顺序。

除了聚簇索引,其它的索引都是二级锁索引,二级索引除了设置的索引列外,还包含主键,最终 InnoDB 都要通过主键来查找聚簇索引里的数据。

如果主键过长,那么二级索引就会占用更大的空间,所以,通常我们都建议设置较短的主键。

B 树索引使用:

  • 支持列 =、>、>=、<、<= 及 BETWEEN 操作。
  • like 操作支持:like 后面的参数需要为常量并且不能以通配符起始。
    //可以命中索引
    SELECT * FROM tbl_name WHERE key_col LIKE 'Patrick%';
    SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%';
    
    //无法使用索引
    SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';
    SELECT * FROM tbl_name WHERE key_col LIKE other_col;
  • 对于 is NULL 条件,如果条件列有索引,则查询会使用到索引。  
  • 对于多列复合索引,如果要使用它们,则在每一个 and 条件分组里都必须使用它们:
    如下使用到了索引:
    ... WHERE index_part1=1 AND index_part2=2 AND other_column=3 /* index = 1 OR index = 2 */ ... WHERE index=1 OR A=10 AND index=2 /* optimized like "index_part1='hello'" */ ... WHERE index_part1='hello' AND index_part3=5 /* Can use index on index1 but not on index2 or index3 */ ... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3; 如下未使用到索引 /* index_part1 is not used */ ... WHERE index_part2=1 AND index_part3=2 /* Index is not used in both parts of the WHERE clause */ ... WHERE index=1 OR A=10 /* No index spans all rows */ ... WHERE index_part1=1 OR index_part2=10
  • 一些特殊情况,如优化器测算使用索引会需要访问表中大量的数据,那么即使条件列命中了索引使用条件也不会使用索引。

b)InnoDB 索引物理结构

除了空间索引(基于 R-trees,用以组织存储多维数据),InnoDB 索引都是基于 B-tree 结构。数据存储于树的叶子结点。

索引数据页默认大小为 16KB,可以通过 mysql 实例初始化时的 innodb_page_size 参数来调整。

当向聚簇索引插入新的记录时,InnoDB 会保留1/16页空间用以应对将来可能的插入和更新。如果是顺序插入,则索引页空间会保持差不多15/16大小。如果是随机的,则页空间大小会在1/2 到 15/16之间。一般低于1/2(MERGE_THRESHOLD 配置)会触发索引树压缩。

c)Sorted Index Builds

InnoDB 使用 bulk load 方式执行索引创建或重建,我们称之为 Sorted index build(不支持空间索引)。

索引重建通常分为三步:

  • 扫描聚簇索引,生成索引记录并添加到 sort buffer。sort buffer 满了之后,记录会被排序并写入一个临时的中介文件
  • 随着多个第一步这个过程写入数据到临时中介文件,文件里的索引记录会执行合并。
  • 排序的索引记录写入 B-tree。

在 Sorted index builds 引入之前,B-tree 索引写入使用特定的写入API。首先需要打开一个 B-tree 游标并找到写入位置,然后使用 optimistic  方式将索记录写入 B-tree。当遇到当前写入页满时,optimistic 会执行相应的 B-tree 节点的分裂或者合并操作来满足写入空间需求。这种自上而下的构建方式存在一定的缺点,包括寻址及经常性的节点分裂及合并成本。

Sorted index builds 基于自底而上的方式来构建索引。从 B-tree 每层最右侧的叶子节点开始,基于索引记录顺序写入。当一个节点页写满,则向其父节点添加一个新的子节点用于新的写入。

2、table space 表空间

system table space

用以存储包括 InnoDB data dictionary、the doublewrite buffer、the change buffer 及 undo logs,也可以存储用户主动创建于此的表及索引数据。 

可以有一个或多个数据存储文件,默认为一个 ibdata1,大小和数量可以通过 innodb_data_file_path 进行配置。

File-Per-Table Tablespaces

file-per-table tablespace 包括一张表的数据和索引,以单个数据文件形式存储在文件系统。

InnoDB 默认在 file-per-table tablespaces 创建表,可以通过 innodb_file_per_table 配置变更,禁用则会导致在  system tablespace 创建。

file-per-table tablespace 数据文件形式 table_name.ibd,存储于 MySQL data 文件夹下。

优势:

  • 表 truncate 或者 drop 操作后,磁盘空间会返还操作系统。

  • 操作表复制时的空间额外使用在共享表空间不会返还操作系统。

  • TRUNCATE TABLE 操作性能在 file-per-table tablespaces 表现更优。

  • File-per-table tablespace 数据文件可以创建于不同的存储设备。这使得我们在 IO 优化,空间管理及备份策略等方面有更灵活的操作。

  • 可以从其它 MySQL 实例中倒入表数据。

  •  file-per-table tablespaces 中创建的表使用 Barracuda 文件格式。支持 DYNAMIC 及 COMPRESSED 行格式特性。

  • 减少崩溃恢复使用时间及增加成功率。

  • 基于 MySQL Enterprise Backup 备份和恢复单标数据更加快捷,并且不影响其它表使用。

  • 可以通过监控表空间数据大小来实现表大小的监控。

  • 通常 Linux 系统不允许并发写入同一个文件,当 innodb_flush_method 设置为 O_DIRECT 时,可能会提升数据库性能表现。

  • 单个 file-per-table tablespace  64TB 空间限制,相较于共享表空间可以存储更多的数据。

劣势:
  • 每张表都会存在未使用的空间,只能用于本表记录使用,管理不当会造成空间的浪费。

  • 系统 fsync 操作只针对单个文件,多表写操作会导致系统 fsync 操作增加
  • mysqld  需要对每个 file-per-table tablespace 保持一个打开的文件句柄,如果表数量比较多多的话,可能影响数据库性能。

  • 需要更多的文件描述符。

  • 可能的文件及内存碎片问题会影响 DROP TABLE 及 table scan 操作。如果可以很好的管理碎片问题那么这些操作的性能反而会更好

  • drop 表时会对 buffer pool 进行扫描,扫表会伴随 broad internal lock,,如果 buffer pool 很大的话耗时会很长,进而会影响其它数据库操作。

  • 自动扩展,空间增长不受 innodb_autoextend_increment 配置控制,期初增长因子很小,一段时间会以 4MB 大小增量扩展。

 General Tablespaces  共享的 InnoDB 表空间。
 Undo Tablespaces  undo logs 存储。
 The Temporary Tablespace  非压缩的,用户创建的临时表及磁盘上的内部临时表存储。

3、double buffer 

具体介绍见前文链接:mysql 优化之 doublewrite buffer 机制

4、Redo Log

redo log 是一种基于磁盘的数据结构,用于修正数据库崩溃恢复期间未完成事务造成的数据脏写。

redo log 磁盘存储数据文件为 ib_logfile0 和 ib_logfile1,MySQL 以环形方式写入。

配置修改:1、配置文件 my.cnf;2、大小 innodb_log_file_size;3、数量:innodb_log_files_in_group.

5、Undo logs

记录单个事务中的一系列记录变更,用以恢复对聚簇索引记录的最新变更。如果有其它事务基于一致性读操作需要查看原始数据,可以从 undo log 记录里查询。

6、InnoDB Data Dictionary 

包括一系列系统表,存储包括表、索引及表列等相关元数据,物理存储在系统表空间。由于一些历史原因,data dictionary metadata 部分存储在 InnoDB 表空间文件 (.frm files)。文章来源地址https://www.toymoban.com/news/detail-419267.html

三、附加订阅

MySQL InnoDB Architecture 简要介绍

到了这里,关于MySQL InnoDB Architecture 简要介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL—MySQL的存储引擎之InnoDB

    存储引擎 说明 MyISAM 高速引擎,拥有较高的插入,查询速度,但不支持事务 InnoDB 5.5版本后MySQL的默认数据库存储引擎,支持事务和行级锁,比MyISAM处理速度稍慢 ISAM MyISAM的前身,MySQL5.0以后不再默认安装 MRG_MyISAM 将多个表联合成一个表使用,在超大规模数据存储时很有用 Me

    2024年04月26日
    浏览(40)
  • 谈谈MySQL的InnoDB存储引擎

    大家好,我是易安! 今天我们谈一谈MySQL中InnoDB存储引擎。InnoDB存储引擎作为我们最常用到的存储引擎之一,充分熟悉它的的实现和运行原理,有助于我们更好地创建和维护数据库表。 InnoDB主要包括了内存池、后台线程以及存储文件。内存池又是由多个内存块组成的,主要包

    2024年02月03日
    浏览(37)
  • MySQL 的 InnoDB 存储引擎简介

    MySQL 是世界上最流行的开源关系型数据库管理系统之一,而其中的存储引擎则是其关键组成部分之一。InnoDB 存储引擎在 MySQL 中扮演了重要角色,提供了许多高级功能和性能优化,适用于各种应用程序和工作负载。本文将深入介绍 InnoDB 存储引擎的各个方面,以帮助您更好地理

    2024年02月08日
    浏览(42)
  • MySQL-07.InnoDB数据存储结构

    索引结构给我们提供了高效的索引方式,不过索引信息以及数据记录都是保存在文件上的,确切说是存储在页结构中。另一方面,索引是在存储引擎中实现的,MySQL服务器上的 存储引擎 负责对表中数据的读取和写入工作。不同存储引擎中 存放的格式 一般是不同的,甚至有的

    2024年04月27日
    浏览(42)
  • MySQL的varchar存储原理:InnoDB记录存储结构

    摘要: varchar(M) 能存多少个字符,为什么提示最大16383?innodb怎么知道varchar真正有多长?记录为NULL,innodb如何处理?某个列数据占用的字节数非常多怎么办?影响每行实际可用空间的因素有哪些?本篇围绕innodb默认行格式dynamic来说说原理。 本文分享自华为云社区《MySQL的v

    2024年02月04日
    浏览(41)
  • MySQL高级10-InnoDB引擎存储架构

    表空间(Tablespace):一个mysql实例,及一个数据库实例,可以对应多个表空间(ibd文件),用于存储记录,索引等数据。 段(Segment):分为数据段(Leaf node segment)、索引段(Non-leaf node segment)、回滚段(Rollback segment),InnoDB是索引组织表,数据段就是B+树的叶子节点(Leaf node segment),

    2024年02月08日
    浏览(42)
  • mysql--InnoDB存储引擎--架构和事务

    MySQL进阶篇 InnoDB 逻辑存储单元主层级关系图: 1、表空间 表空间是InnoDB存储引擎逻辑结构的最高层, 如果用户启用了参数 innodb_file_per_table(在 8.0版本中默认开启) ,则每张表都会有一个表空间(xxx.ibd),一个mysql实例可以对应多个表空间,用于存储记录、索引等数据。 2、段

    2024年02月14日
    浏览(43)
  • 【MYSQL】存储引擎MyISAM和InnoDB

    查看MySQL提供所有的存储引擎 mysql show engines; mysql常用引擎包括:MYISAM、Innodb、Memory、MERGE 1、MYISAM:全表锁,拥有较高的执行速度,不支持事务,不支持外键,并发性能差,占用空间相对较小,对事务完整性没有要求,以select、insert为主的应用基本上可以使用这引擎 2、Innod

    2024年01月18日
    浏览(39)
  • Mysql第二篇---InnoDB数据存储结构

    索引结构给我们提供了高效的索引方式, 不过索引信息以及数据记录都是保存在文件上的(innodb的ibd文件, MyISAM的MyI和MyD文件), 确切的说是存储在页结构中. 另一方面, 索引是在 存储引擎 中实现的, MySQL服务器上的存储引擎负责对表中数据的读取和写入工作. 不同存储引擎中存放

    2024年02月07日
    浏览(63)
  • 【MySQL】 深入了解InnoDB存储引擎的限制

    目录 列数限制 索引数限制 InnoDB的行格式和索引限制 示例和注意事项 **页大小对索引键前缀长度的影响 **对全列索引键的限制 多列索引限制 行大小限制 InnoDB log限制 表空间大小限制 表数量限制 操作系统限制 文件大小和日志文件大小 文件层级限制 随着数据库技术的不断发

    2024年01月24日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包