mysql系列之InnoDB存储引擎结构详解

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: mysql系列之InnoDB存储引擎结构详解

前言


InnoDB是Mysql数据库中最重要的存储引擎,搞清楚它的结构对理解它的各种机制的实现原理非常重要。今天和大家一起分享下InnoDB的结构。


一、InnoDB结构


34.png

由图可知:

InnoDB的底层结构主要由2部分组成:内存结构和磁盘结构。

33.png


二、内存结构详解


1、Buffer Pool

缓冲池是主内存中的一个区域,InnoDB在访问表和索引数据时会在其中进行缓存。 缓冲池允许直接从内存中处理经常使用的数据,从而加快了处理速度。 在专用服务器上,通常将多达80%的物理内存分配给缓冲池。

缓存的单位是页,使用LRU算法的变体将很少使用的数据从缓存中老化掉。


InnoDB的缓冲池缓存什么?有什么用?

缓存表数据与索引数据,把磁盘上的数据加载到缓冲池,避免每次访问都进行磁盘IO,起到加速访问的作用。


总结:

(1)缓冲池(buffer pool)是一种常见的降低磁盘访问的机制;

(2)缓冲池通常以页(page)为单位缓存数据,缓存最热的数据页(data page)与索引页(index page);

(3)缓冲池的常见管理算法是LRU。memcache,OS,InnoDB都使用了这种算法;

(4)InnoDB对普通LRU进行了优化:

32.png

缓冲池使用最近最少使用(LRU)算法的变体对缓冲数据的列表进行管理。 按照5:3的比例将Buffer pool空间划分成年轻代和老年代。

1、年轻代的头部是经常被访问的数据。

2、在老年代的尾部是很少被访问的数据。

什么时候需要一个空间向缓冲池中添加新页面时,删除老年代最近最少使用的页面(最尾部的页),并创建一个新页面添加到列表的中间。


2、Change Buffer

什么是InnoDB的写缓冲?

在MySQL5.5之前,叫插入缓冲(insert buffer),只针对insert做了优化;现在对delete和update也有效,叫做写缓冲(change buffer)。


Change Buffer是缓存那些不在buffer pool里的辅助索引的变化的特殊数据结构 。

在辅助索引发生改变时,如果辅助索引在buffer pool里面就会直接进行修改。如果发生变化的辅助索引页不在buffer pool里,则由Change Buffer先缓存这些辅助索引页的变更动作。等未来辅助索引页被读取时,再将数据再将数据合并(merge)恢复到缓冲池中的技术。写缓冲的目的是降低写操作的磁盘IO,提升数据库性能。


在内存中,Change Buffer是缓冲池的一个组成部分。在磁盘上,Change Buffer是system tablespace(系统表空间)的一部分,当数据库宕机时,索引的变更会被缓冲到磁盘的Change Buffer区域。

31.png


总结:

1、写缓冲只有在要修改的辅助索引页不在buffer pool内时,才会将写入操作缓存在change buffer

2、定期对写辅助索引页的changes buffer进行合并,写到到buffer pool 中

3、change buffer既包含内存结构,也包含磁盘结构。内存中的change buffer主要是缓冲辅助索引的变更操作,以便对变更操作进行合并,提高对辅助索引修改效率。

磁盘部分的change buffer主要是数据库宕机时,会将索引的变更缓冲到磁盘的Change Buffer区域。


为什么change buffer只对辅助索引生效?

以insert新增操作为例,插入顺序一般是按照主键递增顺序进行插入的,插入聚集索引(主键索引)一般是顺序的,不需要磁盘的随机读取。这种情况下对聚集索引的修改速度是非常快的,所以不需要进行写缓冲。

而对于辅助索引的插入或者更新操作,由于B+树的索引结构的特性决定了辅助索引插入的离散型。所以,对于辅助索引的插入或者更新操作,InnoDB中不是每一次都直接插入到索引页中,而是先判断插入的辅助索引页是否在缓存区中,若在直接插入;若不在,则先放入到change buffer中,然后再以一定频率和情况进行change buffer和辅助索引页子节点的merge(合并)操作,这时通常能将多个插入合并到一个操作中(因为在一个索引页中),这就大大提高了对于辅助索引插入的性能。


3、自适应hash索引(Adaptive Hash Index)

InnoDB存储引擎会监控对表上各索引页的查询,如果观察到建立hash索引可以提高查询速度,则自动建立hash索引。这就是自适应哈希索引(Adaptive Hash Index,AHI)

AHI是通过缓存池的B+树页构造而来,因此建立的速度很快,而且不需要对整张表构建hash索引。

InnoDB存储引擎会自动根据访问的频率和模式来自动的为某些热点也建立hash索引。


从这个层面上来说,InnoDB的自使用哈希索引,更像“索引的索引”,毕竟其目的是为了加速索引寻路。

30.png


AHI的要求:

1、对页连续访问的模式必须是一样的,即查询条件一样。

2、hash索引只能用来搜索等值的查询


4、Log Buffer

日志缓冲区是用于保存要写入磁盘上的日志文件数据的内存区域。

日志缓冲区大小由innodb_log_buffer_size变量定义, 默认大小为16MB。 日志缓冲区的内容定期刷新到磁盘。 较大的日志缓冲区使大型事务可以运行,而无需在事务提交之前将redo日志数据写入磁盘。 因此,如果您有更新,插入或删除许多行的事务,则增加日志缓冲区的大小可以节省磁盘I / O。

innodb_flush_log_at_trx_commit

变量控制如何将日志缓冲区的内容写入并刷新到磁盘。

innodb_flush_log_at_timeout

变量控制日志刷新频率。


为什么要有 Log Buffer?

事务提交后,必须将事务对数据页的修改刷(fsync)到磁盘上,才能保证事务的ACID特性。

这个刷盘,是一个随机写,随机写性能较低,如果每次事务提交都刷盘,会极大影响数据库的性能。

日志缓冲区使大型事务可以运行,而无需在事务提交之前将redo日志数据写入磁盘,节省了磁盘I/O.


log buffer刷写的三种策略:

29.png

为了满足不用业务对于吞吐量与一致性的需求,MySQL事务提交时刷redo log有三种策略:innodb_flush_log_at_trx_commit

(1)0:每秒写入一次日志并将其刷新到磁盘。 尚未刷新日志的事务可能会在崩溃中丢失。

(2)1:要完全符合ACID,必须使用默认设置1。 日志在每次事务提交时写入并刷新到磁盘。

(3)2:日志在每次事务提交后写入,并每秒刷新一次到磁盘。 尚未刷新日志的事务可能会在崩溃中丢失。

这里的写入都只是写入到系统的OS Cache中,如果不刷写到redo log中,数据可能在崩溃中丢失。


高并发业务,行业最佳实践,是使用第三种折衷配置(=2),这是因为:

(1)配置为2和配置为0,性能差异并不大,因为将数据从Log Buffer拷贝到OS cache,虽然跨越用户态与内核态,但毕竟只是内存的数据拷贝,速度很快;

(2)配置为2和配置为0,安全性差异巨大,操作系统崩溃的概率相比MySQL应用程序崩溃的概率,小很多,设置为2,只要操作系统不奔溃,也绝对不会丢数据。


高并发业务,行业内的最佳实践,是:

innodb_flush_log_at_trx_commit=2


总结


主要是介绍了InnoDB引擎的结构,对内存结构的各个组成部分进行了重点说明。

1、InnoDB引擎的结构分为内存结构和磁盘结构。

2、内存结构由缓冲池(Buffer Pool),写缓冲(Change Buffer),日志缓冲( Log Buffer),自适应hash索引(Adaptive Hash Index)组成。

3、缓冲池(Buffer Pool)主要是缓存表数据与索引数据,加快访问速度。内部采用基于LRU算法的变体算法来管理缓存对象。

4、写缓冲(Change Buffer)主要是缓存辅助索引的更新操作,加快辅助索引的更新速度。

5、日志缓冲( Log Buffer)使大型事务可以运行,而无需在事务提交之前将redo日志数据写入磁盘,节省了磁盘I/O。注意事务提交时刷redo log有三种策略。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
20天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
本文介绍了MySQL InnoDB存储引擎中的数据文件和重做日志文件。数据文件包括`.ibd`和`ibdata`文件,用于存放InnoDB数据和索引。重做日志文件(redo log)确保数据的可靠性和事务的持久性,其大小和路径可由相关参数配置。文章还提供了视频讲解和示例代码。
129 11
【赵渝强老师】MySQL InnoDB的数据文件与重做日志文件
|
20天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的表空间
InnoDB是MySQL默认的存储引擎,主要由存储结构、内存结构和线程结构组成。其存储结构分为逻辑和物理两部分,逻辑存储结构包括表空间、段、区和页。表空间是InnoDB逻辑结构的最高层,所有数据都存放在其中。默认情况下,InnoDB有一个共享表空间ibdata1,用于存放撤销信息、系统事务信息等。启用参数`innodb_file_per_table`后,每张表的数据可以单独存放在一个表空间内,但撤销信息等仍存放在共享表空间中。
|
20天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL InnoDB的段、区和页
MySQL的InnoDB存储引擎逻辑存储结构与Oracle相似,包括表空间、段、区和页。表空间由段和页组成,段包括数据段、索引段等。区是1MB的连续空间,页是16KB的最小物理存储单位。InnoDB是面向行的存储引擎,每个页最多可存放7992行记录。
|
20天前
|
存储 Oracle 关系型数据库
【赵渝强老师】MySQL的InnoDB存储引擎
InnoDB是MySQL的默认存储引擎,广泛应用于互联网公司。它支持事务、行级锁、外键和高效处理大量数据。InnoDB的主要特性包括解决不可重复读和幻读问题、高并发度、B+树索引等。其存储结构分为逻辑和物理两部分,内存结构类似Oracle的SGA和PGA,线程结构包括主线程、I/O线程和其他辅助线程。
【赵渝强老师】MySQL的InnoDB存储引擎
|
6月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
|
2月前
|
存储 缓存 关系型数据库
详细解析MySQL中的innodb和myisam
总之,InnoDB和MyISAM各有千秋,选择合适的存储引擎应基于对应用程序特性的深入理解,以及对性能、数据完整性和可扩展性的综合考量。随着技术发展,InnoDB因其全面的功能和日益优化的性能,逐渐成为更广泛场景下的首选。然而,在特定条件下,MyISAM依然保留其独特的价值。
138 0
|
4月前
|
监控 关系型数据库 MySQL
在Linux中,mysql的innodb如何定位锁问题?
在Linux中,mysql的innodb如何定位锁问题?
|
4月前
|
SQL 存储 关系型数据库
"MySQL增列必锁表?揭秘InnoDB在线DDL,让你的数据库操作飞一般,性能无忧!"
【8月更文挑战第11天】在数据库领域,MySQL凭借其稳定高效的表现深受开发者喜爱。对于是否会在给数据表添加列时锁表的问题,MySQL的行为受版本、存储引擎等因素影响。从5.6版起,InnoDB支持在线DDL,可在改动表结构时保持表的可访问性,避免长时间锁表。而MyISAM等则需锁表完成操作。例如,在使用InnoDB的表上运行`ALTER TABLE users ADD COLUMN email VARCHAR(255);`时,通常不会完全锁表。虽然在线DDL提高了灵活性,但复杂操作或大表变更仍可能暂时影响性能。因此,进行结构变更前应评估其影响并择机执行。
73 6
|
6月前
|
存储 SQL 关系型数据库
【MySQL技术内幕】6.3-InnoDB中的锁
【MySQL技术内幕】6.3-InnoDB中的锁
201 57
|
5月前
|
存储 SQL 关系型数据库
(十三)MySQL引擎篇:半道出家的InnoDB为何能替换官方的MyISAM?
MySQL是一款支持拔插式引擎的数据库,在开发过程中你可以根据业务特性,从支持的诸多引擎中选择一款适合的,例如MyISAM、InnoDB、Merge、Memory(HEAP)、BDB(BerkeleyDB)、Example、Federated、Archive、CSV、Blackhole.....