MySQL组成模块
- 连接器:客户端通过驱动连接,连接器负责进行连接交互
- 查询缓存:针对查询语句的缓存,只有查询语句完全一致时,才能命中,8.0以移除
- SQL解析器:将SQL语句解析成语法树
- 预处理模块:检查查询字段和表是否存在,还有扩展查询时
*
为全部字段 - 优化器:根据代价选择一种执行代价最低的路径,比如存在多个索引时,选择使用哪个索引
- 执行器:与存储引擎交互,将执行计划交给存储引擎
MySQL存储基础
MySQL数据文件存储位置
|
|
这个目录下会为每个数据库创建一个目录,目录下有这几种文件
- *.frm文件:表结构文件,存储表结构定义
- *.ibd文件:表数据文件,每张表一个单独的ibd文件
- *.opt文件:存储当前数据库默认字符集和字符校验规则
MySQL表空间的结构
表空间由:段、区、页、行组成
行就是表中的一行数据,表结构不同,行存储也有不同的存储结构。
页是存储引擎操作的最小单位,默认大小为16KB,从硬盘读取或写入硬盘都是以16KB的大小进行操作的,这是为了降低磁盘I/O。页的类型有很多种,数据页、Undo页等,数据存储在数据页中。
区由64个页组成,大小1MB。页还是太小了,数据很容易存储在不同的页中,造成随机I/O。因此数据量大的时候,会使用区来分配,这样可以使得多个页是顺序存储的。
段由多个区组成,表空间由多个段组成。
MySQL行格式
行格式指示了一行数据如何组织和记录的。下面是COMPACT行格式
的组织形式。行格式将一条数据分为额外记录信息和真是数据两部分。
变长字段长度列表
记录每一个类型为varchar
的列的字节长度。比如存储了一个字符,而且字符集为ascii,那么字节长度为1。如果有多个类型为varchar
的列,他们的存放顺序是逆序的。当不存在varchar
类型的列时,变长字段长度列表不存在。
NULL值列表
以一个8bit的数,来标识那个列可以为NULL
,可以为NULL
的列置为1,少于8列,也是8bit,多余8列,再往上补8bit。NULL值列表的位,也是逆序存储的。当没有允许为NULL的列时,NULL值列表这个额外字段不存在。
行溢出
当一行的数据大于一页的存储空间16KB时,会发生行溢出。溢出有两种处理方式:
- 将溢出的部分移到溢出页,未溢出的部分后面记录一个指针,指向溢出页的位置。
- 真实数据只存储指向溢出页的指针,所有数据都存储在溢出页。
索引
索引分类
我们可以按照四个角度来分类索引。
- 按「数据结构」分类:B+tree索引、Hash索引、Full-text索引。
- 按「物理存储」分类:聚簇索引(主键索引)、二级索引(辅助索引)。
- 按「字段特性」分类:主键索引、唯一索引、普通索引、前缀索引。
- 按「字段个数」分类:单列索引、联合索引。
MySQL常见面试题
索引底层使用了什么数据结构和算法?
为什么 MySQL InnoDB 选择 B+tree 作为索引的数据结构?
什么时候适用索引?
什么时候不需要创建索引?
什么情况下索引会失效?
有什么优化索引的方法?
基于GTID搭建数据库主从
GTID同步原理
GTID(Global Transaction ID)全局事务ID。主库每一个事务产生一个全局唯一的GTID号,连同变更记录一同写入到bin-log日志中,从库的io线程拉取主库变更的bin-log日志,同步到本地的relay-log日志中,sql线程读取relay-log日志内的GTID号,对比本地的bin-log日志内的GTID,查看是否执行过该GTID号代表的事务,如果没有,将变更内容写入数据库,如果有则忽略。