MySQL InnoDB架构的相关总结

引言

作为一个后端程序员,我们几乎每天都要和数据库打交道,市面上的数据库有很多,比如:Mysql,Oracle,SqlServer等等,那么我们的写的程序是怎么和数据库连接起来的呢?那就是数据库驱动,不同的数据库对应了不同的数据库驱动。在我们连接数据库的时候,首先将数据库驱动进行注册,然后基于数据库地址,用户名,密码等信息与数据库建立连接。如果用maven来管理项目的话,一般会看到如下配置:

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.24</version>
</dependency>

如上,通过maven导MySQL的驱动jar包,接着就可以在项目中通过sql语句操作数据库了。那数据库在接收到请求后,是怎么执行的呢?接下来我将通过MySQL数据库进行详细阐述。

1、Mysql数据库整体架构

一般我们知道,web项目开发完以后,可以将项目文件打成一个war包,然后通过Tomcat容器进行发布,最后用户就可以访问我们的系统了。我们都知道,Tomcat是支持并发访问的,当多个请求需要同时操作数据库的时候,难道是多个请求去抢占一个数据库连接吗?那肯定不是的,不然效率得多低下,那难道是给每个请求都建立一个连接,请求结束后再销毁连接吗?那肯定也不是的,频繁建立、销毁连接肯定也是影响性能的。那Tomcat是如何解决这个问题的呢? 还记得我们在讲线程池的时候提到的“池化”思想吗?是的,Tomcat中有一个数据库连接池,那么同样的数据库服务器中也有一个对应的数据库连接池,大致结构如下图所示

SQL接口

当请求到达数据库以后,会被监听的线程发现,继而将请求转交给SQL接口来处理,SQL接口专门用于执行增删改查这样的SQL语句。

解析器

虽然SQL语句我们比较容易理解,但是对于MySQL系统来说是没法直接理解的,所以SQL接口会把SQL语句转交给解析器,查询解析器负责将SQL语句进行解析,也就是按照既定的SQL语法,对SQL语句进行解析,理解这个SQL要完成的操作。

优化器

当解析器理解了SQL语句需要完成的操作后,接着通过优化器选择一条它认为的最优路径。一般情况下,要达到某种结果并不是只有一条路径,比如,要查询在表T里,符合条件C的两个字段f1,f2的值,至少可以有以下两种路径:

  1. 先去表T中筛选出符合条件C的所有数据行,再选出字段f1,f2的值作为结果集;
  2. 先选出所有f1,f2的值,再根据条件C筛选出符合条件的数据行组成结果集。

优化器会根据不同的策略得到它认为最优的查询路径。

执行器

当优化器选出最优的查询路径后,并不能得到我们最终希望得到的结果,所以还需要用执行器。执行器的作用就是根据优化器选出的最优查询路径生成一套执行计划,然后不停的去调用数据库存储引擎提供的接口去完成SQL语句的执行计划。

存储引擎

数据库一般将数据无非存储在两个地方:内存或磁盘。那么假如我们查询数据时,执行器需要到去磁盘还是内存中查询呢?内存中是如何查询的?磁盘中是如何查询的,内存的容量是有限的,当内存中没有多余的空间怎么办?等等一系列问题的解决方案就是存储引擎,MySQL提供了多种存储引擎:InnoDB,MyISAM,MEMORY等等,比较常见的是InnoDB和MyISAM,可以通过show engines命令查看当前MySQL数据库的存储引擎。本系列将主要分析InnoDB存储引擎。

综上,一套完整的SQL语句执行流程如下图所示

2、InnoDB存储引擎架构

假如现在一条SQL语句通过上述的流程,到了执行器调用InnoDB存储引擎的接口,那么InnoDB存储引擎是怎么工作的呢?

内存缓冲池

首先介绍InnoDB存储引擎中第一个重要组件—内存缓冲池,即Buffer Pool,这是内存中的一块区域,存储了大量数据,便于执行查询、更新等操作。这样做的目的就是提高SQL语句的执行效率,所以要明确一个概念,我们的查询、更新等操作都是在Buffer Pool中完成(无论数据是否存在于Buffer Pool中,存在的话直接操作,不存在的话先从磁盘中加载到Buffer Pool中再操作)。

undo log日志文件

熟悉数据库的同学都知道,在我们更新数据的时候一般是放在一个事务中进行操作。事务有4大特性:ACID,其中A就代表了原子性,即这次操作要么全部成功要么全部失败,成功的话就提交(commit)事务,失败就回滚(rollback),其中回滚就是通过undo log来实现的。(有一次被问到了,一时紧张没想起来,过了一会才反应过来...)。

一般MySQL数据库会默认开启事务自动提交,所以不需要我们做额外的操作,我们可以通过set autocommit = 0 来关闭自动提交事务和set autocommit来打开自动提交事务。有兴趣可以试试去感受感受。

redolog日志文件

前面我们已经介绍了,更新操作是在Buffer Pool中完成的,也就是在内存中完成的,万一操作完以后MySQL宕机了,那么必然会使内存中修改过的数据丢失。为了解决这个问题InnoDB架构中设计了redo log,用来记录你对什么数据进行了修改。如果出现MySQL宕机,重启之后可以通过redo log来进行数据恢复。但是redo log也是先将redo log写到内存中的redo log buffer中,并没有持久化到磁盘,所以数据丢失的风险依然存在。所以InnoDB提供了几种redo log刷盘策略,通过innodb_flush_log_at_trx_commit来进行设置刷盘策略,比如innodb_flush_log_at_trx_commit=1表示事务提交日志马上刷入磁盘,这样就不会存在数据丢失的风险,但是性能肯定会受到影响。一般可以根据业务需求进行设置策略。

binlog日志文件

binlog也叫归档日志,与redo log不同,这是mysql server的,而不是InnoDB所特有的,一般用户恢复某个时间点的数据,主从同步等,而redo log用户故障恢复。一般提交事务的时候也会提交归档日志。同样的归档日志也有几种刷盘策略,通过sync_binlog来控制几次事务提交后会刷盘。特别的sync_binlog=0表示由操作系统控制刷盘时机,而不是Mysql。

InnoDB执行流程

介绍完InnoDB存储引擎的几个组件后,假设现在需要更新一条数据,那么在InnoDB中的执行流程应该是怎么样的呢?如下:

  1. 如果数据不存在于Buffer Pool中,则随机I/O从磁盘读取数据,放入Buffer Pool;
  2. 写undo log用于回滚数据;
  3. 更新Buffer Pool中的数据;
  4. 写redo log到redo log buffer用于故障恢复数据;
  5. 准备提交事务,redo log日志基于策略准备刷入磁盘;
  6. 准备提交事务,binlog日志基于策略准备刷入磁盘;
  7. 写入binlog文件与commit标记到redo log日志文件;
  8. 提交事务;
  9. 后台IO线程将Buffer Pool中脏数据输入磁盘。(因为前期只修改了Buffer Pool中日志,磁盘中数据并未修改,所以对于磁盘数据来说,Buffer Pool中的数据是脏数据)

流程如下图所示:

以上就是MySQL InnoDB架构的相关总结的详细内容,更多关于MySQL InnoDB架构的资料请关注我们其它相关文章!

(0)

相关推荐

  • MySQL InnoDB 锁的相关总结

    1.  Shared and Exclusive Locks shared lock (译:共享锁) exclusive lock (译:排它锁.独占锁) InnoDB实现了标准的行级锁,其中有两种类型的锁,共享锁(shared locks)和排他锁(exclusive locks). A shared (S) lock permits the transaction that holds the lock to read a row. An exclusive (X) lock permits

  • MySQL InnoDB表空间加密示例详解

    前言 从 MySQL5.7.11开始,MySQL对InnoDB支持存储在单独表空间中的表的数据加密 .此功能为物理表空间数据文件提供静态加密.该加密是在引擎内部数据页级别的加密手段,在数据页写入文件系统时加密,加密用的是AES算法,而其解密是在从文件读到内存中时进行. 1 配置加密插件 1.1 修改配置文件 在mysql配置文件[mysqld]x项中添加如下内容 plugin_dir=/usr/local/mysql5.7/lib/mysql/plugin # 插件路径,根据实际情况修改 ear

  • MySQL创建数据表时设定引擎MyISAM/InnoDB操作

    我在配置mysql时将配置文件中的默认存储引擎设定为了InnoDB.今天查看了MyISAM与InnoDB的区别,在该文中的第七条"MyISAM支持GIS数据,InnoDB不支持.即MyISAM支持以下空间数据对象:Point,Line,Polygon,Surface等." 作为一个地理信息系统专业的学生(其实是测绘专业)来讲,能存储空间数据的数据库才是好数据库,原谅我是数据库小白的身份. 有三种方式可以设定数据库引擎: (1)修改配置文件 将安装目录下~\MySQL\mysql-5.6

  • MySQL Innodb 存储结构 和 存储Null值 用法详解

    背景: 表空间:INNODB 所有数据都存在表空间当中(共享表空间),要是开启innodb_file_per_table,则每张表的数据会存到单独的一个表空间内(独享表空间). 独享表空间包括:数据,索引,插入缓存,数据字典.共享表空间包括:Undo信息(不会回收<物理空间上>),双写缓存信息,事务信息等. 段(segment):组成表空间,有区组成. 区(extent):有64个连续的页组成.每个页16K,总共1M.对于大的数据段,每次最后可申请4个区. 页(page):是INNODB 磁盘

  • 详解MySQL InnoDB存储引擎的内存管理

    存储引擎之内存管理 在InnoDB存储引擎中,数据库中的缓冲池是通过LRU(Latest Recent Used,最近最少使用)算法来进行管理的,即最频繁使用的页在LRU列表的最前段,而最少使用的页在LRU列表的尾端,当缓冲池不能存放新读取到的页时,首先释放LRU列表尾端的页. 上面的图中,我使用8个数据页来表示队列,具体作用,先卖个关子.在InnoDB存储引擎中,缓冲池中页的默认大小是16KB,LRU列表中有一个midpoint的位置,新读取到的数据页并不是直接放入到LRU列表的首部,而是放入

  • MySQL Innodb关键特性之插入缓冲(insert buffer)

    什么是insert buffer? 插入缓冲,也称之为insert buffer,它是innodb存储引擎的关键特性之一,我们经常会理解插入缓冲时缓冲池的一个部分,这样的理解是片面的,insert buffer的信息一部分在内存中,另外一部分像数据页一样,存在于物理页中. 在innodb中,我们知道,如果一个表有自增主键,那么对于这个表的默认插入是非常快的,注意,这里的主键是自增的,如果不是自增的,那么这个插入将会变成随机的,就可能带来数据页分裂的开销,这样,插入就不是顺序的,就会变慢.还有一种

  • MySQL InnoDB ReplicaSet(副本集)简单介绍

    01 InnoDB ReplicaSet(副本集)介绍 在MySQL8.0引入了InnoDB ReplicaSet,它提供了我们熟悉的复制特性,如果有mongodb副本集的概念,理解InnoDB ReplicaSet会比较容易. InnoDB ReplicaSet使用了下面的技术: 1.MySQL Shell,一个功能更强大的客户端 2.MySQL Router,一个轻量级别的中间件,可以类比MongoDB中的mongos的角色: 3.MySQL Server,也就是MySQL服务 InnoDB

  • 修改MySQL数据库引擎为InnoDB的操作

    PS:我这里用的PHPStudy2016 1.修改时停止MySQL 2.修改my.ini default-storage-engine=INNODB 3.修改后删除D:\phpStudy\MySQL\data下ib开头的日志文件 4.启动MySQL 设置好后,通过navicat创建与目标数据库一致编码的新数据库,然后复制过来即可.复制过来的数据表数据引擎与源数据表数据引擎一致. 注:修改数据表引擎 alter table tableName type=InnoDB 补充:InnoDB和MyISA

  • MySQL InnoDB架构的相关总结

    引言 作为一个后端程序员,我们几乎每天都要和数据库打交道,市面上的数据库有很多,比如:Mysql,Oracle,SqlServer等等,那么我们的写的程序是怎么和数据库连接起来的呢?那就是数据库驱动,不同的数据库对应了不同的数据库驱动.在我们连接数据库的时候,首先将数据库驱动进行注册,然后基于数据库地址,用户名,密码等信息与数据库建立连接.如果用maven来管理项目的话,一般会看到如下配置: <dependency> <groupId>mysql</groupId> &

  • MySQL InnoDB 存储引擎的底层逻辑架构

    目录 正文 内存架构 1. 自适应哈希索引 2. Buffer pool 3. Change buffer 4. Log Buffer 磁盘架构 1. 系统表空间 2. 独立表空间 3. 普通表空间 4. Undo 表空间 5. 临时表空间 总结 正文 我们都知道 MySQL 数据库有很多个存储引擎,其中另我们印象深刻的应该是 InnoDB 存储引擎,它从 MySQL 5.5 之后就是默认的存储引擎,它有支持事务.行级锁.MVCC 以及外键等优点. 那么你知道InnoDB存储引擎的底层逻辑架构吗

  • MySQL InnoDB存储引擎的深入探秘

    前言 在MySQL中InnoDB属于存储引擎层,并以插件的形式集成在数据库中.从MySQL5.5.8开始,InnoDB成为其默认的存储引擎.InnoDB存储引擎支持事务.其设计目标主要是面向OLTP的应用,主要特点有:支持事务.行锁设计支持高并发.外键支持.自动崩溃恢复.聚簇索引的方式组织表结构等. 体系架构 InnoDB存储引擎是由内存池.后台线程.磁盘存储三大部分组成. 线程 InnoDB 使用的是多线程模型, 其后台有多个不同的线程负责处理不同的任务 Master Thread Maste

  • MySQL高级学习笔记(三):Mysql逻辑架构介绍、mysql存储引擎详解

    Mysql逻辑架构介绍总体概览 和其它数据库相比,MySQL有点与众不同,它的架构可以在多种不同场景中应用并发挥良好作用.主要体现在存储引擎的架构上,插件式的存储引擎架构将查询处理和其它的系统任务以及数据的存储提取相分离 . 这种架构可以根据业务的需求和实际需要选择合适的存储引擎. controller层: Connectors:连接层,c .java等连接mysql 业务逻辑处理成: Connection Pool:连接层 c3p0连接池等 Manager Service util:备份.容灾

  • MySQL 整体架构介绍

    MySQL 在整体架构上分为 Server 层和存储引擎层.其中 Server 层,包括连接器.查询缓存.分析器.优化器.执行器等,存储过程.触发器.视图和内置函数都在这层实现.数据引擎层负责数据的存储和提取,如 InnoDB.MyISAM.Memory 等引擎.在客户端连接到 Server 层后,Server 会调用数据引擎提供的接口,进行数据的变更. 连接器 负责和客户端建立连接,获取用户权限以及维持和管理连接. 通过 show processlist; 来查询连接的状态.在用户建立连接后,

  • 深入了解Mysql逻辑架构

    Mysql现在是大多数公司企业在用的数据库,之所以用Mysql,一点是因为Mysql是开源软件,一些有能力的公司会基于已有的Mysql架构,进行修改.调整改成适合自己公司的业务需要. 一点是因为Mysql免费,相对昂贵的Oracle服务,对于很多刚起步的公司来说,是最适合不过的数据库了. 之所以要认识Mysql的逻辑架构,就好比我们自己在做开发时,首先需要先掌握自己系统用的分层架构,这样在开发的过程中,如果有哪个环节产生问题,就很好排查.认识Mysql的逻辑架构也同理,我们在用Mysql的时候,

  • Mysql InnoDB 的内存结构详情

    目录 1 前言 2 InnoDB 存储引擎结构 2.1 InnoDB表存储引擎文件 2.2 InnoDB 预读机制 2.3 InnoDB 特性 2.3.1 插入缓存 2.3.2 二次写 (double write) 2.3.3 自适应hash索引 2.3.4 异步IO 2.3.5 刷新邻接页 3 sql 执行的逻辑 3.1 sql 执行 3.2 FreeList.LRU List 和 Flush List 1 前言 我们都熟悉mysql数据库服务架构,也清楚 sql 的执行顺序,mysql的数据

  • 一条sql详解MYSQL的架构设计详情

    目录 1 前言 2 应用层 2.1 连接线程处理 3 服务层 3.1 SQL 接口 3.2 SQL解析器 3.3 SQL优化器 3.4 执行器 3.5 查询缓存 4 存储引擎层 4.1 概述 4.2 缓冲池(buffer pool) 4.2.1 数据页.缓存页和脏页 4.2.2 元数据 4.2.3 free链表 4.2.4 flush链表 4.2.5 LRU链表 4.2.6 小结 4.3 undo log 4.4 redo log 5 总结 1 前言 对于一个服务端开发来说 MYSQL 可能是他

  • MySQL学习之MySQL基本架构与锁

    目录 MySql架构 MySQL锁 锁的分类 按粒度分 按功能分 锁的演示 表锁 行锁 意向锁 MySql架构 SQL Layer Connection Pool : 连接池,用于接收连接请求和管理连接. ManagementService&Utilities 管理服务组件和工具组件,主要提供了一些备份,安全,主从,集群,等功能. SQL Interface:主要提供了SQL语句接口.包括SQL解析器,优化器,缓存等.将我们输入的SQL语句,解析成节点树,然后传递给存储引擎执行. Storage

随机推荐