不能直接通过源码编译方式为已安装的mysql二进制发行版添加自定义存储引擎,必须基于mysql官方源码树,使用其cmake构建系统将引擎作为storage/子目录集成编译,严格匹配abi、符号版本及构建环境,否则dlopen会因符号缺失或段错误失败。

不能直接通过源码编译方式为已安装的 MySQL 二进制发行版添加自定义存储引擎。
MySQL 的插件式存储引擎体系结构(自 5.1 起引入)确实支持动态加载,但前提是:引擎必须与 MySQL 服务器使用完全一致的 ABI、符号版本和构建环境(包括编译器版本、glibc 版本、CMake 配置选项等)。而官方预编译的二进制包(如 MySQL Community Server 下载页提供的 .tar.gz 或 .msi)不提供匹配的头文件、链接库和构建脚手架,也不导出必要的内部符号(如 ha_engine 基类虚表布局、plugin_initialize 签名、内存分配钩子等),导致你写的引擎在 dlopen() 时大概率触发符号未定义或段错误。
所以,真实可行路径只有一条:从 MySQL 官方源码出发,完整构建整个 server + 自定义引擎。
必须用 MySQL 源码树构建,而非单独编译 .so
常见错误是试图把自定义引擎写成独立的 .so 文件,再用 INSTALL PLUGIN 加载——这仅对 MySQL 官方支持的插件(如 mysqlx、semisync)有效,且要求引擎代码严格遵循其构建系统约定。
- MySQL 的
storage/目录才是合法入口:你的引擎必须作为子目录放入storage/myengine/,并提供CMakeLists.txt和ha_myengine.cc等标准文件 - 必须复用 MySQL 的 CMake 构建流程:
cmake -DPLUGIN_MYENGINE=ON ...,否则ha_myengine不会被链接进mysqld或注册为可加载插件 - 不要尝试用系统 GCC 或自建 Makefile 编译:MySQL 8.0+ 强依赖于其 CMake 工具链中定义的
MYSQL_ABI_CHECK、MYSQL_PLUGIN_INTERFACE_VERSION等宏,手动编译必然 ABI 不兼容
从 example 引擎开始改,但注意 MySQL 5.1 vs 8.0 的 API 断层
MySQL 5.1 的 ha_example.cc 是起点,但到 MySQL 8.0,核心接口已重写——rnd_next、write_row 等函数签名变更,handler 类继承关系重构,且新增了 SE_PRIVATE_DATA、事务状态机集成等强制要求。
- 若目标是 MySQL 8.0+,请直接参考
storage/perfschema/或storage/blackhole/的实现,而非examples/(该目录在 8.0 中已被移除) -
ha_blackhole.cc是最简可用模板:它实现了最小必要接口(open、close、write_row返回HA_ERR_RECORD_DELETED),无索引、无事务,适合验证构建流程 - 务必检查
sql/handler.h中的handlerton初始化结构体字段顺序——MySQL 8.0.29+ 新增了create_handler成员,漏填会导致plugin_register失败并静默忽略引擎
加载失败时先查 error log,不是 SHOW ENGINES
SHOW ENGINES 只显示成功注册的引擎;如果引擎因符号缺失、构造函数抛异常或 plugin_init 返回非零值而加载失败,MySQL 会记录到错误日志,但不会报错给客户端。
- 启动 mysqld 时加
--log-error-verbosity=3,并在日志中搜索myengine或Plugin 'myengine' init function returned error - 常见失败原因:
undefined symbol: _ZTV12ha_myengine(虚表未导出)、cannot allocate memory for handler(handler::handler构造函数里用了new但没重载 operator new)、SE_PRIVATE_DATA is NULL(忘记在create_handler里分配私有结构体) - 不要依赖
SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'myengine':它只反映 SQL 层注册状态,底层 handler 初始化失败时此行仍可能存在
真正卡住的地方,往往不是逻辑,而是构建环境与 MySQL 源码的咬合精度——差一个 CMake cache 变量、少一个 target_link_libraries、甚至 glibc minor 版本不一致,都会让 dlopen 失败且无明确提示。动手前,先跑通 blackhole 引擎的构建和加载,比直接写业务逻辑重要十倍。











