Fork me on GitHub

MySQL

MySQL的底层基础补一下。先占个坑。

执行步骤

先检查是否有权限,如果没有权限直接返回,如果有权限就去查询缓存QueryCache(如果开了的话,现在已经关掉了),命中直接返回结果否则进行词法分析,语法分析,优化器进行优化(语义优化,语法优化,执行优化),然后执行,返回结果。

数据结构

MySQL的存储采用了B+树的数据结构,建立的索引也是B+树。B+树是一种多路平衡树,最大搜索次数是树的深度。B+树支持全局搜索,相较二叉查找树更加矮胖,同样B树的非叶子节点存储数据信息,而B+树只存储键值,剩余的位置可以存储更多的键值,使得树更矮胖。因为叶子结点都在同一层,查询时间稳定。叶子结点由指针链接起来对范围查找非常有利。

索引

要不要建立索引要多方考虑,索引的类型很多。ElasticSearch中采用了倒排索引,而MySQL中主键是聚簇索引,属于一级索引。

一级索引:B+树,叶子结点包含了行的全部数据(索引和数据存储),节点页只包含主键。

二级索引:二级索引可以有0个,1个或者多个。二级索引的结点只存被索引列的值,而二级索引的叶子结点存索引列值和主键值。

数据库容错

主从复制

QueryCache

参考

避免相同SQL的硬解析(语法分析>语义分析>生成执行计划),SQL执行结果缓存在RESULT CACHE内存组件中,有效将的将物理IO转化为逻辑IO,提高SQL执行效率。但是更新数据库使缓存失效,因此频繁更新操作并不适合开启QC。理想的情况是相同的查询由相同或者多个客户机重复发出,被访问的底层数据本质上是静态或者半静态,并发性和QPS(Query Per Second)都不高,然而实际的业务系统都是有CRUD的,数据更新比较频繁,查询接口的QPS比较高。开启后对数据库并发度和处理能力都会降低很多。同时查询缓存碎片化还会导致服务器的负载升高,影响数据库的稳定性。

查询缓存分片数据块默认大小是4KB,如果有很多查询结果很小,那么默认数据块大小可能会导致内存碎片,由于内存不足,碎片可能会强制查询缓存从缓存中删除查询。在这种情况下,可以减小它的值,如果大量的查询有较大的结果集,可以增大该参数的值来提高性能

这段的思想其实就是组原学过的内存管理,虽然QC已经退出MySQL,但在系统优化方法上还是可以学习的。

InnoDB

BufferPool

参考

MySQL不会直接修改磁盘的数据,会先改内存,然后记录redo log,等有空了再刷新磁盘,这些数据就存在Bufer Pool。就像我们平时开发会用redis来缓解数据库压力。基于LRU(least recently used)算法来管理内存。

这其实也是内存管理内容,缓存的思想无处不在。

Change Buffer

只在操作二级索引时才用,因为聚簇索引必须是唯一的。要修改的页不在内存里,就把要对页的修改先寄到Change Bufer中,同时记录redo log,再慢慢把数据load到内存,然后把Change Buffer中的修改应用到内存(Buffer Pool)中,这个动作叫merge。

Adaptive Hash Index

MySQL索引在磁盘和内存都是B+树,频繁访问的数据用指针把数据位置记录下来。

Log Buffer

redo log会刷到磁盘中。

Doublewrite Buffer

用来保证数据页可靠性。

MySQL在刷数据到磁盘之前,要先把数据写到Doublewrite Buffer, 写完之后再开始写磁盘。万一发生crash可以利用它来修复磁盘数据。

PageCache

是操作系统层面的,在磁盘上提供的缓存区。

面试专题

参考1 2



本文标题:MySQL

文章作者:tsuki

发布时间:2022.03.22 - 22:03

最后更新:2022.03.25 - 22:11

原始链接:https://tsuki419.github.io/MySQL.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------THE END-------------
0%