细读经典第二期——所有后端程序员必读神作!!!!《MySQL技术内幕 InnoDB存储引擎第2版》

这本书是一本相见恨晚的书,那时候我使用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会检测该区所在的所有页,如果是脏页,一起刷新,对于传统机械硬盘,建议启用,对于固态硬盘而言,建议关闭

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值