MySQL跨大版本升级后UDF报ERROR 1126或崩溃,主因是ABI不兼容;须重编译插件并确认版本、插件路径、头文件、编译器,Linux用gcc -shared -fPIC -I/usr/include/mysql -o xxx.so xxx.c -lmysqlclient,Windows需匹配位数与CRT,且必须显式INSTALL PLUGIN加载。

MySQL升级后UDF报ERROR 1126或mysqld crash:ABI不兼容是主因
MySQL跨大版本升级(比如5.7→8.0)后,原有 .so 或 .dll 文件几乎必然失效——这不是路径或权限问题,而是MySQL内部符号、内存管理接口、线程模型发生了ABI级变动。直接复用旧库会导致 ERROR 1126 (HY000): Can't open shared library,更严重时触发 mysqld got signal 11 崩溃。
重编译前必须确认的4个关键点
跳过任一检查都可能白忙活:
-
SELECT VERSION();确认当前 MySQL 实际版本(注意区分 8.0.19+ 的函数名前缀强制要求) -
SELECT @@plugin_dir;拿到目标插件目录,确保编译输出路径与之匹配 - 查 MySQL 官方文档对应版本的
mysql.h头文件位置(如 8.0 在/usr/include/mysql/mysql.h,但某些容器镜像需从mysql-community-devel包提取) - 确认编译器版本:MySQL 8.0+ 推荐 GCC 9.3+ 或 Clang 12+;用太新的编译器(如 GCC 14)反而可能引入不兼容符号
Linux下重编译.so的最小可行命令
别套用网上五年前的Makefile,直接用这条命令保底可用(假设源码为 udf_sha256.c):
gcc -shared -fPIC -I/usr/include/mysql -o udf_sha256.so udf_sha256.c -lmysqlclient
关键细节:
-
-fPIC不可省略,否则加载时报cannot make segment writable for relocation -
-lmysqlclient必须链接,否则my_malloc/my_error等符号找不到 - 生成的
udf_sha256.so必须复制到@@plugin_dir目录,且chown mysql:mysql+chmod 755 - 若用 C++ 编写,加
-lstdc++,并确保extern "C"封装所有 UDF 函数声明
Windows上.dll加载失败的典型陷阱
即使 .c 源码完全一样,Windows 下极易栽在位数和运行时库上:
- MySQL 是 x64 进程?那
udf_xxx.dll必须用 x64 工具链编译(Visual Studio 的 x64 Native Tools Command Prompt),x86 DLL 会静默失败 - 动态链接 CRT(/MD)比静态链接(/MT)更安全,避免
msvcp140.dll版本冲突 - 不要用 MinGW 编译 —— 其生成的 DLL 依赖
libgcc_s_seh-1.dll,而 mysqld 进程不会加载它 - 用
dumpbin /exports udf_xxx.dll确认导出符号名是否与CREATE FUNCTION中的函数名完全一致(大小写敏感)
最常被忽略的是:重编译只是第一步,你还得用 INSTALL PLUGIN udf_name SONAME 'udf_name.so' 显式加载,再查 information_schema.PLUGINS 确认状态为 ACTIVE —— 升级后旧插件不会自动复活。



















