MySQL中的InnoDB引擎

大白话扯一扯InnoDB存储引擎架构

在探索InnoDB存储引擎之前,我们先来补充几个重要的概念,如果没有看过我前面的文章可以去补一补哦

存储引擎是什么?

​ 和大多数的数据库不同, MySQL中有一个存储引擎的概念, 针对不同的存储需求可以选择最优的存储引擎。存储引擎就是存储数据,建立索引,更新查询数据等等技术的实现方式。存储引擎是基于表的,而不是基于库的。所以存储引擎也可被称为表类型。插件是存储引擎是MySQL数据库最重要的特性之一。

常见的存储引擎有哪些?

  • InnoDB : 是Mysql的默认存储引擎,用于事务处理应用程序,支持外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询意外,还包含很多的更新、删除操作,那么InnoDB存储引擎是比较合适的选择。InnoDB存储引擎除了有效的降低由于删除和更新导致的锁定, 还可以确保事务的完整提交和回滚,对于类似于计费系统或者财务系统等对数据准确性要求比较高的系统,InnoDB是最合适的选择。
  • MyISAM : 如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的。
  • MEMORY将所有数据保存在RAM中,在需要快速定位记录和其他类似数据环境下,可以提供几块的访问。MEMORY的缺陷就是对表的大小有限制,太大的表无法缓存在内存中,其次是要确保表的数据可以恢复,数据库异常终止后表中的数据是可以恢复的。MEMORY表通常用于更新不太频繁的小表,用以快速得到访问结果。
  • MERGE用于将一系列等同的MyISAM表以逻辑方式组合在一起,并作为一个对象引用他们。MERGE表的优点在于可以突破对单个MyISAM表的大小限制,并且通过将不同的表分布在多个磁盘上,可以有效的改善MERGE表的访问效率。这对于存储诸如数据仓储等VLDB环境十分合适。

你可以通过如下方式来查看自己数据库的默认引擎:

mysql> show variables like '%default_storage_engine%';
+------------------------+--------+
| Variable_name          | Value  |
+------------------------+--------+
| default_storage_engine | InnoDB |
+------------------------+--------+
1 row in set (0.02 sec)

为什么需要存储引擎?

​ 存储引擎真正的负责了MySQL中数据的存储和提取,服务器通过API和存储引擎进行通信。不同的存储引擎具有不同的功能,这样我们可以根据自己的需要,来选取合适的存储引擎。

InnoDB存储引擎的架构是怎样的?

架构图:

在这里插入图片描述

希望大家在看下面的步骤的时候,可以是不是回过头来看这张图

假设我们有一条更新数据的SQL:

update users set name='小明' where id=10

这条SQL通过一个数据库的连接然后到达MySQL中,经过SQL接口、解析器、优化器、执行器这几个环节,解析SQL语句并生成执行计划然后由执行器调用InnoDB存储引擎的接口来去执行,大概就是这样的流程

那存储引擎究竟是如何执行的呢?

让InnoDB存储引擎进行更新操作的时候,首先他会去Buffer Pool中检查"id=10"这行数据是否存在于缓冲池中,如果不存在则会将其从磁盘中加载到缓冲池里面来,并且,你想一下,在更新"id=10"这一行数据的时候肯定是不希望别人同时进行更新,此时会为这条记录加上一个独占锁

紧接着,第二部就是将旧值写入到undo log日志中去(这个日志的作用是便于事务回滚)

完成上面两步之后,此时要操作的数据一定会存在于Buffer Pool中的缓存页内(这个概念在之后会进行讲解),然后就可以基于内存对其进行修改了。注意,此时被修改的数据仅是内存中的数据,而磁盘中的数据还未被修改,因此,此时内存中的数据被称之为脏数据

在接下来,肯定是要将内存中被修改的数据刷入磁盘中去的,我们来看看它究竟是怎么做的。首先他会将此次的操作写入到redo log Buffer中去,在提交事务之后会根据一定的策略将redo log buffer中的数据到磁盘的磁盘文件中。此时你肯定会想,为什么会有这个日志呢?其实呀,是为了应对这样的情况:当你修改玩内存中的数据后,此时MySQL突然宕机了,那么就会出现在内存中被修改过并且还没有及时写入到磁盘的数据丢失的情况。有了redo log之后,即便你内存中的数据还没来得及刷入磁盘,只要入到了redo log日志中那就没关系,因为当MySQL再次启动后,会根据redo log中的信息去恢复宕机前的操作。

之前说的,在提交事务后,MySQL会根据一定的策略将Redo log buffer中的数据刷入到磁盘中去,这里的“策略”是通过参数innodb_flush_log_at_trx_commit来进行配置的,大家可以通过下面的方式来查看自己所用的MySQL现在使用的是那种策略:

mysql> show variables like '%innodb_flush_log_at_trx_commit%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.01 sec)
  • innodb_flush_log_at_trx_commit = 0

    当你提交事务的时候,不会把Redo Log Buffer中的数据刷入磁盘中。如果你在成功提交事务后出现宕机的情况,那么就会导致内存中redo lo出现数据丢失的情况

  • innodb_flush_log_at_trx_commit = 1

    这个是MySQL的默认情况,当你提交事务后,就必须把redo lo从内存刷入到磁盘上,只要你事务提交成功,那么磁盘上redo log中就一定会有相应的数据,也就是我们之前说过的情况。

  • innodb_flush_log_at_trx_commit = 2

    当你提交事务后,redo log可能不会立刻刷入到磁盘中去,可能会停留在os cache内存缓存中,一旦提交事务成功后出现宕机的情况,就会出现redo log日志丢失的情况。

在说完上面的三种策略之后,我们现在就可以来总结一下他们各自的优缺点了

策略 优点 缺点
0 因为每次提交事务不用向磁盘中写数据,因此写入速度快 数据安全性最差,无法应对提交事务后宕机的情况
1 因为,每次提交事务都要向磁盘中写入数据,因此写入性能是最差的 数据安全性最高
2 写入性能虽然不是最高的,但是也非常的高 虽然不能保证提交事务后数据不会丢失,但是最多只会丢失1s内的数据,安全性相对0来说要高很多

猜你喜欢

转载自blog.csdn.net/weixin_44829930/article/details/111547048
今日推荐