深入分析MySQL系列之总体架构介绍
bigegpt 2025-01-16 18:06 3 浏览
在我们详细深入介绍MySQL的方方面面之前,让我们首先来看一下MySQL的总体架构,从总体上对MySQL有所了解,这样我们在后面的具体介绍部分的时候才能够知道这些部分属于哪个模块,大概有什么样的作用。
MySQL的逻辑架构
首先我们来看一下MySQL的逻辑架构,如下图所示。
我们可以看到大概可以分成三层:
- Connection/thread handing,这一层其实和MySQL没有什么大的关系,在一般的C/S架构中都会存在,一般用来处理相关的连接,认证,安全等等方面,我们不具体介绍。
- Parser/Optimizer。这一层就是MySQL的大脑了,它主要工作就是解析查询语句,分析并进行优化,所有跨storage engines的函数都是在这里实现的,比如Stored Procedures,views等等。
- Storage Engines。顾名思义,这一层的主要作用就是存储和查询数据。MySQL支持很多种不同的Storage Engine,我们在后面一一给大家介绍。
并行控制
在了解了MySQL的逻辑架构之后,我们来看一下MySQL对一些常见数据库的问题的处理方法。第一个问题当然就是我们常见的并行控制,简单说就是有读写同时发生的时候会如何处理。我们在之前的文章介绍过常见的处理方法,这里MySQL选用的是读写锁,也就是说读获取锁的时候,可以有多个读同时进行,但是写的锁是排外的,也就是说有写获取锁,那么任何别的读和写都没有办法获取相应的锁。
使用锁有一个重要的问题就是如何确定锁的粒度,说白了,你把锁加在越大的粒度上,并行的性能就会降低,因为拿不到锁的概率就会变大。假如你把锁的粒度搞到比较小,拿不到锁的概率就会变低,这样并行的性能就会变好,但是问题是锁消耗的资源其实是很大的看,粒度越小就意味着需要更多的锁,从而有更多的资源消耗。这就是我们需要考虑的trade off。
MySQL在这个方面提供了一些选择,根据不同的Storage engine可以实现不同的锁机制和锁粒度。不过通常来说有两种锁的机制比较常见:
- 表锁:顾名思义,即使lock整个表。每次写一个表的时候都去抓这个表锁,也就意味着其它任何读写都需要等待这个锁。
- 行锁:这个锁的粒度相比表锁来说就细了很多,它是应用到一行上面的。也就是说只有这行的数据被修改的时候,才会影响到需要修改这行数据的读和写。这样一来其实并行读写的性能就会变得比较好。
大多数MySQL使用的不是简单的行锁。他们使用的是行锁和一种称之为多版本同步控制(MVCC)的技术。这个技术我们在之前的《Snapshot的隔离和Repeatable的读》中有详细的介绍。
Transaction
Transaction是一个通用的概念,这里我们不详细介绍,大家可以参考《Transactions的基本概念和介绍》这篇文章。
具体到MySQL,它有不同的storage engine支持Transaction,我们这里以最推荐的InnoDB来说明。
默认来说,单独的Insert,Update以及Delete操作是被隐式地转变成 一个Transaction并且立即commit的。也就是我们常说的AUTOCOMMIT。你可以使用SET AUTOCMMIT = 0/1来关掉或者打开这个功能。注意关掉之后,你就会一直在一个transaction里面,直到你commit或者rollback。
另外MySQL还可以自己设置隔离的级别,你可以简单使用下面这个命令来进行设置
如果你想了解具体关于transaction的隔离相关知识,可以参见这些文章:
《Transaction弱隔离之读提交的介绍和实现》
《Snapshot的隔离和Repeatable的读》
《Transaction弱隔离之更新丢失》
《Transaction弱隔离之Write Skew和Phantoms》
《Transaction Serializable隔离之串行执行》
《Transaction Serializable隔离之两阶段锁》
《一文带你深入理解Serializable隔离最新技术SSI》
相信读了这些文章之后,你会对Transaction的隔离相关内容有一个非常清晰的理解。
需要注意的是在MySQL中,transaction是在storage engine level实现的,这也就意味着假如你一个transaction设计多个不同的engine,那么这个transaction是不可靠的,因为不同的engine都有自己的设置,尤其是需要rollback的时候,可能transaction在其中一个engine中的内容被rollback了,而另外一个则没有。当然有时它会报错,但是很多时候都不会有这样的错误出现,所以你自己需要小心。
另外InnoDB使用的是两阶段锁,同时它也支持现实锁的设置,如下所示,这个是MySQL 8.0的新的功能。
Replication
MySQL中的replication使用的是pull的模式,也就是说它的每个replica是周期性的到source那边进行pull最新的log。简单的示意图如下所示:
通常来说为了更好地达到replication的目的,我们需要有最少3个replica,他们最好能分布在不同的数据中心(位置)。这样即使有灾难发生,比如地震等等,我们也能保证有至少一个repica是可以使用的。有关replication的基础知识可以参见这篇文章《分布式系统之leader-followers Replication深入介绍》。
Storage Engines
MySQL支持很多不同的Storage Engine,你可以根据自己的应用需求来进行选择。每个版本的MySQL对Storage Engine都有不同的支持。具体可能需要大家参考各个版本的说明。
在8.0之前,MySQL每个数据库是按照文件系统中的子目录格式来存储的。你创建了一个表,MySQL把表保存成一个.frm文件(定义)和一个.ibd文件(存储数据)。所以你创建了一个表Test,就会有两个文件出现,一个是Test.frm一个是Test.ibd。假如你使用了partition的话,还会有一个Test.par文件。
在8.0之中,MySQL重新定义了表的metadata,把它直接包含到标的.ibd文件中。这样一来表的结构就支持了transaction和atomic数据定义的改变。这样我们可以使用一个基于LRU的memory cache来保存partition的定义,表的定义等等。这样可以有效的降低了IO的消耗。
下面我们来看几种常见的存储引擎:
InnoDB引擎
我们其实上文也提到过,InnoDB是MySQL默认的也是最常见的存储引擎。它主要应用于那些很短的transaction。另外它的性能很好,且支持自动crash恢复,所以常见的无transaction应用也会使用它。
InnoDB使用的MVCC来实现concurrency的处理,并且实现了所有的四种隔离。默认是Repeatable read的隔离。它使用的cluster index,所以primary key的查询很快,但是secondary index则有可能受primary key影响。
InnoDB有一些内置的优化,比如预测读,内存哈希索引加速查询,插入buffer来加速插入操作等。后面我们会再写几篇文章来详细介绍这些内容。
JSON文档支持
从5.7版本开始,MySQL的InnoDB开始支持JSON格式的自动validation以及快速读。和以前的BLOB的存储方式相比有了很大的进步。紧接着InnoDB设置可以支持一些基于JSON的SQL函数。8.0.7之后,开始支持JSON数组的多指索引。这可以进一步加速JSON格式的匹配某种pattern的读速度。
MYISAM
这个引擎是MySQL的第一个引擎,也是5.6之前的默认引擎。它不支持transaction也不支持行锁。在8.0中已经完全移除了。
Archive Engine
Archive Engine只支持INSERT和SELECT查询,直到5.1才支持索引,相比来说,磁盘IO消耗会小很多。它只是一个简单的为高速插入和压缩设计的引擎。
CSV Engine
CSB引擎可以把逗号分割文件解析成表格,但是不支持索引。所以可以很方便地进行csv文件的导入和导出。
Memory Engine
这个引擎是用来匹配快速读写或者不需要在重启时保存的场景的。所有的数据都是保存在memory中,所以查询速度很快,不需要等待I/O。但是不会有数据保存。其实MySQL内部会使用它来作为一些临时表的结果保存。当然数据太大,也会把它转变成其他格式比如MyISAM表保存到磁盘中等。
Merge Storage Engine
它是多个MyISAM的组合,现在已经被废弃了。
总结
至此,本文详细介绍了MySQL的基本架构以及常见的并行控制,transaction, replication的实现。最后还介绍了各种不同的Storage Engine,希望大家阅读后能对MySQL有一个大概的了解。
总结了很多有关于java面试的资料,希望能够帮助正在学习java的小伙伴。由于资料过多不便发表文章,创作不易,望小伙伴们能够给我一些动力继续创建更好的java类学习资料文章,
请多多支持和关注小作,别忘了点赞+评论+转发。右上角私信我回复【03】即可领取免费学习资料谢谢啦!
原文出处:https://donggeitnote.com/2021/07/07/mysql-architecture/?hmsr=toutiao.io&utm_campaign=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
相关推荐
- 10w qps缓存数据库——Redis(redis缓存调优)
-
一、Redis数据库介绍:Redis:非关系型缓存数据库nosql:非关系型数据库没有表,没有表与表之间的关系,更不存在外键存储数据的形式为key:values的形式c语言写的服务(监听端口),用来存...
- Redis系列专题4--Redis配置参数详解
-
本文基于windowsX64,3.2.100版本讲解,不同版本默认配置参数不同在Redis中,Redis的根目录中有一个配置文件(redis.conf,windows下为redis.windows....
- 开源一夏 | 23 张图,4500 字从入门到精通解释 Redis
-
redis是目前出场率最高的NoSQL数据库,同时也是一个开源的数据结构存储系统,在缓存、数据库、消息处理等场景使用的非常多,本文瑞哥就带着大家用一篇文章入门这个强大的开源数据库——Redis。...
- redis的简单与集群搭建(redis建立集群)
-
Redis是什么?是开源免费用c语言编写的单线程高性能的(key-value形式)内存数据库,基于内存运行并支持持久化的nosql数据库作用主要用来做缓存,单不仅仅是做缓存,比如:redis的计数器生...
- 推荐几个好用Redis图形化客户端工具
-
RedisPlushttps://gitee.com/MaxBill/RedisPlusRedisPlus是为Redis可视化管理开发的一款开源免费的桌面客户端软件,支持Windows、Linux...
- 关于Redis在windows上运行及fork函数问题
-
Redis在将数据库进行持久化操作时,需要fork一个进程,但是windows并不支持fork,导致在持久化操作期间,Redis必须阻塞所有的客户端直至持久化操作完成。微软的一些工程师花费时间在解决在...
- 你必须懂的Redis十大应用场景(redis常见应用场景)
-
Redis作为一款高性能的键值存储数据库,在互联网业务中有着广泛的应用。今天,我们就来详细盘点一下Redis的十大常用业务场景,并附上Golang的示例代码和简图,帮助大家更好地理解和应用Redis。...
- 极简Redis配置(redis的配置)
-
一、概述Redis的配置文件位于Redis安装目录下,文件名为redis.conf(Windows名为redis.windows.conf,linux下的是redis.conf)你可以通过C...
- 什么是redis,怎么启动及如何压测
-
从今天起咱们一起来学习一下关于“redis监控与调优”的内容。一、Redis介绍Redis是一种高级key-value数据库。它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富。...
- 一款全新Redis UI可视化管理工具,支持WebUI和桌面——P3X Redis UI
-
介绍P3XRedisUI这是一个非常实用的RedisGUI,提供响应式WebUI访问或作为桌面应用程序使用,桌面端是跨平台的,而且完美支持中文界面。Githubhttps://github....
- windows系统的服务器快速部署java项目环境地址
-
1、mysql:https://dev.mysql.com/downloads/mysql/(msi安装包)2、redis:https://github.com/tporadowski/redis/r...
- window11 下 redis 下载与安装(windows安装redis客户端)
-
#热爱编程是一种怎样的体验#window11下redis下载与安装1)各个版本redis下载(windows)https://github.com/MicrosoftArchive/r...
- 一款轻量级的Redis客户端工具,贼好用!
-
使用命令行来操作Redis是一件非常麻烦的事情,我们一般会选用客户端工具来操作Redis。今天给大家分享一款好用的Redis客户端工具TinyRDM,它的界面清新又优雅,希望对大家有所帮助!简介Ti...
- 一个.NET开发且功能强大的Windows远程控制系统
-
我们致力于探索、分享和推荐最新的实用技术栈、开源项目、框架和实用工具。每天都有新鲜的开源资讯等待你的发现!项目介绍SiMayRemoteMonitorOS是一个基于Windows的远程控制系统,完...
- Redis客户端工具详解(4款主流工具)
-
大家好,我是mikechen。Redis是大型架构的基石,也是大厂最爱考察内容,今天就给大家重点详解4款Redis工具@mikechen本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- skip-name-resolve (63)
- linuxlink (65)
- pythonwget (67)
- logstashinput (65)
- hadoop端口 (65)
- vue阻止冒泡 (67)
- oracle时间戳转换日期 (64)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)