MySQL 8.0是MySQL发展的一个重要里程碑。在这个版本中,MySQL Server层的整体架构得到了质的飞跃,通过持续每三个月的迭代和重构工作,使得MySQL在性能和功能上都有了显著的提升。本文将基于MySQL 8.0.25源码,详细介绍MySQL 8.0的最新架构和一些重要的变化。
背景与架构
在过去,我们对MySQL的理解主要建立在5.6和5.7版本之上,更多的是对比PostgreSQL或者传统数据库。然而,从MySQL 8.0开始,通过持续的迭代和重构,MySQL Server层的整体架构有了质的飞越。MySQL 8.0的架构与其他数据库并没有太大的区别,而MySQL现在更多的是加强InnoDB、NDB集群和RAPID(HeatWave clusters)内存集群架构的演进。本文将更偏向于从优化器、执行器的流程角度来演进。
MySQL解析器(Parser)
在MySQL 8.0中,官方使用Bison进行了重写,生成Parser Tree,同时Parser Tree会通过contextualize函数生成MySQL抽象语法树(Abstract Syntax Tree)。MySQL抽象语法树和其他数据库有些不同,是由比较让人拗口的SELECT_LEX_UNIT/SELECT_LEX类交替构成的,然而这两个结构在最新的版本中已经重命名成标准的SELECT_LEX -> Query_block和SELECT_LEX_UNIT -> Query_expression。
MySQL准备/重写阶段
在解析和转换过程中,需要经过一系列的步骤。这些步骤按功能分而非完全按照执行顺序,主要包括:
Setup and Fix:设置和修复过程,包括设置表 leaves、解析 derived table、设置自然连接的行类型等。
Resolve and Transform:解析和转换过程,包括解析 WHERE 条件、设置 GROUP BY 列表、解析 ORDER BY 列表等。
Window::setup_windows1:设置窗口。
setup_order_final:设置 ORDER BY 子句。
setup_ftfuncs:设置全文函数。
Transformation
转换阶段包括以下几个主要步骤:
remove_redundant_subquery_clause:移除冗余子查询。
remove_base_options:移除 SELECT_DISTINCT 选项。
resolve_subquery:解析子查询。
Convert subquery predicate into semi-join, or Mark the subquery for execution using materialization, or Perform IN->EXISTS transformation, or Perform more/less ALL/ANY -> MIN/MAX rewrite:将子查询转换为半连接,或者将子查询标记为使用 materialization 执行,或者执行 IN->EXISTS 转换,或者执行更多的 ALL/ANY -> MIN/MAX 重写。
Substitute trivial scalar-context subquery with its value:用子查询的值替换简单的标量上下文子查询。
transform_scalar_subqueries_to_join_with_derived:将 eligible scalar subqueries 转换为 derived tables。
flatten_subqueries:将 semi-join subquery predicates 转换为 semi-join join nests。
apply_local_transforms:应用本地转换,包括删除未使用的合并列、简化连接等。
Window::eliminate_unused_objects:消除未使用的窗口定义、冗余排序等。
结论
MySQL 8.0的Server层架构在多个方面进行了优化和升级,包括解析器、准备/重写阶段以及转换阶段等。这些优化和升级使得MySQL 8.0在性能和功能上都有了显著的提升,为用户提供了更好的使用体验。随着MySQL 8.0的不断发展和完善,相信其在数据库市场的份额将会越来越大。