1、什么是存储引擎,作用是什么
存储引擎是数据库管理系统中对数据存储和访问的核心组件。它定义数据如何存储,索引,检索以及如何事务性地更新。不同的存储引擎提供不同的功能与特性,优化不同的负载。
以下是存储引擎的一些关键特性和功能:
-
数据存储:存储引擎决定了数据在磁盘上的存储方式,包括数据的物理格式和存储结构。
-
索引:存储引擎提供了创建和管理索引的方法,以加速数据检索。
-
事务处理:存储引擎支持事务的ACID属性(原子性、一致性、隔离性、持久性)。
-
并发控制:存储引擎管理多个用户或进程对数据的并发访问,以防止数据损坏。
-
崩溃恢复:存储引擎必须能够处理系统崩溃,确保数据的完整性和一致性。
-
备份和恢复:存储引擎支持数据的备份和恢复操作。
-
性能优化:不同的存储引擎针对不同的查询类型和数据访问模式进行优化。
-
支持的数据类型和功能:不同的存储引擎可能支持不同的数据类型和功能,例如全文搜索、空间数据类型等。
2、Mysql存储引擎有哪些
Mysql存储引擎有InnoDB,,MyISAM,Memory,CSV等等,本人常用只有InnoDB与MyISAM两种,其他暂时不清楚。
- InnoDB
- 作用:适用于需要事务处理和外键支持的应用,是MySQL的默认存储引擎。
- 特性:支持ACID事务、行级锁定、外键约束、崩溃恢复、MVCC
- MyISAM
- 作用:适用于读取密集型应用,不支持事务。
- 特性:表级锁定、全文索引支持、快速读取。
- Memory
- 作用:存储数据于内存中,提供快速访问,适用于临时表和高速缓存。
- 特性:高速读写、不支持事务、数据在数据库重启后丢失。
- CSV
- 作用:存储数据为逗号分隔值格式,适用于数据导入导出。
- 特性:简单数据存储、没有索引、不支持事务。
InnoDB与MyISAM两种引擎有什么区别?
1、事务
InnoDB支持事务,对于数据一致性要求较高的场景使用。即 频繁更改操作的场景InnoDB引擎俱佳。
MyISAM不支持事务。
2、锁
InnoDB支持行锁+表锁,锁的粒度更小,更改数据并发能力较强。
MyISAM只支持表锁,更改数据并发能力弱。
3、外键
InnoDB支持外键,有助于维护数据引用的完整性。
MyISAM不支持。
4、数据恢复
InnoDB支持多种数据恢复,即日志恢复,事务日志恢复。
MyISAM需要专业第三方工具才行。
5、索引
InnoDB支持丰富的索引,即 主键、唯一索引、普通索引、聚簇索引、联合索引、全文索引(5.6开始)等。对数据检索具有较高的性能。
MyISAM只支持全文索引。
6、存储结构
InnoDB将数据与索引存储在一起,所以使用主键与聚簇索引查询性能高。
MyISAM将数据与索引分开存储,非聚簇索引。
7、表空间
InnoDB支持表空间,用来管理数据文件。即 数据与索引存储在表空间中。
MyISAM不支持。
总结:InnoDB适合在高并发和事务的场景下使用。MyISAM适合在多读且不需要事务的场景下使用。
3、InnoDB存储引擎-存储结构
我们先来看一张图来理解存储结构。
3.1、Tablespaces(表空间)
Tablespaces(idb文件)表空间是整个InnoDB存储结构中的最顶层,是所有数据与结构的存储位置。
数据表所存放表空间中,需要看系统innodb_file_per_table配置状态,如果是ON时,则每新建一张表都是独立的表空间,如果时OFF,会将新建表都统一放在共享表空间中(idbdata1表空间中)。
注意:共享表空间有个缺点,删除表不会立即从表空间中清理,需要服务重启才会。目前Mysql8.0版本时默认开启的,可查看下图。
3.2、Segments(段)
InnoDB会将每个表空间(tableSpaces)划分成多个段(Segments),主要用于存储不同类型的数据。段的主要类型包括 数据段,索引段,回滚段,系统段。数据段就是B+树中的叶子节点,索引段就是非叶子节点。
3.3、Extents(区)
InnoDB会将每个段(Segment)划分成多个页,每个区默认时1M,一个页默认是16KB,所以一个段会划分成64个页。区是磁盘读写最小的单位,它包含了一组连续的数据页。
3.4、Pages(页)
页是一组行(Row)组成,一个页默认是16KB,是InnoDB数据存储最小的单位,它包含了表的行数据,索引数据以及其他管理信息。
3.5、Rows(行)
InnoDB使用"B+树"索引结构来组织数据。数据行存储在表的叶子页中,每一行代表一条记录。行数据包括所有列的值以及一些额外的管理信息。
4、InnoDB存储引擎-系统架构
我们先来看一张系统架构图(官方Mysql8.0版本),通过图来分析InnoDB的架构思想。
从上图可以看出它分为三个部分。一部分是内存(缓存,减少IO,提高性能),一个是磁盘(数据最终存储的地方),一个是内部线程(数据同步),下面我们就详细讲讲三个组件部分。
4.1、内存分析
4.1.1、Buffer Pool(缓存池)
缓存池,将经常使用磁盘中的数据存放在缓存(单位是页Page)。当缓存数据没有时,会从磁盘中读数据并写入内存中,有缓存数据直接返回,可以降低磁盘IO,提供数据库性能。
缓存池中的页有三种状态,分别是 Free Page, Clean Page,Dirty Page.
Free Page:空闲页,没有存放数据。
Clean Page:已存放数据的页,与磁盘中的数据保持一致。
Dirty Page:脏页,即存放的数据与磁盘中的数据不一致,等待刷新策略将数据刷新只磁盘中
4.1.2、Change Buffer(改变的缓存)
用于存储更改数据的缓存。即 当Buffer Pool中没有当前更改的数据时,会将更改的数据放入change Buffer中,等待未来使用该数据时,将Change Buffer中的数据合并至Buffer Pool中,后续根据特殊策略同步至磁盘中。
4.1.3、Adaptive Hash Index(自适应Hash)
InnoDB存储引擎是不支持Hash索引的,支持B+树索引。但是官方为了提升Buffer Pool的查询性能在内部加入了自适应Hash,Hash索引是系统根据某些策略来自主加索引,外部无法干预。旨在提升性能。
4.1.4、Log Buffer(日志缓存)
主要存储日志的地方与数据缓存策略差不多,旨在减少对IO的次数,提升性能。
4.2、磁盘分析
4.2.1、System Tablespace(系统表空间)
InnoDB默认生成的表空间,当Mysql数据库关闭了独立表空间时,所有的数据都会存储在系统表空间中。如果开启了独立表空间,则放入独立表空间中。
注意:Mysql8.0已默认开启独立表空间。
4.2.2、File_Per_TableSpaces(独立表空间)
每个表都独自存在表空间,方便管理与维护。可以在配置中进行关闭。
4.2.3、Genderal TableSpaces(公用表空间)
共用表空间一般不会使用,因为需要创建表空间才会生成。
语法格式:
# 创建公用表空间
create tablespace 表空间名 add datafile 文件路径/文件名 engine=innoDB;
# 示例
create tablespace my_tx add DATAFILE 'C:\ProgramData\MySQL\MySQL Server 8.0\Data\myUserTx.ibd' ENGINE=innoDB;
# 创建表并指定表空间
create table d_use(id int primary key auto_increment, name varchar(20)) engine=innoDB tablespace 表空间名;
4.2.4、Template TableSpaces(临时表空间)
临时表空间是存放临时表的地方。
4.2.5、Undo TableSpaces(撤销表空间)
撤销表空间主要存储事务回滚信息的特殊类型的表空间。例如事务中更改数据时,撤销表日志会记录相反的update语句,用于后期数据回滚。
4.2.6、Redo Log(重做日志)
Redo Log重做日式主要存储事务提交的日志,用于系统崩溃后数据恢复。
4.2.7、Doublewrite Buffer Files(双写缓存)
双写缓存是磁盘中用于存储内存中数据同步至磁盘中的一个区域,避免直接操作相关数据,好处是同步失败后可以进行恢复等。
4.3、内部线程分析
4.3.1、主线程
主要负责调度其他线程,以及脏页刷新用于保证数据一致性,合并插入缓存和自适应Hash的维护,负责页压缩等。
4.3.2、IO线程
IO线程主要相关的IO操作,根据不同的类型操作不同的线程,以达到并行的操作,提高数据同步性能。其中读写线程各4个,写缓存线程一个,可以根据命令查看。
show engine innoDB status;
执行命令后,可以查看到各个线程,读写各4个,插入缓存线程一个,其他版本应该会有日志线程,我的版本中没有。
4.3.2.1、读线程
读线程负责将数据从磁盘加载到缓冲池(Buffer Pool)中。 当数据页不在缓冲池中时,读线程会被唤醒,并异步读取数据到内存中。 读线程的数量可以根据需要进行配置,多个读线程可以并行处理不同的读取请求,提高读取性能。
4.3.2.2、写线程
写线程负责将缓冲池中的脏页(被修改但尚未写入磁盘的数据页)刷新到磁盘。 写线程会根据脏页的比例和系统的负载情况,动态调整刷新的频率和数量。 多个写线程可以并行处理不同的写请求,提高写入性能。写线程的数量也可以在配置中进行调整 。
4.3.2.3、Log线程
日志线程负责将日志缓冲区中的内容刷新到磁盘的重做日志文件中。 重做日志是InnoDB保证事务持久性的重要机制,日志线程确保了日志的写入顺序和一致性。 日志线程通常只有一个,因为日志的写入是顺序的,不需要多个线程并行处理 。
4.3.2.4、Writer Bufer线程
插入缓冲线程负责将插入缓冲中的内容刷新到磁盘。 插入缓冲是InnoDB用于优化非聚集索引插入操作的缓冲区,它可以将多个插入操作合并成一个,减少磁盘IO次数。 插入缓冲线程会定期将缓冲中的数据写入到实际的索引页中,以提高写入性能 。
4.3.3、Page Cleaner Thread(页面清理线程)
主要回复事务提交后的Undo log日志,原因:事务一旦提交,undo log日志可能就用不了(注意MVVC中会使用,后期会讲解),可以回收。
4.3.4、Thread Scheduler(线程调度器)
用于管理用户连接和后台线程。 它负责任务队列的管理,以及线程的创建和销毁。 提高了并发处理能力,使得线程管理更加高效。也是主线程的协助线程,让主线程做其他的事情,减少阻塞。