代码改变世界

MySQL-存储引擎架构

2022-12-29 09:52  杭伟  阅读(127)  评论(0编辑  收藏  举报

MySQL是一种分层体系结构的关系数据库。

一共有三层:客户(连接)层,Server层,存储引擎层。

简单理解就是这三层架构。官网的解释在这里。(这个部分建议看8.0的文档,8.0文档补充了架构图,5.7没有放图)

如上图所示(请记住各层的上下顺序,比如索引下推概念中的下推pushdown指的就是server层处理的where下推到存储引擎层):

客户(连接)层:负责连接处理,验证,安全

Server层:核心层,负责 连接线程处理,NoSQL接口,SQL接口,解析器,优化器,缓存

存储引擎层:各种可插拔替换的存储引擎,如InnoDB,MyISAM,Memory等

主要需要关注Server层和存储引擎层的分工不同:

Server层负责--所有跨存储引擎层的通用功能,如各种接口,存储过程,视图,触发器,SQL语句操作等等

存储引擎层负责--为数据库执行实际的IO操作

 

**Server层的binlog

开启binlog

同时要设置日志记录格式,参考

 

查看binlog是否启用:

show variables like 'log_%';

 

 SHOW BINARY LOGS; 列出二进制文件。参考

使用mysqlbinlog查看binlog文件:

 mysqlbinlog --base64-output=DECODE-ROWS -v /var/lib/mysql/mysql-bin.000001

 可以看到binlog中记录了每一个操作的sql语句。

 

**Server层的查询缓存

查询缓存在8.0被取消,因为在一个频繁更新的表中,查询缓存命中率极低。另外它的扩展性问题也是瓶颈所在

 

存储引擎层: 

InnoDB磁盘结构一篇中有大致描述Disk Stuctures。关于Memory Structures中则主要是Buffer Pool以及自适应哈希索引。

存储引擎-InnoDB架构,图片来源

Buffer Pool:内存结构中的操作缓冲池,数据在刷盘前的缓冲阵地,提高读写性能。注意,它是直接操作磁盘页结构前的一个内存缓冲,

                     里面一样是管理的页结构。由于不是实时刷盘,数据在内存中有丢失的风险,因此才引入了redo log机制。

Buffer Pool也是mysql调优的一个重要部分。

由于Buffer Pool的内存大小是有限的,不可能缓存所有的数据页。应该缓存一些频繁操作的“热数据”,同时清理冷却数据,这就涉及到空间管理。

如何判断及取出磁盘页中的热数据呢?

使用了改进的LRU(Least Recently Used)算法 ,将LRU链表的数据做冷热区域划分。具体参考

 

**redo log

上文已经介绍了redo log被引出的背景:我们日常操作sql直接操作的其实是innodb的buffer pool,为了保证buffer pool的数据不丢失, 引入了redo log。

redo log恢复内存中未完成的事务/提交,binlog恢复数据库完整记录。仅凭binlog,可能存在丢失未刷盘事务数据的情况,所以mysql不建议删除redo log并直接使用binlog来

恢复数据库。同时恢复数据库时,redo log的操作部分是完全自动的不需要人为介入。 

 

**undo log

undo log是事务开始前将数据状态进行记录,方便进行数据回滚。用来保证事务的原子性(事务过程全部成功/全部失败,借助undo log可以恢复数据到原始状态)。

 

扩展问题

**为什么存储引擎基于表而不是基于数据库

 在InnoDB磁盘结构这一章中,我们知道一个数据库由许多表组成,表即是InnoDB的tablespace。

表空间与数据库到底是什么关系??有人说存储引擎是基于表的,我们也知道InnoDB里一大堆的tablespace。

但是数据库呢?数据库和它对应在InnoDB物理文件中又是什么?

从mysql服务器物理文件上看,数据库就是对应了一个文件夹,表对应了具体的文件(innodb==》.frm,.ibd)。

创建数据库官方解释:MySQL 中的数据库被实现为包含与数据库中的表相对应的文件的目录。因为最初创建数据库时没有表,所以该Create database语句只在MySQL数据目录下创建一个目录。