这本书是一本相见恨晚的书,那时候我使用mysql已经有几年了,但是从来没有系统的认识过mysql,仍然停留在碎片化的感性认知阶段,后来这本书直接打通了关系型数据库的大门,基本上这本梳里没有废话,甚至可以说看完这本书,关系型数据库在理论知识上,你已经全部打通,可以说这本书里大部分内容,你应该背下来。
废话不多说,开始
1、体系架构和存储引擎
1.1 数据库和数据库实例的区别
数据库实例是操作数据库的一个客户端进程,多个数据库实例可以共享一个物理存储(数据库),这点可以类比Oracle的RAC架构HA,就是一个典型的多实例操纵同一存储的实现。
1.2体系架构
如果让你设计一个数据库你会怎么做?以下是解答
1、连接池 管理、缓冲用户的连接,线程处理等需要缓存的需求
2、管理服务和工具组件 系统管理和控制工具,例如备份恢复、Mysql复制、集群等
3、sql接口 接受用户的SQL命令,并且返回用户需要查询的结果
4、查询解析器 SQL命令传递到解析器的时候会被解析器验证和解析(权限、语法结构)
5、查询优化器 SQL语句在查询之前会使用查询优化器对查询进行优化
6、缓存 如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据
7、插入式存储引擎 存储引擎说白了就是如何管理操作数据(存储数据、如何更新、查询数据等)的一种方法。因为在关系数据库中数据的存储是以表的形式存储的,所以存储引擎也可以称为表类型(即存储和操作此表的类型)
8、物理存储
这里得提一句mysql的逻辑分层,逻辑上讲,client访问mysql的整体过程是
client ==>连接层(1,2) ==>服务层(3,4,5,6)==>存储引擎层(7)==>存储层 server(8)
引用一张图展示一下访问mysql的整体过程(图片来源:mysql指引(二):mysql逻辑结构和整体处理流程_oatlmy-CSDN博客_mysql配合oa):
1.3mysql连接方式
mysql连接操作实际上是一个连接进程和mysql数据库实例之间通信,也即进程间通信,不展开说进程间通信,随便一篇文章都有
2 Innodb存储引擎(核心)
注意框内的都是存储引擎这一层内的,包括后台线程和存储引擎内存池
2.1 后台线程
后台线程包括 Master Thread,IO Thread,Purge Thread,Page Cleaner Thread
(1)Master Thread:将缓冲池内的数据刷新到磁盘
(2)IO Thread:处理读写请求
(3)Purge Thread:回收事务提交之后不在使用的undolog页,可以多个,加快undolog的回收
(4)Page Cleaner Thread:脏页的刷新,用于减轻Master线程的压力,这里有个checkPoint机制,待有机会展开说
2.2 内存
设置缓冲池平衡CPU和磁盘之间速度的差异,同时还有一些其他的缓冲,至于缓冲池的大小,32bit系统受操作系统限制,最多支持3G,所以大多数情况下建议操作系统64bit起支持更大的存储引擎内存缓冲区。
缓冲池内页的大小默认16k,同操作系统使用优化了的MID-LRU进行管理,有兴趣的自行查看
redolog_buffer redolog缓冲默认8M,以下三种情况会将redolog刷到磁盘中:
(1)Master Thread 每秒将redolog_buffer内的数据刷入磁盘
(2)每个事务提交时会将redolog_buffer内的数据刷入磁盘
(3)redolog_buffer容量小于总容量的1/2时
书中还讲了checkpoint和Master Thread的一些特性,不过我都略过了,不是目前阶段的主要矛盾
2.3 Innodb的关键特性
以下可能时面试时体现你对Innodb理解的地方,也是很多面试文章里没有的部分
很多时候面试官问你多种存储引擎,其实他自己用过的也很有限,但是Innodb作为你最常用必须回的,几个特性还是要了解的,这块能完整说出来的人不多,我多讲一点。
1、insert buffer (提升非聚簇索引的插入性能)
insert buffer看图是在缓冲池里,其实insert buffer也是物理页的组成部分
insert buffer核心作用是提升非聚簇索引插入时的性能,只要非聚簇索引不是唯一索引,就可以利用insert buffer,其原理是当你插入或更新一条非聚簇索引时,先去缓冲池内看看非聚簇索引是否在索引页内,如果在,直接插入,如果不在,则放到insert buffer里,假装自己已经插入,然后再以一定的频率merge到索引页内。至于为什么不是唯一索引,因为如果在插入时需要校验该索引值是否唯一(也就是需要io),那本身就失去了insert buffer的意义。具体实现也是基于B+Tree的
借用一张图,图片来源右下加,侵删!
2、double write (提升数据可靠性)
考虑这种情况:innodb正在将数据写入缓冲池中的page中,写了一部分的情况下发生了宕机,例如当前data page 16kb,写入4kb之后,发生了宕机,此时无法通过redolog重做(注意redolog存储的是物理日志,也即磁盘上数据的更改,而binlog存储的是逻辑日志,说白了就是sql),doublewrite就是在应用redolog前,存储一个当前页的副本,当当前页写入失效的时候,通过副本还原现场,再进行重做。
doublewrite包括两部分,一部分是doublewrite buffer,大小2MB,一部分是物理磁盘上连续的128个页,大小同样为2MB,在对缓冲池的脏页进行刷新时,不是直接写磁盘,而是通过memcpy函数将脏页先复制到内存的doublewrite buffer中,之后通过doublewrite buffer分两次,每次1MB的大小写入共享表空间的物理磁盘,再调用fsycn同步到磁盘,由于doublewrite buffer是连续的,因此写磁盘是顺序写的。
3、自适应哈希索引:存储引擎会对索引页上的监控进行查询,如果能够通过hash索引提高查询效率,就会自动创建自适应哈希索引,不过该自适应哈希索引只能用于等值查询,而不能用于范围搜索
4、异步IO:脏页的刷新,磁盘的写入,都是通过AIO实现的
5、刷新邻接页:当一个脏页刷新时,innodb会检测该区所在的所有页,如果是脏页,一起刷新,对于传统机械硬盘,建议启用,对于固态硬盘而言,建议关闭