文章索引
1. mysql网络架构模型
2. mysql执行计划explain
3. 数据存储结构分析(包括平衡树,红黑树,B树,B+树,hash分桶+开放链表,以及redis的跳表)
4. mysql 存储引擎innoDB与MyISAM对比与应用场景
5. InnoDB事务实现原理(MVCC,快照读,当前读,readview机制与锁控制)
6. InnoDB索引结构与存储
7. InnoDB内存管理与缓冲区
8. InnoDB日志模块undo log与redo log分析
9. InnoDB数据存储
10. Mysql主从同步与binlog异构应用场景
**备注:**正文红色字体会重点部分,绿色字体为涉及到的概念,读者可自行了解或者等后续文章一同探讨
正文
本篇文章把mysql整体的架构梳理了一下,以便我们对于mysql有个整体的理解。总的来说mysql是一个cpu密集型系统,所以很多模块的划分与设计,都是为了提高cpu执行效率。
mysql主要包括以下几部分:
-
网络模块:每一个存储引擎或者网络框架都实现自己一套处理请求的网络模块,在mysql中采用的是poll/select的线程池模型(如下图,这里mysql没有采用epoll实现reactor模式的网络架构,是因为mysql的瓶颈并不在网络IO,而是更多地把精力专注于sql的执行效率优化上)
(涉及概念:poll/select/epoll网络IO模型,reactor模式) -
缓存模块:mysql的server层增加一层缓存模块,类似一个内存的kv层,k是sql,value是结果
-
解析模块:sql语法树解析,这个模块的功能平时工作中经常用到, 比如sql流量截获解析,或者数据迁移设计字段转换等工作,会使用开源库做语法树解析成我们想要的结构(比如golang的github.com/pingcap/par…
-
预处理与查询优化:主要就是我们工作中经常用到的explain,查询计划,explain是每个开发者必备的分析技能,除了可以看到mysql本身对我们的查询语句做了哪些优化改动外,我们也能从查询计划中分析我们的表结构或者sql语句有没有性能问题
-
存储引擎:mysql 实现了可插拔的存储引擎,包括innodb, myisam,memory近十种存储引擎,存储引擎则是我们理解mysql最为主要的模块,比如我们理解了innodb,那就相当于我们掌握了mysql了
-
当然除了上面提到的模块,mysql还有很多管理模块比如**权限控制,内置函数库,主备同步的log模块(数据同步的binlog,数据重放的relaylog)**等
MySQL查询过程:
-
客户端发送一条查询给服务器。
-
服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果。否则进入下一阶段。
-
服务器端进行SQL解析、预处理,再由优化器生成对应的执行计划。
-
MySQL根据优化器生成的执行计划,再调用存储引擎的API来执行查询。
-
将结果返回给客户端。
InnoDB模块
存储引擎一般我们需要了解InnoDB和MyISAM两个引擎,一般开发中用得最多的就是InnoDB,上图展示了InnoDB包含的几大模块
-
事务机制:事务与锁模块,InnoDB采用我们熟悉的MVCC(Multiversion concurrency control 多版本并发控制,mvcc解决的是ACID里的I(隔离性)),同时加上锁模块(行锁,表锁,间隙锁等)使得采用InnoDB的数据能够实现多个事务的相互隔离与并发访问
(涉及概念:ACID,MVCC,隔离级别,读现象(脏读,幻读,不可重复读,可重复读)当前读,快照读,readview可见试图,行锁,表锁,间隙锁) -
异常恢复机制:log日志模块,主要包括undo log(记录某一行在多个活跃事务中的多版本日志链表,用户事务多版本控制的版本回退), redo log(记录数据更新记录,用户异常奔溃后的数据原子操作恢复)
(涉及概念:日志链表,事务递增id,回滚,清理线程,顺序IO) -
内存管理模块:内存管理模块是InnoDB最有意思的模块了,其中最主要的就是innodb的索引存储机制(采用B+树,聚集索引cluster index),数据表示采用了自定义的page结构(16k),通过buffer poll与自适应hash索引(adaptive hash index)和优化的LRU(5 新生代/3 老生代)算法,以及各种page的维护链表(freelist, flushlist,lrulist),共同构成了InnoDB的内存缓存模块,极大提高效率(内存缓存除了buffer poll,还包括了change buffer, log buffer, additional buffer pool, double write buffer)
(涉及概念:操作系统内存管理,B+树,二进制数据组织,LRU,,内存申请与释放)
备注:内存管理中的数据结构实际上很复杂,比如page的管理就细分了inode节点->segment段->extend簇->page自定义页(16k)->系统页(4k)
-
数据存储模块:作为存储引擎,数据总要以文件的形式落地的,InnoDB的表数据以.ibd文件落地磁盘(内部是以page的结构组织的二进制文件,包括root page, index page, data page等内容页),除此之外,还包括
(涉及概念,表空间,虚拟文件系统vfs,系统调用fsync,磁盘异步IO) -
表空间
-
系统表空间(system tablespace):新版本只有data directory, change buffer内容
-
undo表空间(undo tablespace): undo log文件(.ibu)
-
临时表空间(temporary tablespace): 存储临时结果
-
双写区(doublewrite file): 双写文件(.dblwr),从旧版本的系统表空间中抽离出来
-
redo log(重做日志)
-
记录修改持久化
-
异常恢复
-
循环文件顺序写**(顺序IO)**
-
**线程模块:**包括主线程,页清理线程,刷盘线程,文件读写线程,buffer读写线程等
附上官方5.8的innodb内存与磁盘架构图(图片来源)