InnoDB存储引擎架构

InnoDB存储引擎最早由Innobase Oy公司开发(属第三方存储引擎)。从MySQL 5.5版本开始作为表的默认存储引擎。该存储引擎是第一个完整支持ACID事务的MySQL存储引擎,特点是行锁设计、支持MVCC、支持外键、提供一致性非锁定读,非常适合OLTP场景的应用使用。目前也是应用最广泛的存储引擎。

InnoDB存储引擎架构包含内存结构和磁盘结构两大部分,总体架构图如下:

内存结构

  • 缓冲池(buffer pool)

Buffer pool是主要功能是在内存中缓存表和索引数据,提供高速访问,所有表在访问时必须在缓冲池存在。若不存在,则需要昂贵的磁盘I/O将表从磁盘加载入缓冲池。

缓冲池在实现上是一系列链接的页,采用一个变种的LRU算法进行管理。

如果SQL的buffer cache hit 命中率较低,则有可能是此内存区域过小,无法缓存全部的热点数据。在数据库专用服务器上,buffer cache一般建议可以调整为物理内存的80%。

从InnoDB 1.0.x版本开始,InnoDB可以配置多个缓冲池。每个页根据哈希值平均分配到不同缓冲池实例中。这样做的好处是减少数据库内部的资源竞争,增加数据库的并发处理能力。可以通过参数innodb_buffer_pool_instances来进行配置。

  • 变更缓冲(change buffer)

Change buffer是用来缓存对二级索引(secondary index)的更新。InnoDB存储引擎可以对各种DML操作——INSERT、DELETE、UPDATE都进行缓冲,他们分别是:Insert Buffer、Delete Buffer、Purge buffer。

当需要更新二级索引时,如果此二级索引的页恰好不在内存中,InnoDB可以利用change buffer先将变更存起来,待后续该页因其他原因被读入内存后再将变更应用至索引上。这样机制避免每次需要都要去磁盘读,可以减少大量的随机磁盘I/O。

InnoDB存储引擎提供了参数innodb_change_buffering,用来开启各种Buffer的选项。该参数可选的值为:inserts、deletes、purges、changes、all、none。inserts、deletes、purges就是前面讨论过的三种情况。changes表示启用inserts和deletes,all表示启用所有,none表示都不启用。该参数默认值为all。

变更缓冲为buffer pool的一部分,由参数innodb_change_buffer_max_size控制,默认值为25,代表占buffer pool大小的25%。

  • 自适应hash索引(Adaptive hash index)

哈希(hash)是一种非常快的查找方法,在一般情况下这种查找的时间复杂度为O(1),即一般仅需要一次哈希运算就能定位数据。

InnoDB自身是不支持Hash索引的。但在内存中,如果InnoDB监测到特定的访问模式(例如频繁读取某些数据),则会基于B+ Tree索引的前缀再建立Hash索引,由此来加速查询。DBA可以控制此特性的开关,但是无法干涉Hash索引的建立。

  • 日志缓冲(Log buffer)

Log buffer是用来缓冲即将写入重做日志的变更。缓冲中的内容包含的数据库的变更,并定期的刷新到磁盘。一旦数据库出现崩溃,可以根据磁盘上的重做日志恢复数据。因此保证日志内容不丢失至关重要。强烈建议将参数innodb_flush_log_at_trx_commit设置为1,代表每次提交事务时,都强制将日志刷新会磁盘。防止出现事务已提交,但日志还没来得及刷新回磁盘,此时出现崩溃导致事务丢失的情况。

磁盘结构:

表由create table语句创建,是基本的数据存储单元。Innodb存储引擎表在磁盘表现为2个文件.frm(表定义)和.ibd(数据和索引)。如果要在system表空间创建表。需要禁用innodb_file_per_table参数。

  • 索引

InnoDB表中数据是按聚簇索引进行组织的,通常情况下聚簇索引即是主键,因此建议每张表都显式指定主键。如果未指定主键,innodb会隐式的创建一个主键索引。

所有非主键索引都称为次级索引,次级索引在创建时会将主键附件在索引后,即先查找对应的主键记录,再通过主键访问记录。

  • 表空间

Innodb的表空间包含系统表空间、file_per_table表空间、undo表空间。

系统表空间存储数据字典、double write buffer、undo logs。

如果启用了innodb_file_per_table参数,则会为每张表创建一个独立的file_per_table表空间。

undo日志默认存储在系统表空间,也可以分离出来存储在独立的表空间中。

  • 数据字典

数据字典存储在系统表空间中,由一系列元数据表组成,保存了表、索引、字段的定义信息。

  • 两次写缓冲

数据在内存中被变更后,从buffer pool刷回磁盘的时候会先刷新到double write buffer,然后再从double write buffer刷新回正确的位置。如果系统出现崩溃,重启恢复的时候会从double write buffer中找到正确的副本。数据在刷新回double write buffer时会采用顺序刷新的方式,效率很高。所以并不会产生2倍的I/O负担。double write buffer在磁盘上属于系统表空间的一部分。

  • 重做日志

redo log记录数据库的变更,数据库崩溃后,会从redo log获取事务信息,进行系统恢复。redo log在磁盘上表现为ib_logfile0和ib_logfile1两个文件。MySQL会在事务的提交前将redo日志刷新回磁盘。

在同一时间提交的事务,会采用组提交(group commit)的方式一次性刷新回磁盘。从而避免一个事务刷新一次磁盘,提高性能。

  • undo日志

事务修改数据时,MySQL会将旧的数据版本存储到undo记录中,当事务需要回滚,或者其他事务需要读取相同的数据时,会从undo记录中获取旧数据版本。undo日志在物理表现上是系统表空间的一部分。

以上即为Innodb主要组成部分及各部分功能,理解架构原理有助于提升实际应用中的优化能力。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值