MySQL原理(二)存储引擎(3)InnoDB

目录

一、概况:

 1、介绍:

2、特点:

二、体系架构

1、后台线程

2、内存池(缓冲池)

三、物理结构 

1、数据文件(表数据和索引数据)

1.1、作用:

1.2、共享表空间与独立表空间

1.3、共享表空间

1.4、独立表空间

2、日志文件

2.1、介绍

2.2、作用

2.3、配置参数:

四、配置参数


一、概况:

 1、介绍:

从Mysql5.5版本开始,InnoDB是默认的表存储引擎。

2、特点:

(1)支持事务安全:

InnoDB 最重要的一点就是支持事务,可以说这是 InnoDB 成为 MySQL 中最流行的存储引擎的一个非常重要的原因。InnoDB 还实现了 SQL92 标准所定义的 4 个隔离级别(READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ 和 SERIALIZABLE)。

(2)数据多版本读取;

(3)锁定机制的改进,行锁设计;

(4)支持外键:

InnoDB 支持外键约束,检查外键、插入、更新和删除,以确保数据的完整性。在存储表中数据时每张表的存储都按主键顺序存放,如果没有显式地在定义表时指定主键,InnoDB 会为每一行生成一个 6 字节的 ROWID ,并以此作为主键。

(5)实现了缓冲处理:

InnoDB 提供了专门的缓存池,实现了缓冲管理,不仅能缓冲索引也能缓冲数据,常用的数据可以直接从内存中处理,比从磁盘获取数据处理速度要快。相比之下,MyISAM 只是缓存了索引。

(6)灾难恢复性好
InnoDB 通过 commit、rollback、crash-recovery 来保障数据的安全。具体来说,crash-recovery 就是指如果服务器因为硬件或软件的问题而崩溃,不管当时数据是怎样的状态,在重启 MySQL 后,InnoDB 都会自动恢复到发生崩溃之前的状态,并回到用户离开的地方。

(7)支持MVCC、提供一致性非锁定读、同时被设计用来最有效的利用以及使用内存和CPU。

二、体系架构

MySQL原理(二)存储引擎(3)InnoDB_第1张图片

InnoDB存储引擎有多个内存块,这些内存块组成了一个大的内存池。后台线程主要负责刷新内存池中的数据、将已修改的数据刷新到磁盘等等。

1、后台线程

InnoDB后台有多个不同的线程,用来负责不同的任务。主要有如下:

(1)Master Thread
这是最核心的一个线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括赃页的刷新、合并插入缓冲、UNDO 页的回收等.

(2)IO Thread
在 InnoDB 存储引擎中大量使用了异步 IO 来处理写 IO 请求, IO Thread 的工作主要是负责这些 IO 请求的回调处理。

(3)Purge Thread
事务被提交之后, undo log 可能不再需要,因此需要 Purge Thread 来回收已经使用并分配的 undo页. InnoDB 支持多个 Purge Thread, 这样做可以加快 undo 页的回收。

(4)Page Cleaner Thread
Page Cleaner Thread 是在InnoDB 1.2.x版本新引入的,其作用是将之前版本中脏页的刷新操作都放入单独的线程中来完成,这样减轻了 Master Thread 的工作及对于用户查询线程的阻塞。

2、内存池(缓冲池)

InnoDB 存储引擎是基于磁盘存储的,也就是说数据都是存储在磁盘上的,由于 CPU 速度和磁盘速度之间的鸿沟,InnoDB 引擎使用缓冲池技术来提高数据库的整体性能。缓冲池简单来说就是一块内存区域.在数据库中进行读取页的操作,首先将从磁盘读到的页存放在缓冲池中,下一次读取相同的页时,首先判断该页是不是在缓冲池中,若在,称该页在缓冲池中被命中,直接读取该页。否则,读取磁盘上的页。对于数据库中页的修改操作,首先修改在缓冲池中页,然后再以一定的频率刷新到磁盘,并不是每次页发生改变就刷新回磁盘。

缓冲池中缓存的数据页类型有:索引页、数据页、 undo 页、插入缓冲、自适应哈希索引、 InnoDB 的锁信息、数据字典信息等。索引页和数据页占缓冲池的很大一部分。在InnoDB中,缓冲池中的页大小默认为16KB。

MySQL原理(二)存储引擎(3)InnoDB_第2张图片

Buffer Pool其实是一片连续的内存空间,InnoDB为每一个缓存页都创建了一些所谓的控制信息,这些控制信息包括该页所属的表空间编号、页号、页在Buffer Pool中的地址,一些锁信息以及LSN信息(锁和LSN这里可以先忽略),当然还有一些别的控制信息。每个缓存页对应的控制信息占用的内存大小是相同的,

MySQL原理(二)存储引擎(3)InnoDB_第3张图片

三、物理结构 

使用 InnoDB 时,MySQL 会在数据目录(Data)下创建一个名为 ibdata1 的 10MB 大小的自动扩展数据文件,以及两个名为 ib_logfile0 和 ib_logfile1 的 5MB 大小的日志文件。InnoDB 存储引擎和 MyISAM 不太一样,虽然也有 .frm 文件来存放表结构定义相关的元数据,但是表数据和索引数据是存放在一起的。至于是每个表单独存放还是所有表存放在一起,用户可以自己设置。InnoDB 的物理存储结构分为两大部分:

1、数据文件(表数据和索引数据)
1.1、作用:

数据文件用来存放数据表中的数据和所有的索引数据,包括主键和其他普通索引。

1.2、共享表空间与独立表空间

InnoDB 存储的数据采用表空间(Tablepace)进行存放设计。表空间是用来存放 MySQL 系统相关信息的一个特殊共享表空间。InnoDB 的表空间分为以下两种形式:

(1)共享表空间,表数据和索引都存放在同一个表空间。默认的表空间文件就是上面所提到的 MySQL 初始化路径下的 ibdata1 文件;

(2)独立表空间,每个表的数据和索引被存放在一个单独的 .ibd 文件中。

可以通过以下命令查看 MySQL 是否使用独立表空间:

SHOW VARIABLES LIKE 'innodb_file_per_table%';

innodb_file_per_table 值为 ON 时表示开启独立表文件,InnoDB 表的数据和索引都会以单独的形式存放;值为 OFF 时,InnoDB 表的数据和索引都存放在一个表空间。可以通过设置该参数的值来决定是否使用独立表空间。

如我的

MySQL原理(二)存储引擎(3)InnoDB_第4张图片   MySQL原理(二)存储引擎(3)InnoDB_第5张图片

1.3、共享表空间

(1)共享表空间的数据文件可以设置为固定大小和可自动扩展大小两种形式。自动扩展形式的文件可以设置文件的最大大小和每次扩展量。在创建自动扩展的数据文件时,建议最好加上最大尺寸的属性,一个原因是文件系统本身有一定的大小限制,还有一个原因就是方便自身维护。

(2)当表空间快要用完的时候,我们必须要为其增加数据文件,当然,只有共享表空间有此操作。在mysql配置文件 innodb_data_file_path 参数后面按照标准格式设置好文件路径和相关属性即可,设置完 innodb_data_file_path 参数后,所有基于 InnoDB 存储引擎的表的数据都会记录到该共享表空间中

innodb_data_file_path=datafile_spec1[;datafile_spec2]...

其中,datafile_spec1 格式为表空间文件路径:大小:属性,还可以指定多个文件组成一个表空间,同时指定文件的属性,如
[mysqld]
innodb_data_file_path=/db/ibdata1:2000M;/dr2/db/ibdata2:2000M:autoextend
表示将 /db/ibdata1 和 /dr2/db/ibdata2 两个文件用来组成表空间。若这两个文件位于不同的磁盘上,磁盘的负载可能被平均,因此可以提高数据库的整体性能。
指定多个文件时,autoextend 属性只在最后一个数据文件中指定,表示表空间自动扩展。这里表示文件 ibdata1 的大小为 2000MB,文件 ibdata2 的大小为 2000MB,如果用完了 2000MB,该文件还可以自动增长。

使用以下命令查看当前共享表空间文件的路径、大小和自动化策略:

SHOW VARIABLES LIKE 'innodb_data_file_path%';

MySQL原理(二)存储引擎(3)InnoDB_第6张图片

注意:InnoDB 在创建新数据文件时不会创建目录,如果指定目录不存在,则会报错并无法启动。另外,InnoDB 给共享表空间增加数据文件之后,必须要重启数据库系统才能生效。这也是大多数人一直不太喜欢使用共享表空间而选用独立表空间的原因之一。

1.4、独立表空间

通过设置 innodb_file_per_table 参数,可以将每个基于 InnoDB 存储引擎的表产生一个独立表空间。独立表空间的命名规则为表名.ibd。通过这样的方式,用户不用将所有数据都存放于默认的表空间中。使用 SET 命令打开/关闭独立表空间

mysql> SET GLOBAL innodb_file_per_table=1;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW VARIABLES LIKE 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set, 1 warning (0.03 sec)

mysql> SET GLOBAL innodb_file_per_table=0;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW VARIABLES LIKE 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | OFF   |
+-----------------------+-------+
1 row in set, 1 warning (0.00 sec)

注意:需要注意的是,单独的表空间文件只存储该表的数据、索引和缓冲等信息。所以无论是使用共享表空间还是独享表空间来存放表,共享表空间都是必须存在的。

2、日志文件
2.1、介绍

默认情况下,InnoDB 存储引擎的数据目录下会有两个名为 ib_logfile0 和 ib_logfile1 的文件。在 MySQL 官方手册中将其称为 InnoDB 存储引擎的重做日志文件(redo log file)。每个 InnoDB 存储引擎至少有 1 个重做日志文件组(group),每个文件组下至少有 2 个重做日志文件,如默认的 ib_logfile0 和 ib_logfile1。

2.2、作用

重做日志文件对 InnoDB 存储引擎至关重要。InnoDB 可以通过重做日志将数据库宕机时已经完成但还没有来得及将数据写入磁盘的事务恢复,也能将所有部分完成并已经写入磁盘的未完成事务回滚,并且将数据还原,以此来保证数据的完整性。

注意:如果你的数据库中有 InnoDB 的表,那么千万别全部删除 InnoDB 的日志文件,这很可能会让你的数据库 Crash(数据库不工作或停止响应、进程中断等情况,在业界也叫做数据库 Crash),无法启动,或者丢失数据。

2.3、配置参数:

影响重做日志文件的参数:

(1)innodb_log_file_size:指定每个重做日志的大小。
(2)innodb_log_files_in_group:指定日志文件组中重做日志文件的数量,默认为 1。
(3)innodb_mirrored_log_groups:指定日志镜像文件组的数量,默认为 1。
(4)innodb_log_group_home_dir:指定日志文件组所在路径,默认为./。

四、存储结构

MySQL原理(二)存储引擎(3)InnoDB_第7张图片

1). 表空间表空间是InnoDB存储引擎逻辑结构的最高层, 如果用户启用了参数 innodb_file_per_table(8.0版本中默认开启) ,则每个库中的表及其索引等都会有一个单独表空间(xxx.ibd),如果没有启用,所有的库及其数据都会在系统表空间中。一个mysql实例可以对应多个表空间,用于存储记录、索引等数据。

2).

段,分为数据段(Leaf node segment)、索引段(Non-leaf node segment)、回滚段

Rollback segment),InnoDB是索引组织表,数据段就是B+树的叶子节点, 索引段即为B+树的非叶子节点。段用来管理多个Extent(区)。

3).

区,表空间的单元结构,每个区的大小为1M。 默认情况下, InnoDB存储引擎页大小为16K, 即一个区中一共有64个连续的页。

4).

页,是InnoDB 存储引擎磁盘管理的最小单元,每个页的大小默认为 16KB。为了保证页的连续性,

InnoDB 存储引擎每次从磁盘申请 4-5 个区。

5).

行,InnoDB 存储引擎数据是按行进行存放的。 在行中,默认有两个隐藏字段:

Trx_id:每次对某条记录进行改动时,都会把对应的事务id赋值给trx_id隐藏列。

Roll_pointer:每次对某条引记录进行改动时,都会把旧的版本写入到undo日志中,然后这个

隐藏列就相当于一个指针,可以通过它来找到该记录修改前的信息。 

五、配置参数

在 MySQL 启动参数文件设置中,InnoDB 的所有参数基本上都带有前缀“innodb_”,不论是 InnoDB 数据还是和日志相关,或者是其他一些性能,事务等等相关的参数都是一样。

在 MySQL 中,可以通过 skip-innodb 参数来屏蔽 InnoDB 存储引擎,这样即使我们在安装编译时,安装了 InnoDB 存储引擎,使用者也无法创建 InnoDB 的表。

你可能感兴趣的:(关系型数据库MySQL,mysql,数据库)