一.MySQL整体逻辑架构

第一层:连接层:连接处理,身份验证,安全性等等。
第二层:核心服务层 。这是MySQL的核心部分。在 MySQL据库系统处理底层数据之前的所有工作都是在这一层完成的,包括权限判断, sql解析,行计划优化, query cache 的处理以及所有内置的函数(如日期,时间,数学运算,加密)等等。各个存储引擎提供的功能都集中在这一层,如存储过程,触发器,视图等。
第三层:存储引擎层。也就是底层数据存取操作实现部分,由多种存储引擎共同组成。它们负责存储和获取所有存储在MySQL中的数据。就像Linux众多的文件系统 一样。每个存储引擎都有自己的优点和缺陷。服务器是通过存储引擎API来与它们交互的。这个接口隐藏 了各个存储引擎不同的地方。对于查询层尽可能的透明。这个API包含了很多底层的操作。如开始一个事 物,或者取出有特定主键的行。存储引擎不能解析SQL,互相之间也不能通信。仅仅是简单的响应服务器 的请求。
第四层:数据存储层。主要是将数据存储在运行于裸设备的文件系统之上,并完成与存储引擎的交互。
二.MySQL架构详图(摘自网络,待完善)

1.Connectors
指的是不同语言中与SQL的交互,如php、java等。
2 Management Serveices & Utilities:
系统管理和控制工具
3 Connection Pool: 连接池
管理缓冲用户连接,线程处理等需要缓存的需求。
负责监听对 MySQL Server 的各种请求,接收连接请求,转发所有连接请求到线程管理模块。每一个连接上 MySQL Server 的客户端请求都会被分配(或创建)一个连接线程为其单独服务。而连接线程的主要工作就是负责 MySQL Server 与客户端的通信,
接受客户端的命令请求,传递 Server 端的结果信息等。线程管理模块则负责管理维护这些连接线程。包括线程的创建,线程的 cache 等。
4 SQL Interface: SQL接口。
接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface
5 Parser: 解析器。
SQL命令传递到解析器的时候会被解析器验证和解析。
主要功能:
a . 将SQL语句进行语义和语法的分析,分解成数据结构,然后按照不同的操作类型进行分类,然后做出针对性的转发到后续步骤,以后SQL语句的传递和处理就是基于这个结构的。
b. 如果在分解构成中遇到错误,那么就说明这个sql语句是不合理的
6 Optimizer: 查询优化器。
SQL语句在查询之前会使用查询优化器对查询进行优化。就是优化客户端请求的 query(sql语句) ,根据客户端请求的 query 语句,和数据库中的一些统计信息,在一系列算法的基础上进行分析,得出一个最优的策略,告诉后面的程序如何取得这个 query 语句的结果。
7 Cache和Buffer: 查询缓存。
8 、存储引擎接口(未完成)
三.SQL SELECT语句执行过程

MySQL 整个查询执行过程,总的来说分为 6 个步骤 :
SQL执行步骤:请求、缓存、SQL解析、优化SQL查询、调用引擎执行,返回结果
1、连接:客户端向 MySQL 服务器发送一条查询请求,与connectors交互:连接池认证相关处理。
2、缓存:服务器首先检查查询缓存,如果命中缓存,则立刻返回存储在缓存中的结果,否则进入下一阶段
3、解析:服务器进行SQL解析(词法语法)、预处理。
4、优化:再由优化器生成对应的执行计划。
5、执行:MySQL 根据执行计划,调用存储引擎的 API来执行查询。
6、结果:将结果返回给客户端,同时缓存查询结果。
四.SQL更新机制和日志记录
4.1、基本流程:
查询语句的流程,更新语句也会同样的走一遍。sql= update T set c=c+1 where id=2
1、客户端向 MySQL 服务器发送一条更新请求
2、清除表查询缓存,跟这个有关的查询缓存会失效。这就是一般不建议使用查询缓存的原因。
3、分析器进行 SQL解析(词法和语法分析),分析这是一条更新语句和。
4、优化器生成对应的执行计划,优化器决定使用ID这个索引;
5、执行器负责更新,找到这一行,然后进行更新:

取数据行: 执行器先找引擎取 ID=2 这一行: ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。)
更新数据: 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
更新内存: 引擎将这行新数据更新到内存中,
更新 redo log :同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。
写入binlog:执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
提交事务: 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。
4.2、日志类型
与查询流程不同的是,更新流程涉及两个重要日志模块:redo log(重做日志)和 binlog(归档日志)。redo log是InnoDB存储引擎层的日志,binlog是MySQL Server层记录的日志, 两者都是记录了某些操作的日志(不是所有)自然有些重复(但两者记录的格式不同)。
redo log在数据库重启恢复的时候被使用,因为其属于物理日志的特性,恢复速度远快于逻辑日志。而binlog和undo log属于的逻辑日志。
4.3、redo log(重做日志):
redo log 是InnoDB引擎特有的物理日志,记录的是数据页的物理修改,即用于记录事务操作的变化,不管事务是否提交都会记录下来。有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,InnoDB存储引擎会使用redo log恢复到掉宕机前的时刻,以此来保证数据的完整性。这个能力称为crash-safe。
在一条更新SQL语句进行执行的时候,InnoDB引擎会把更新记录写到redo log日志中,并更新内存,这时更新完成。同时InnoDB引擎在适当的时候,将这个操作记录更新到磁盘里。
在MySQL中,每次的更新操作都需要写进磁盘,然后磁盘也要找到对应记录,进行更新,整个过程的IO成本、查找成本都很高。可使WAL(Write-Ahead-Logging)技术,他的关键点是先写日志,再写磁盘。
4.3.1 redo log的实施流程(待详细完善):
提交事务 -> 日志写入relog log buffer -> os buffer -> 写入磁盘的log file -> 根据checkpoint更新磁盘中的数据
innodb_flush_log_at_trx_commit 有3种值:0、1、2,默认为1。但注意,这个变量只是控制commit动作是否刷新log buffer到磁盘。
4.3.3 Redo log机制:
InnoDB的redo log 是固定大小,即记录满了以后就从头循环写。

图中展示了一组 4 个文件的 redo log 日志,checkpoint 是当前要擦除的位置,擦除记录前需要先把对应的数据落盘(更新内存页,等待刷脏页)。write pos 到 checkpoint 之间的部分可以用来记录新的操作,如果 write pos 和 checkpoint 相遇,说明 redolog 已满,这个时候数据库停止进行数据库更新语句的执行,转而进行 redo log 日志同步到磁盘中。checkpoint 到 write pos 之间的部分等待落盘(先更新内存页,然后等待刷脏页)。
4.4、binlog (归档日志)
binlog是属于MySQL Server层面的,又称为归档日志,属于逻辑日志,是以二进制的形式记录的是这个语句的原始逻辑,依靠binlog是没有crash-safe能力的.
binlog主要作用:复制(Master-Slave 主从同步)、恢复和审计。
最开始 MySQL 里并没有 InnoDB 引擎。MySQL 自带的引擎是 MyISAM,但是 MyISAM 没有 crash-safe 的能力,binlog 日志只能用于归档。而 InnoDB 是另一个公司以插件形式引入 MySQL 的,既然只依靠 binlog 是没有 crash-safe 能力的,所以 InnoDB 使用另外一套日志系统------也就是 redo log 来实现 crash-safe 能力。
1、binlog是Server层实现的,意味着所有引擎都可以使用binlog日志
2、binlog通过追加的方式写入的,可通过配置参数max_binlog_size设置每个binlog文件的大小,当文件大小大于给定值后,日志会发生滚动,之后的日志记录到新的文件上。
4.5 redo log和binlog区别
redo log是属于innoDB层面,binlog属于MySQL Server层面的,这样在数据库用别的存储引擎时可以达到一致性的要求。
redo log是物理日志,记录该数据页更新的内容;binlog是逻辑日志,记录的是这个更新语句的原始逻辑
redo log是循环写,日志空间大小固定;binlog是追加写,是指一份写到一定大小的时候会更换下一个文件,不会覆盖。
binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用。