MySQL 如何保证强一致性(InnoDB引擎解析)

1. MySQL 基础架构

前面写过几篇 MySQL 的文章,大多是对一些基础概念的讲解,当我想去了解存储引擎的时候发现不知从何下手,或者说不知道如何开头,回头想想好像对 MySQL 的基础架构还不是特别熟悉,所以本文尽管是介绍 InnoDB 存储引擎,但也会大致讲解一下 MySQL 的基础架构。

先看这样一张图(网上找的):

MySQL 如何保证强一致性(InnoDB引擎解析)_第1张图片

可以看出 MySQL 最上层是连接组件。下面服务器是由连接池、管理工具和服务、SQL 接口、解析器、优化器、缓存、存储引擎、文件系统组成。

看的懂吗?看不懂。没事,咱翻译一下:

MySQL 如何保证强一致性(InnoDB引擎解析)_第2张图片

大致上来说,MySQL 可以分为 Server层和 存储引擎层:

  • Server层: Server层涵盖了MySQL大部分核心业务功能,并且所有存储引擎的功能都在这一层实现,包括存储过程、触发器、视图等。;
  • 存储引擎层: 存储引擎有很多,包括 MyISAM、InnoDB 和 Memory 等,最常用的是 InnoDB,也是现在 MySQL 的默认存储引擎。

1.1 连接器

使用 MySQ L数据库,第一步是要连接MySQL数据库,这时候第一个迎接的你就是连接器。连接器负责跟客户端建立连接、获取权限、管理连接等工作。我们一般是使用命令mysql -uroot -p + Enter后输入密码并登录。

当输入密码提交登录时,MySQL客户端会与服务器建立连接,在完成TCP握手后,连接器就开始确认你所输入的用户名和密码。如果用户名密码正确则成功登录,如果用户名密码错误,会受到如下错误信息!

[root@VM-12-13-centos ~]# mysql -uroot -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
[root@VM-12-13-centos ~]# 
复制代码

1.2 查询缓存

连接建立完成后,假设你正在使用该 SQL 语句查询一条数据。

select * from user where id = 1
复制代码

接下来 MySQL 执行逻辑就回到了查询缓存中。此时MySQL拿到一个查询请求后,先到查询缓存里看看是否执行过一这条 SQL 语句,在之前如果执行过这条语句,其结果大概就是以 Key-Value(键值对)的形式直接缓存在内存中。这里的 Key 代指的是查询语句,Value 代指的是查询结果。如果你所查询的语句在查询缓存中就命中缓存,它就会把该 SQL 语句对应的 Value 值结果集返回,这样就并不会执行其他 MySQL 零部件了,大大提高了查询效率。

MySQL 如何保证强一致性(InnoDB引擎解析)_第3张图片

但是往往利弊是同时存在的,查询缓存有着一个致命的缺点,那就是查询缓存失效十分频繁。这里所说的查询缓存失效是指的只要有对一个表的更新,这个表上所有的查询缓存都会被清空。因此可能你废了很大的劲把结果存起来,还没使用呢,就被一个更新全清空了!大家都知道数据的宝贵,由于这个致命的缺点,导致查询缓存在 MySQL 8.0版本的时候就被抛弃了,也就是说 MySQL8.0 版本彻底删除了查询缓存

1.3 分析器

如果没有命中缓存,那就必须执行 SQL 语句了。这时候你所写的查询语句就到了分析器,分析器先会对 SQL 语句进行词法分析,它会分析并识别你所输入的空格、字符串和关键字都在 MySQL 中代表了什么,比如首先它会识别出来 select 关键字、表名、列名和条件。识别了 SQL 语句的这些后,就到了语法分析的阶段,它会根据MySQL 的语句标准来检查你所输入的 SQL 语句是否符合标准。如果不符合标准就会报出一个You have an error in your SQL syntax的语法错误提示。

注意: 一般语法错误提示第一个你所需要关注的是紧接着use near的内容,因为它会告诉你哪个语法附近有错误!

1.4 优化器

查询优化器,SQL 语句在查询之前会使用查询优化器对查询进行优化。

能进到优化器优化环节的 SQL 语句,说明在分析器分析的时候没有出现任何错误。那么优化器对该 SQL 语句做了些什么呢?假如一个 SQL 语句中是有索引的,优化器会根据优化规则选择合适的索引。比如之前讲的联合索引关于最左前缀原则改变索引的顺序,查询优化器就会自动优化成最优的查询 SQL。

简单来说就是优化器会判断你使用了哪种索引,使用了何种连接,其作用就是确定效率最高的执行方案

1.5 执行器

通过分析器知道了做什么,通过优化器知道了怎么做,这就遇到了一个问题,谁来做?可想而知就是执行器开始执行 SQL 语句。开始执行的时候,要先判断一下你对表是否有执行查询的权限,如果没有就会报出错误的提示信息。如果有权限,就打开表继续执行。执行器会根据表的引擎来调用提供的引擎接口,开始执行。

以上内容来自:MySQL基础架构分析

2. 存储引擎

从体系结构图中可以发现,MySQL 数据库区别于其他数据库的最重要的一个特点就是其插件式的表存储引擎。

MySQL 插件式的存储引擎架构提供了一系列标准的管理和服务支持,这些标准与存储引擎本身无关,可能是每个数据库系统本 身都必需的,如 SQL 分析器和优化器等,而存储引擎是底层物理结构和实际文件读写的实现,每个存储引擎开发者可以按照自己的意愿来进行开发。

需要特别注意的是,存储引擎是基于表的,而不是数据库

插件式存储引擎的好处是,每个存储引擎都有各自的特点,能够根据具体的应用建立不同存储引擎表。由于 MySQL 数据库的开源特性,用户可以根据 MySQL 预定义的存储引擎接口编写自己的存储引擎。若用户对某一种存储引擎的性能或功能不满意,可以通过修改源码来得到想要的特性,这就是开源带给我们的方便与力量。

由于 MySQL 数据库开源特性,存储引擎可以分为 MySQL 官方存储引擎和第三方存储引擎。有些第三方存储引擎很强大,如大名鼎鼎的 InnoDB 存储引擎(最早是第三方存储引擎,后被 Oracle 收购),其应用就极其广泛,甚至是 MySQL 数据库 OLTP(Online Transaction Processing 在线事务处理)应用中使用最广泛的存储引擎。

2.1 InnoDB

InnoDB 是 MySQL 的默认事务型引擎,也是最重要、使用最广泛的存储引擎。

它被设计用来处理大量的短期(short-lived)事务,短期事务大部分情况是正常提交的,很少会被回滚。InnoDB 的性能和自动崩溃恢复特性,使得它在非事务型存储的需求中也很流行。除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑 InnoDB 引擎。

如果要学习存储引擎,InnoDB 也是一个非常好的值得花最多的时间去深入学习的对象,收益肯定比将时间平均花在每个存储引擎的学习上要高得多。

2.2 MyISAM

在 MySQL 5.1 及之前的版本,MyISAM 是默认的存储引擎。MyISAM 提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但 MyISAM 不支持事务和行级锁,而且有一个毫无疑问的缺陷就是崩溃后无法安全恢复。

尽管 MyISAM 引擎不支持事务、不支持崩溃后的安全恢复,但它绝不是一无是处的。对于只读的数据,或者表比较小、可以忍受修复(repair)操作,则依然可以继续使用 MyISAM(但请不要默认使用 MyISAM,而是应当默认使用 InnoDB)。

但是 MyISAM 对整张表加锁,而不是针对行。读取时会对需要读到的所有表加共享锁,写入时则对表加排他锁,MyISAM 很容易因为表锁的问题导致典型的的性能问题。

2.3 Memory

如果需要快速地访问数据,并且这些数据不会被修改,重启以后丢失也没有关系,那么使用 Memory 表(以前也叫做 HEAP 表)是非常有用的。Memory 表至少比 MyISAM 表要快一个数量级,因为每个基于 MEMORY 存储引擎的表实际对应一个磁盘文件。该文件的文件名与表名相同,类型为 .frm 类型。该文件中只存储表的结构。而其数据文件,都是存储在内存中,这样有利于数据的快速处理,提高整个表的效率,不需要进行磁盘 I/O。所以 Memory 表的结构在重启以后还会保留,但数据会丢失。

Memroy 表在很多场景可以发挥好的作用:

  • 用于查找(lookup)或者映射(mapping)表,例如将邮编和州名映射的表;
  • 用于缓存周期性聚合数据(periodically aggregated data)的结果;
  • 用于保存数据分析中产生的中间数据。

Memory 表支持 Hash 索引,因此查找操作非常快。虽然 Memory 表的速度非常快,但还是无法取代传统的基于磁盘的表。Memroy 表是表级锁,因此并发写入的性能较低。它不支持 BLOB 或 TEXT 类型的列,并且每行的长度是固定的,所以即使指定了 VARCHAR 列,实际存储时也会转换成 CHAR,这可能导致部分内存的浪费。

除了以上介绍的 3 种,还有其他的如:Mrg_MyISAM ,Archive,Blackhole,CSV,Federated,还有第三方引擎XtraDB,TokuDB等等,这里就不一一介绍了。

2.4 对比

MyISAM

你可能感兴趣的:(Java,mysql,数据库,服务器)