数据库是通过SQL存储和处理数据的,那么数据库内部是通过哪些部件来处理SQL的呢?
一、综述
总体来说,数据库内部的运行部件可以分为如下几种:监听器(Listener)、解析器(Parser)、优化器(Optimizer)、执行器(Executer)、存储管理器(Storage Manager)和协调器(Coordinator)。
上述部件中,解析器、优化器和执行器统称SQL引擎,也称为SQL执行引擎,存储管理器则被称为存储引擎,SQL引擎和存储引擎组合起来就构成了我们常说的数据库内核的主要部分。
二、监听器(Listener)
监听器是数据库的对外门户,本质上属于一种网络服务,总是部署在数据库服务端,用于接收和处理来自于客户端的数据库连接请求。
监听器有两种表现形式,一种表现为独立的操作系统进程,比如Oracle 的 Listener,另一种则表现为数据库服务进程的一个或多个线程,比如MySQL、PostgreSQL。
监听器的工作流程:
- 收到来自于客户端的数据库连接请求后,对请求的正确性和合法性进行判断,当连接信息不正确或合法性不满足要求时,监听器会拒绝该连接请求。
- 监听器把客户端请求信息转发给数据库服务主进程。
- 主进程判断当前实例上的连接是否已经达到上限,如果达到上限,则终止连接处理。
- 数据库服务主进程创建一个新的执行进程或线程,该进程或线程后续会用于处理本次连接请求的客户端的数据库操作请求。
- 数据库服务主进程把创建出的执行进程或线程的信息返回给监听器。
- 监听器把收到的新创建出来的执行进程或线程的信息返回给客户端,至此,监听器完成自身职责。
- 客户端使用监听器反馈回来的连接信息建立与数据库实例的连接。
对于那些来自于数据库服务器本地的连接请求,通常可以不需要监听器就能正确处理。
三、解析器(Parser)
解析器可以被理解为是数据库的翻译系统,用于把把文本格式的SQL语句翻译成数据库内部的执行时可识别的语法树结构。
解析器的作用是告诉数据库要做什么,详细一点的说法就是告诉数据库要根据什么条件对什么数据对象做什么操作。解析器的输入是SQL语句,输出是语法树结构。
解析器的两大部件
- 语法分析器(Syntactic Analyzer):(1)判断传入的SQL语句是否符合SQL标准,如果不符合,则会报 “语法错误” 并返回,(2)判断SQL语句具体要做什么操作,根据操作类型拆分SQL语句的各个部分并对拆分出的内容进行归类;
- 词法/语义分析器(Semantic Analyzer):(1)判断SQL语句中对象的合法性,比如指定名称的表是否存在、指定的条件值是否满足数据类型要求等,对象不合法时会报诸如 “指定的表不存在” 这样的错误,(2)进行权限判断,判断当前连接的用户是否有权限对指定的数据库对象执行SQL语句中要求的操作,无权限时会报 “权限不足” 这样的错误。
通常情况下,解析器会先进行语法分析,后进行词法/语义分析,最后再通过语法分析生成语法树结构。
语法树是解析器的最终输出,可以把语法树理解为逻辑上的执行计划树。比如如下SQL语句:
SELECT Name, CardNo
FROM Employee
WHERE DeptID='0301' AND Salary>20000;
生成的语法树类似于下图:
四、优化器(Optimizer)
优化器是对SQL的实际执行过程进行性能优化的组件,解决的是数据库对SQL语句所代表的操作要怎么做的问题。优化器是数据库内核的核心,决定了数据库的运行性能,可以说,事务型数据库核心能力的高低主要取决于优化器的能力。
优化器通常是基于关系代数运算规则,使用穷举的方法来判断SQL语句如何才能执行得更快,然后通过等价代换选择执行代价最低(也就执行效率最高)的方案来执行SQL语句。
优化器的输入是解析器生成的语法树,输出是物理执行计划。
优化器通常分为两类:
- 基于规则的优化器 RBO(Rule-Based Optimizer):这类优化器根据既定的关系代数运算规则对SQL进行优化,主要是以等价代换来改写SQL实现优化。
- 基于代价的优化器 CBO(Cost-Based Optimizer):这类优化器根据数据库在运行期间自动收集到的统计信息进行执行代价估算。
现代数据库优化器基本上都使用 RBO+CBO 的方式来完成SQL优化,而决定优化能力高低的主要是CBO。
五、执行器(Executer)
执行器是数据库引擎中执行运算的部件,完成各类具体运算的部件都可以称为执行器,但通常所说的执行器指的是SQL执行器。
执行器逐条执行优化器生成的物理执行计划,根据物理执行计划的具体步骤进行操作和运算。
执行器完成的主要操作总体上分为两类:
- 内存操作:从内存中取得数据,把计算的结果或中间结果写入到内存。
- 文件操作:通常是与存储管理器交互,发送数据读取请求或数据落地请求。
执行器执行上述两类操作基本上都是调用操作系统的相关接口来完成的。
执行器出不总是依赖于物理执行计划工作,也会根据数据库内核调度接收数据库内部服务进程或相关线程的指令来工作。
六、存储管理器(Storage Manager)
存储管理器是与数据库存储进行交互的部件,其功能是从数据库存储中读取数据到内存和把内存中的数据写入到数据库存储。
存储管理器通常是实例级部件,通常接受执行器的请求完成文件操作,也可以接受数据库内部其它进程或线程的请求执行 I/O 动作。
针对不同的存储设备和存储结构设计,存储管理器可以有不同的实现,比如 MySQL 的多引擎架构中,每种引擎都会实现自己特有的存储管理器。
七、协调器(Coordinator)
协调器也是数据库内核中的基本组件,但它不参与运算,而通常的作用是协调多个执行器的操作或调度执行器与其它可执行组件之间的协作。
协调器在实现上通常是实例级的,一个数据库中可以存在多个协调器。
协调器主要包含两种协调行为:
- 并行协调:为参与并行的多个执行器提供操作调度,或在执行器与其它可执行组件之间提供操作调度。
- 并发协调:在有资源争用的多个执行器之间进行协调。