目录
3.1.InnoDB存储引擎与MyISAM存储引擎之间的区别
4.1. 为什么Innodb存储引擎要设计成内存结构和磁盘结构两个部分?
一. 专题目标
我们现在来复习一下我们的MySQL架构
整体架构图如下所⽰:
MySQL直接讲其实很复杂,我们还是举例来说明比较好。
-
连接层 (Connection Pool) = 迎宾与座位安排
迎宾员管理客流: 核对身份(认证),检查空位(连接池),分配服务员(线程复用/创建),建立专属用餐会话(连接)。
-
服务层 (Service Layer) = 点餐与流程规划
服务员处理订单: 接收需求(SQL接口),理解复杂要求(解析器),规划最优上菜路径(优化器),检查缓存(出菜口),协调后台管理(备份/安全/复制等)。
-
存储引擎层 (Storage Engines) = 后厨烹饪执行
厨师团队专注烹饪: 按优化订单(执行计划)使用特定厨艺(引擎特性)存取食材(数据读写),保证菜品质量(事务ACID),记录关键步骤(Redo/Undo Log)。
-
文件系统层 (Files & Logs) = 仓库与运营记录
冷库与监控系统: 持久存储食材(数据文件),记录所有成功订单(Binlog)用于分店/恢复,保存退菜方法(Undo Log)和烹饪流水(Redo Log),记录问题(Error/Slow Log)。
总结四句话:
-
迎宾员管接入 (连接层): 认证、分配连接、管线程。
-
服务员管翻译 (服务层): 接SQL、解析、优化、用缓存、管后台。
-
厨师管做饭 (存储引擎): 按计划读写、保事务、记日志。
-
仓库管存储 (文件系统): 存数据、记日志(Binlog/Undo/Redo/Error)。
我们都知道,对于一个餐厅而言,最重要的就是他做的菜好不好吃,对吧?而这都取决于他的厨师。那么MySQL也是如此吗,存储引擎层是MySQL中的核心,而在MySQL5.5之后默认的存储引擎就是Innodb存储引擎,所以我们在日常使用中最长用到的就是这个Innodb存储引擎了。所以我们必须好好学习。
我们学习Innodb存储引擎,下面这些问题是我们绕不开的
-
掌握MySQL存储结构
-
掌握数据行的结构
-
掌握表空间、段、区、页、行的作用
-
掌握InnoDB整体架构
-
掌握InnoDB内存结构
-
掌握InnoDB内存缓冲区的作用和工作原理
-
掌握数据页在内存中的管理方式
-
掌握数据在磁盘上的组织方式
-
掌握InnoDB磁盘文件分类及作用
-
掌握InnoDB各种表空间文件和作用
-
掌握Undo日志的结构和作用
-
掌握Undo日志的管理方式
-
掌握Undo日志如何保证事务原子性
-
掌握Redo日志的结构和作用
-
掌握Redo日志内存与磁盘的交互机制
-
了解崩溃恢复的过程
-
掌握Redo日志如何保证事务持久性
-
掌握SQL在InnoDB中的执行流程
这些难度都不高,大家一定都能学会的。
我们将上面那些问题整合一下,也即是下面这些问题。
-
InnoDB简介
-
MySQL存储结构(重点讲清楚是什么)
-
页结构
-
行结构
-
InnoDB内存结构
-
数据在内存中的管理方式
-
InnoDB磁盘结构
-
数据在磁盘中的管理方式
-
内存与磁盘的交互过程
二 . InnoDB存储引擎的前世今生
InnoDB做为MySQL的默认存储引擎,其实并不是MySQL开发的,而是由 Innobase Oy 公司所开发,2006年五月时由甲骨文公司并购。这也是MySQL做为一个开源数据库的好处之一,第三方开发者可以根据自己的业务场景开发出高性能的存储引擎,像 Innobase Oy 公司开发的InnoDB,一旦被官方采纳,那么就可能通过被收购从而得到可观的收入,官方的产品也得到了有效的扩展,是一个双赢的结果。
开源社区有很多,除了MySQL之外,常见的还有Linux、Java、Android,开发都通过社区交流并贡献自己的技术,逐步完善各种应用场景下的技术支持,现在开发过程中使用的很多框架和中间件都得益于此。
三 . MySQL为什么默认使⽤InnoDB存储引擎?
这个问题也可以说是InnoDB存储引擎的优点 (也可以理解为InnoDB与MyISAM之间的区别)
mysql5.5之前的版本都是使用MyISAM存储引擎,mysql5.5开始使用InnoDB存储引擎
3.1.InnoDB存储引擎与MyISAM存储引擎之间的区别
**InnoDB:**在mysql5.5版本之后,MySQL默认的事务型引擎,也是最重要和使用最广泛的存储引擎。
- 它被设计成为大量的短期事务,短期事务大部分情况下是正常提交的,很少被回滚。
- InnoDB的性能与自动崩溃恢复的特性,使得它在非事务存储需求中也很流行。
- 除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB引擎
**MyISAM:**在MySQL 5.5 之前的版本,MyISAM是默认引擎。
- 是 MySQL数据库服务器中的组件,负责为数据库执行实际的数据I/O操作
- MyISAM提供的大量的特性,包括全文索引、压缩、空间函数(GIS)等
- 但MyISAM并不支持事务以及行级锁,而且一个毫无疑问的缺陷是崩溃后无法安全恢复
- 正是由于MyISAM引擎的缘故,即使MySQL支持事务已经很长时间了,在很多人的概念中MySQL还是非事务型数据库
- 尽管这样,它并不是一无是处的。对于只读的数据,或者表比较小,可以忍受修复操作,则依然可以使用MyISAM(但请不要默认使用MyISAM,而是应该默认使用InnoDB)
区别1:事务支持
- MyISAM:不支持事务,强调的是性能。
- InnoDB:支持事务:支持4个事务隔离级别
区别2:表锁差异
- MyISAM:表级锁定形式,数据在更新时锁定整个表
- InnoDB:行级锁定,但是全表扫描仍然会是表级锁定
区别3:读写过程
MyISAM:数据库在读写过程中相互阻塞
- 会在数据写入的过程阻塞用户数据的读取
- 也会在数据读取的过程中阻塞用户的数据写入
InnoDB:读写阻塞与事务隔离级别相关
区别4:缓存特性
- MyISAM:可通过key_buffer_size来设置缓存索引,提高访问性能,减少磁盘I/O的压力,但缓存只会缓存索引文件,不会缓存数据
- InnoDB:具有非常高效的缓存特性:能缓存索引,也能缓存数据
区别5:存储方式
- MyISAM:釆用 MyISAM存储引擎数据单独写入或读取,速度过程较快且占用资源相对少
- InnoDB:表与主键以簇的方式存储
区别6:外键支持
- MyISAM:MyISAM存储引擎它不支持外键约束
- InnoDB:支持外键约束
区别7:全文索引
- MyISAM:只支持全文索引
- InnoDB:5.5以前不支持全文索引,5.5版本以后支持全文索引
区别8:在磁盘上的存储类型
MyISAM:每个 MyISAM在磁盘上存储成三个文件,每一个文件的名字以表的名字开始,扩展名指出文件类型
MyISAM在磁盘上存储的文件
- .frm文件存储表定义(mysql8.0起换成.sdi文件)
- 数据文件的扩展名为.MYD( MYData)
- 索引文件的扩展名是.MYI( MYIndex)
InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB
区别9:存储空间
MyISAM:支持三种不同的存储格式:
- 静态表(默认,但是注意数据末尾不能有空格,会被去掉)
- 动态表
- 压缩表
当表在创建之后并导入数据之后,不会再进行修改操作,可以使用压缩表,极大的减少磁盘的空间占用
InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引
区别10:表主键
- MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址
- InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值
区别11:表的具体行数
- MyISAM:保存有表的总行数,如果select count() from table;会直接取出出该值
- InnoDB:没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样
区别12:读写性能
- MyISAM:读取性能优越,但是写入性能差,如果执行大量的select,MyISAM是更好的选择
- InnoDB:写入性能较强,如果执行大量的insert或者update,InnoDB是更好的选择
3.1.1:生产环境中依据什么选择存储引擎?
需要考虑毎个存儲引擎提供了哪些不同的核心功能及应用场景
支持的字段和数据类型
- 所有引擎都支持通用的数据类型
- 但不是所有的引擎都支持其它的字段类型,如二进制对象
锁定类型:不同的存储引擎支持不同级别的锁定
- 表锁定
- 行锁定
索引的支持
- 建立索引在搜索和恢复数据库中的数据的时候能够显著提高性能
- 不同的存储引擎提供不同的制作索引的技术
- 有些存储引擎根本不支持索引
事务处理的支持
- 事务处理功能通过提供在向表中更新和插入信息期间的可靠性
- 可根据企业业务是否要支持事务选择存储引擎
3.1.2:什么生产场景适合使用MyISAM?
- 公司业务不需要事务的支持
- 一般单方面读取数据比较多的业务,或单方面写入数据比较多的业务
- MyISAM存储引擎数据读写都比较频繁场景不适合
- 使用读写并发访问相对较低的业务
- 数据修改相对较少的业务
- 对数据业务一致性要求不是非常高的业务
- 服务器硬件资源相对比较差
3.1.3:什么生产场景适合使用InnoDB?
- 业务需要事务的支持
- 行级锁定对高并发有很好的适应能力,但需确保查询是通过索引来完成
- 业务数据更新较为频繁的场景,如:论坛,微博等
- 业务数据一致性要求较高,例如:银行业务
- 硬件设备内存较大,利用 Innodb较好的缓存能力来提高内存利用率,减少磁盘I/O的压力
- 业务需要事务的支持
- 行级锁定对高并发有很好的适应能力,但需确保查询是通过索引来完成
- 业务数据更新较为频繁的场景,如:论坛,微博等
- 业务数据一致性要求较高,例如:银行业务
- 硬件设备内存较大,利用 Innodb较好的缓存能力来提高内存利用率,减少磁盘I/O的压力
3.2.Innodb存储引擎的好处
InnoDB在设计时考虑到了处理巨大数据量时的性能,InnoDB支持事务(transaction)、回滚(rollback)并且具有崩溃修复的能力(crash recovery capabilities),通过多版本并发控制(multi-versioned concurrency control)减少锁定,同时还支持外键约束(FOREIGN KEY constraints),通过缓冲池在内存中缓存数据从而提高查询性能,也可以每个表使用各自的独立表空间存储数据并且文件大小只受限于操作系统。
由于InnoDB存储引擎存储数据量大,性能高,可以有效的保证数据安全等优点,在MySQL5.5版本之后成为默认的存储引擎。
衍生问题
-
InnoDB事务是什么?
-
事务的回滚是什么?
-
InnoDB崩溃修复如何处理?
-
多版本并发控制是什么?
-
锁分类有哪些?
-
缓冲池的作用及工作原理?
-
独立表空间的作用及优点?
附注说明:
以上衍生问题我们在后续的文章中都会详细介绍
四. InnoDB存储引擎的架构⻓啥样?
InnoDB存储引擎有这么多的优点,要深⼊了解InnoDB⾸先从它的架构开始,那么它的架构是怎么 样的呢?可以从官⽅⽂档中找到答案
InnoDB架构官网:MySQL :: MySQL 8.0 Reference Manual :: 17.4 InnoDB Architecture
InnoDB架构包含下面这些
一、内存结构
-
缓冲池 (Buffer Pool)——内存中的主要工作区域,优化查询的性能
-
变更缓冲区 (Change Buffer)——优化修改操作的性能
-
日志缓冲区 (Log Buffer)
-
自适应哈希索引 (Adaptive Hash Index)——进一步提升查询的性能
二、磁盘结构
-
系统表空间 (System Tablespace)——保存的是真实的数据
-
独立表空间 (File-Per-Table Tablespaces)——保存的是真实的数据
-
通用表空间 (General Tablespaces)——保存的是真实的数据
-
临时表空间 (Temporary Tablespaces)——保存的是真实的数据
-
撤销表空间 (Undo Tablespaces)——保存的是真实的数据
-
重做日志 (Redo Log) ——保证数据安全
-
双写缓冲区 (Doublewrite Buffer) ——保证数据安全
这个问题在⾯试中可能会被问到,在回答时先说总体的架构分为内存和磁盘两部分,再分别说说内存 和磁盘中都包括哪些组件就可以了
4.1. 为什么Innodb存储引擎要设计成内存结构和磁盘结构两个部分?
根本矛盾:速度 vs 持久性
-
磁盘(持久但慢)
-
数据必须持久化到磁盘,否则断电/崩溃会导致数据丢失。
-
但磁盘 I/O(尤其是随机读写)速度比内存慢 10⁵~10⁶ 倍(机械硬盘寻道约 10ms,内存访问约 100ns)。
-
-
内存(快但易失)
-
内存访问速度极快,可支持高并发操作。
-
但内存断电后数据立即丢失,无法保证持久性。
-
InnoDB 的解决方案:分层架构
▶ 内存结构(加速访问)
-
核心组件:缓冲池 (Buffer Pool)、变更缓冲区 (Change Buffer) 等。
-
作用:
-
缓存热点数据,减少直接访问磁盘的次数。
-
合并多次写操作(如 Change Buffer 延迟更新非唯一索引),降低随机 I/O。
-
-
效果:
-
查询命中缓冲池时,速度提升 100~1000 倍。
-
写操作先写入内存缓冲区,由后台线程异步刷盘,避免阻塞用户线程。
-
▶ 磁盘结构(持久化保障)
-
核心组件:表空间文件、Redo Log、Doublewrite Buffer 等。
-
作用:
-
Redo Log:记录所有修改操作(顺序写磁盘),崩溃时重放日志恢复数据。
-
Doublewrite Buffer:防止页断裂(Partial Page Write),确保数据页写入的原子性。
-
表空间:最终存储数据的物理文件(如
.ibd
)。
-
-
效果:
-
即使服务器断电,也能通过日志恢复提交的事务(ACID 中的 Durability)。
-
4.2 内存结构和磁盘结构中每个部分的作用是什么?
后续内容将深入解析以下两部分:
-
内存结构组件(缓冲池、变更缓冲区等)的作用与工作原理
-
磁盘结构组件(表空间、日志等)的作用与工作原理
五. 使⽤InnoDB存储引擎创建的表对应的数据⽂件在哪⾥?
首先我们需要知道,默认情况下这些数据文件都是保存在数据目录下面的。而我们都可以通过修改配置文件来修改数据目录。
我们在使用create database……这个语句中,系统会在数据目录里面生成一个与数据库同名的子目录,保存了表的信息。
无论使用哪个存储引擎创建表,真实的数据都必须存储在磁盘或其他存储介质中。
当使用InnoDB存储引擎创建一个表时,默认会在数据目录对应的数据库子目录中生成相应的表空间文件,以 .ibd 为文件的后缀,用来存储数据和索引。
如果每个表都对应一个表空间文件,称为独立表空间,在MySQL5.7及以后的版本中默认为每个表生成独立表空间,可以通过系统变量 innodb_file_per_table[=ON|OFF]
进行控制(建议强制开启),如果关闭这个选项,则所有表的数据都在系统表空间中存储,独立表空间文件如下所示:
create database db10;
use db10;
create table t1(id int);
show tables;