MySQL 作为世界上使用最广泛的开源关系型数据库管理系统(RDBMS)之一,不仅以其易用性和灵活性著称,还拥有相对精简但高效的内核设计。MySQL 的内核实现,涵盖了 连接管理、SQL 解析、查询优化、执行引擎、存储引擎接口 等多个模块,这些模块通过模块化设计和插件化机制,使得 MySQL 能适应不同的业务场景。

理解 MySQL 内核,不仅能帮助开发者更好地使用和调优 MySQL,还能在数据库内核研发、二次开发、系统性能优化等领域发挥重要作用。


一、MySQL 内核总体架构

从高层来看,MySQL 内核可以划分为四个主要层次:

  1. 连接层(Connection Layer)

    • 负责客户端与服务器之间的连接管理、线程处理、权限验证等。
    • 对外提供多种协议支持,如 TCP/IP、Socket、Named Pipe 等。
  2. SQL 层(SQL Layer)

    • 核心是 解析器(Parser)优化器(Optimizer)执行器(Executor)
    • 完成 SQL 语句的解析、逻辑优化、执行计划生成与执行。
  3. 存储引擎层(Storage Engine Layer)

    • MySQL 特有的插件式存储引擎架构
    • InnoDB、MyISAM、Memory、NDB Cluster 等引擎可以自由选择。
  4. 系统服务层(System Service Layer)

    • 负责日志、事务、缓存、锁、恢复、后台任务等功能。

架构图示(文字版)

+-----------------------------+
|     客户端 API/驱动程序       |
+-----------------------------+
|       连接管理层              |
+-----------------------------+
| SQL 解析器 → 优化器 → 执行器 |
+-----------------------------+
|   存储引擎接口(SE API)     |
+-----------------------------+
|     InnoDB / MyISAM 等      |
+-----------------------------+
| 操作系统文件/磁盘/内存管理   |
+-----------------------------+

二、连接管理(Connection Management)

当客户端发起连接请求时,MySQL 内核会:

  1. 监听端口(默认 3306)。

  2. 接收连接请求,并创建一个 连接线程(Thread-per-connection 模型)。

  3. 认证与授权

    • 根据 mysql.user 表验证用户名、密码、来源 IP。
  4. 分配会话资源

    • 内存结构(连接缓冲区、临时表空间等)。
    • 会话变量(autocommitsql_mode 等)。

伪代码示例:

void handle_new_connection(int sock) {
    MYSQL_CONNECTION conn = create_connection(sock);
    if (!authenticate(conn)) {
        close_connection(conn);
        return;
    }
    while (conn.active) {
        char* query = read_query(conn);
        if (query) {
            execute_query(conn, query);
        }
    }
    destroy_connection(conn);
}

三、SQL 解析与优化

3.1 词法与语法解析

MySQL 使用 Bison + Flex(或 GNU yacc)实现解析器,将 SQL 语句转换成 抽象语法树(AST)

例如,输入:

SELECT id, name FROM user WHERE age > 20;

解析流程:

  1. 词法分析:分解为 SELECTid,nameFROMuserWHEREage>20
  2. 语法分析:构造 AST,表示查询的逻辑结构。

3.2 查询优化器

MySQL 的优化器主要是 基于成本的优化器(Cost-Based Optimizer, CBO),它会:

  • 统计信息(表的行数、索引选择性等)。
  • 决定是否走索引、选择何种连接算法(Nested Loop Join、Block Nested Loop Join 等)。
  • 生成执行计划(Execution Plan)。

优化器伪代码示例:

ExecutionPlan* optimize(AST* ast) {
    Stats stats = collect_statistics(ast);
    CandidatePlans plans = generate_possible_plans(ast);
    return choose_best_plan(plans, stats);
}

四、执行引擎(Executor)

优化器生成的执行计划会被执行引擎按步骤执行,例如:

  1. 打开所需的表(调用存储引擎接口)。
  2. 根据条件获取行数据。
  3. 应用过滤、排序、分组等操作。
  4. 将结果集返回给客户端。

执行器示例(简化版):

ResultSet* execute_plan(ExecutionPlan* plan) {
    open_tables(plan->tables);
    while (row = get_next_row(plan)) {
        if (matches_conditions(row, plan->filters)) {
            add_to_result_set(row);
        }
    }
    return result_set;
}

五、存储引擎接口与 InnoDB 实现

5.1 插件式架构

  • 存储引擎通过 handler API 与 SQL 层交互。
  • 这样可以在不改动 SQL 层代码的情况下,更换底层数据管理方式。

5.2 InnoDB 内部机制

InnoDB 是 MySQL 默认存储引擎,具备:

  • 事务支持(ACID)。
  • MVCC(多版本并发控制)。
  • 行级锁
  • 缓冲池(Buffer Pool)
  • 双写缓冲区(Doublewrite Buffer)
  • 重做日志(Redo Log)回滚日志(Undo Log)

六、事务与并发控制

6.1 事务实现

InnoDB 使用 ARIES 事务恢复算法:

  1. Write-Ahead Logging(WAL):先写日志,再写数据。
  2. Redo Log:保证已提交事务在崩溃后能恢复。
  3. Undo Log:支持事务回滚与 MVCC。

6.2 并发控制

  • 锁机制:行锁、间隙锁、意向锁。
  • 隔离级别:READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE。

事务示例:

START TRANSACTION;
UPDATE account SET balance = balance - 100 WHERE id = 1;
UPDATE account SET balance = balance + 100 WHERE id = 2;
COMMIT;

七、日志与恢复机制

7.1 日志类型

  • Error Log:记录错误、启动/关闭事件。
  • General Query Log:记录所有连接与查询。
  • Binary Log:记录数据修改,用于主从复制。
  • Redo/Undo Log:事务恢复与回滚。

7.2 崩溃恢复

  • 分析阶段(Analysis Phase)
  • 重做阶段(Redo Phase)
  • 撤销阶段(Undo Phase)

八、MySQL 内核源码结构(参考)

sql/           -- SQL 层实现
storage/       -- 存储引擎实现
include/       -- 公共头文件
mysys/         -- 系统工具
libmysql/      -- 客户端库

九、示例:自定义存储引擎(简化版)

下面是一个非常简化的 MySQL 存储引擎插件框架代码(仅演示结构):

#include "my_global.h"
#include "my_sys.h"
#include "mysql/plugin.h"
#include "sql_class.h"
#include "handler.h"

class simple_engine : public handler {
public:
    simple_engine(handlerton *hton, TABLE_SHARE *table_arg)
        : handler(hton, table_arg) {}
    const char *table_type() const { return "SIMPLE_ENGINE"; }
    ulonglong table_flags() const { return HA_NULL; }
    int open(const char *name, int mode, uint test_if_locked) { return 0; }
    int close(void) { return 0; }
    int write_row(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
    int rnd_init(bool scan) { return 0; }
    int rnd_next(uchar *buf) { return HA_ERR_END_OF_FILE; }
};

handlerton simple_hton;

mysql_declare_plugin(simple) {
    MYSQL_STORAGE_ENGINE_PLUGIN,
    &simple_hton,
    "SIMPLE_ENGINE",
    "Author",
    "Simple example storage engine",
    PLUGIN_LICENSE_GPL,
    NULL, NULL, 0x0100, NULL, NULL, NULL
} mysql_declare_plugin_end;

这个插件不会真正存储数据,只是展示了 MySQL 存储引擎的注册与接口结构。


十、性能优化与内核调优

10.1 参数调优

  • innodb_buffer_pool_size:内存缓冲池大小,建议占物理内存 60%~80%。
  • max_connections:最大连接数。
  • query_cache_size(MySQL 8.0 已移除):查询缓存大小。

10.2 索引优化

  • 避免低选择性列建立索引。
  • 使用覆盖索引(Covering Index)。

总结

MySQL 内核通过 模块化、插件化、事务化 的设计,使得它既适合轻量级应用,也能支撑大规模、高并发场景。理解其内核工作原理,不仅有助于正确使用和调优,还能为二次开发、内核研究提供坚实基础。

⭐️ 好书推荐

《MySQL内核设计与实现》

在这里插入图片描述

【内容简介】

本书是资深数据库专家结合其十余年一线实战经验与源码研究倾力打造的MySQL内核权威指南,全景式解构MySQL 5.7及MySQL 8.0内核设计精髓。作者采用基于SQL执行流的独特分析范式,通过一条查询语句的生命周期,串联起协议解析、数据字典、InnoDB存储引擎、并发控制等核心模块,揭秘缓冲池、双写缓冲区、自适应哈希索引的协同机制,以及B+树索引的物理操作细节。

Logo

纵情码海钱塘涌,杭州开发者创新动! 属于杭州的开发者社区!致力于为杭州地区的开发者提供学习、合作和成长的机会;同时也为企业交流招聘提供舞台!

更多推荐